[runtime] Add documentation to mono-os-{mutex,cond,sem} + Move to .c file
authorLudovic Henry <ludovic@xamarin.com>
Thu, 28 Jul 2016 22:05:49 +0000 (00:05 +0200)
committerLudovic Henry <ludovic@xamarin.com>
Thu, 28 Jul 2016 22:07:40 +0000 (00:07 +0200)
mono/utils/Makefile.am
mono/utils/mono-os-mutex.c [new file with mode: 0644]
mono/utils/mono-os-mutex.h
mono/utils/mono-os-semaphore.c [new file with mode: 0644]
mono/utils/mono-os-semaphore.h

index 7db91094593e6c34716b2602b8f027c05f52fb3c..8451be86f54fa3c954ff178fa097899538a3f31b 100644 (file)
@@ -41,6 +41,7 @@ monoutils_sources = \
        mono-mmap.h             \
        mono-mmap-internals.h   \
        mono-os-mutex.h         \
+       mono-os-mutex.c         \
        mono-coop-mutex.h               \
        mono-once.h             \
        mono-lazy-init.h                \
@@ -58,6 +59,7 @@ monoutils_sources = \
        mono-poll.c             \
        mono-path.c             \
        mono-os-semaphore.h     \
+       mono-os-semaphore.c     \
        mono-coop-semaphore.h           \
        mono-sigcontext.h       \
        mono-stdlib.c           \
diff --git a/mono/utils/mono-os-mutex.c b/mono/utils/mono-os-mutex.c
new file mode 100644 (file)
index 0000000..8e590b1
--- /dev/null
@@ -0,0 +1,308 @@
+
+#include <config.h>
+#include <glib.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#if !defined(HOST_WIN32)
+#include <pthread.h>
+#include <errno.h>
+#else
+#include <winsock2.h>
+#include <windows.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include "mono-os-mutex.h"
+
+#if !defined(HOST_WIN32)
+
+void
+mono_os_mutex_init (mono_mutex_t *mutex)
+{
+       gint res;
+
+       res = pthread_mutex_init (mutex, NULL);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+void
+mono_os_mutex_init_recursive (mono_mutex_t *mutex)
+{
+       gint res;
+       pthread_mutexattr_t attr;
+
+       res = pthread_mutexattr_init (&attr);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutexattr_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+       res = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutexattr_settype failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+       res = pthread_mutex_init (mutex, &attr);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+       res = pthread_mutexattr_destroy (&attr);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutexattr_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+gint
+mono_os_mutex_destroy (mono_mutex_t *mutex)
+{
+       gint res;
+
+       res = pthread_mutex_destroy (mutex);
+       if (G_UNLIKELY (res != 0 && res != EBUSY))
+               g_error ("%s: pthread_mutex_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+       return res != 0 ? -1 : 0;
+}
+
+void
+mono_os_mutex_lock (mono_mutex_t *mutex)
+{
+       gint res;
+
+       res = pthread_mutex_lock (mutex);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutex_lock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+gint
+mono_os_mutex_trylock (mono_mutex_t *mutex)
+{
+       gint res;
+
+       res = pthread_mutex_trylock (mutex);
+       if (G_UNLIKELY (res != 0 && res != EBUSY))
+               g_error ("%s: pthread_mutex_trylock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+       return res != 0 ? -1 : 0;
+}
+
+void
+mono_os_mutex_unlock (mono_mutex_t *mutex)
+{
+       gint res;
+
+       res = pthread_mutex_unlock (mutex);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_mutex_unlock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+void
+mono_os_cond_init (mono_cond_t *cond)
+{
+       gint res;
+
+       res = pthread_cond_init (cond, NULL);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_cond_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+gint
+mono_os_cond_destroy (mono_cond_t *cond)
+{
+       gint res;
+
+       res = pthread_cond_destroy (cond);
+       if (G_UNLIKELY (res != 0 && res != EBUSY))
+               g_error ("%s: pthread_cond_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+       return res != 0 ? -1 : 0;
+}
+
+void
+mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
+{
+       gint res;
+
+       res = pthread_cond_wait (cond, mutex);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_cond_wait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+gint
+mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
+{
+       struct timeval tv;
+       struct timespec ts;
+       gint64 usecs;
+       gint res;
+
+       if (timeout_ms == MONO_INFINITE_WAIT) {
+               mono_os_cond_wait (cond, mutex);
+               return 0;
+       }
+
+       /* ms = 10^-3, us = 10^-6, ns = 10^-9 */
+
+       res = gettimeofday (&tv, NULL);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+       tv.tv_sec += timeout_ms / 1000;
+       usecs = tv.tv_usec + ((timeout_ms % 1000) * 1000);
+       if (usecs >= 1000000) {
+               usecs -= 1000000;
+               tv.tv_sec ++;
+       }
+       ts.tv_sec = tv.tv_sec;
+       ts.tv_nsec = usecs * 1000;
+
+       res = pthread_cond_timedwait (cond, mutex, &ts);
+       if (G_UNLIKELY (res != 0 && res != ETIMEDOUT))
+               g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+       return res != 0 ? -1 : 0;
+}
+
+void
+mono_os_cond_signal (mono_cond_t *cond)
+{
+       gint res;
+
+       res = pthread_cond_signal (cond);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_cond_signal failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+void
+mono_os_cond_broadcast (mono_cond_t *cond)
+{
+       gint res;
+
+       res = pthread_cond_broadcast (cond);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: pthread_cond_broadcast failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+#else
+
+/* Vanilla MinGW is missing some defs, load them from MinGW-w64. */
+#if defined __MINGW32__ && !defined __MINGW64_VERSION_MAJOR && (_WIN32_WINNT >= 0x0600)
+
+/* Fixme: Opaque structs */
+typedef PVOID RTL_CONDITION_VARIABLE;
+
+#define RTL_SRWLOCK_INIT 0
+#define RTL_CONDITION_VARIABLE_INIT 0
+#define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 1
+
+/*Condition Variables http://msdn.microsoft.com/en-us/library/ms682052%28VS.85%29.aspx*/
+typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
+
+WINBASEAPI VOID WINAPI InitializeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
+WINBASEAPI WINBOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD dwMilliseconds);
+WINBASEAPI VOID WINAPI WakeAllConditionVariable(PCONDITION_VARIABLE ConditionVariable);
+WINBASEAPI VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
+
+/* https://msdn.microsoft.com/en-us/library/windows/desktop/ms683477(v=vs.85).aspx */
+WINBASEAPI BOOL WINAPI InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags);
+
+#define CRITICAL_SECTION_NO_DEBUG_INFO 0x01000000
+
+#endif /* defined __MINGW32__ && !defined __MINGW64_VERSION_MAJOR && (_WIN32_WINNT >= 0x0600) */
+
+void
+mono_os_mutex_init (mono_mutex_t *mutex)
+{
+       BOOL res;
+
+       res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
+}
+
+void
+mono_os_mutex_init_recursive (mono_mutex_t *mutex)
+{
+       BOOL res;
+
+       res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
+}
+
+gint
+mono_os_mutex_destroy (mono_mutex_t *mutex)
+{
+       DeleteCriticalSection (mutex);
+       return 0;
+}
+
+void
+mono_os_mutex_lock (mono_mutex_t *mutex)
+{
+       EnterCriticalSection (mutex);
+}
+
+gint
+mono_os_mutex_trylock (mono_mutex_t *mutex)
+{
+       return TryEnterCriticalSection (mutex) == 0 ? -1 : 0;
+}
+
+void
+mono_os_mutex_unlock (mono_mutex_t *mutex)
+{
+       LeaveCriticalSection (mutex);
+}
+
+void
+mono_os_cond_init (mono_cond_t *cond)
+{
+       InitializeConditionVariable (cond);
+}
+
+gint
+mono_os_cond_destroy (mono_cond_t *cond)
+{
+       /* Beauty of win32 API: do not destroy it */
+       return 0;
+}
+
+void
+mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
+{
+       BOOL res;
+
+       res = SleepConditionVariableCS (cond, mutex, INFINITE);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
+}
+
+gint
+mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
+{
+       BOOL res;
+
+       res = SleepConditionVariableCS (cond, mutex, timeout_ms);
+       if (G_UNLIKELY (res == 0 && GetLastError () != ERROR_TIMEOUT))
+               g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
+
+       return res == 0 ? -1 : 0;
+}
+
+void
+mono_os_cond_signal (mono_cond_t *cond)
+{
+       WakeConditionVariable (cond);
+}
+
+void
+mono_os_cond_broadcast (mono_cond_t *cond)
+{
+       WakeAllConditionVariable (cond);
+}
+
+#endif
index ece9bd410f6142aa38b59773fbdd144ed1d60c07..766094777b66c411b5efefb4d2cc54da36b94516 100644 (file)
 #include <config.h>
 #include <glib.h>
 
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
 #if !defined(HOST_WIN32)
 #include <pthread.h>
-#include <errno.h>
 #else
 #include <winsock2.h>
 #include <windows.h>
 #endif
 
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-G_BEGIN_DECLS
-
 #ifndef MONO_INFINITE_WAIT
 #define MONO_INFINITE_WAIT ((guint32) 0xFFFFFFFF)
 #endif
 
+G_BEGIN_DECLS
 
 #if !defined(HOST_WIN32)
 
 typedef pthread_mutex_t mono_mutex_t;
 typedef pthread_cond_t mono_cond_t;
 
-static inline void
-mono_os_mutex_init (mono_mutex_t *mutex)
-{
-       int res;
-
-       res = pthread_mutex_init (mutex, NULL);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-static inline void
-mono_os_mutex_init_recursive (mono_mutex_t *mutex)
-{
-       int res;
-       pthread_mutexattr_t attr;
-
-       res = pthread_mutexattr_init (&attr);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_mutexattr_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
-       res = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_mutexattr_settype failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
-       res = pthread_mutex_init (mutex, &attr);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
-       res = pthread_mutexattr_destroy (&attr);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_mutexattr_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-static inline int
-mono_os_mutex_destroy (mono_mutex_t *mutex)
-{
-       int res;
-
-       res = pthread_mutex_destroy (mutex);
-       if (G_UNLIKELY (res != 0 && res != EBUSY))
-               g_error ("%s: pthread_mutex_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
-       return res != 0 ? -1 : 0;
-}
-
-static inline void
-mono_os_mutex_lock (mono_mutex_t *mutex)
-{
-       int res;
-
-       res = pthread_mutex_lock (mutex);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_mutex_lock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-static inline int
-mono_os_mutex_trylock (mono_mutex_t *mutex)
-{
-       int res;
-
-       res = pthread_mutex_trylock (mutex);
-       if (G_UNLIKELY (res != 0 && res != EBUSY))
-               g_error ("%s: pthread_mutex_trylock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
-       return res != 0 ? -1 : 0;
-}
-
-static inline void
-mono_os_mutex_unlock (mono_mutex_t *mutex)
-{
-       int res;
-
-       res = pthread_mutex_unlock (mutex);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_mutex_unlock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-static inline void
-mono_os_cond_init (mono_cond_t *cond)
-{
-       int res;
-
-       res = pthread_cond_init (cond, NULL);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_cond_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-static inline int
-mono_os_cond_destroy (mono_cond_t *cond)
-{
-       int res;
-
-       res = pthread_cond_destroy (cond);
-       if (G_UNLIKELY (res != 0 && res != EBUSY))
-               g_error ("%s: pthread_cond_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
-       return res != 0 ? -1 : 0;
-}
-
-static inline void
-mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
-{
-       int res;
-
-       res = pthread_cond_wait (cond, mutex);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_cond_wait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-static inline int
-mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
-{
-       struct timeval tv;
-       struct timespec ts;
-       gint64 usecs;
-       int res;
-
-       if (timeout_ms == MONO_INFINITE_WAIT) {
-               mono_os_cond_wait (cond, mutex);
-               return 0;
-       }
-
-       /* ms = 10^-3, us = 10^-6, ns = 10^-9 */
-
-       res = gettimeofday (&tv, NULL);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
-       tv.tv_sec += timeout_ms / 1000;
-       usecs = tv.tv_usec + ((timeout_ms % 1000) * 1000);
-       if (usecs >= 1000000) {
-               usecs -= 1000000;
-               tv.tv_sec ++;
-       }
-       ts.tv_sec = tv.tv_sec;
-       ts.tv_nsec = usecs * 1000;
-
-       res = pthread_cond_timedwait (cond, mutex, &ts);
-       if (G_UNLIKELY (res != 0 && res != ETIMEDOUT))
-               g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
-       return res != 0 ? -1 : 0;
-}
-
-static inline void
-mono_os_cond_signal (mono_cond_t *cond)
-{
-       int res;
-
-       res = pthread_cond_signal (cond);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_cond_signal failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-static inline void
-mono_os_cond_broadcast (mono_cond_t *cond)
-{
-       int res;
-
-       res = pthread_cond_broadcast (cond);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: pthread_cond_broadcast failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
 #else
 
-/* Vanilla MinGW is missing some defs, load them from MinGW-w64. */
-#if defined __MINGW32__ && !defined __MINGW64_VERSION_MAJOR && (_WIN32_WINNT >= 0x0600)
-
-/* Fixme: Opaque structs */
-typedef PVOID RTL_CONDITION_VARIABLE;
-typedef PVOID RTL_SRWLOCK;
-
-#ifndef _RTL_RUN_ONCE_DEF
-#define _RTL_RUN_ONCE_DEF 1
-typedef PVOID RTL_RUN_ONCE, *PRTL_RUN_ONCE;
-typedef DWORD (WINAPI *PRTL_RUN_ONCE_INIT_FN)(PRTL_RUN_ONCE, PVOID, PVOID *);
-#define RTL_RUN_ONCE_INIT 0
-#define RTL_RUN_ONCE_CHECK_ONLY 1UL
-#define RTL_RUN_ONCE_ASYNC 2UL
-#define RTL_RUN_ONCE_INIT_FAILED 4UL
-#define RTL_RUN_ONCE_CTX_RESERVED_BITS 2
-#endif /* _RTL_RUN_ONCE_DEF */
-#define RTL_SRWLOCK_INIT 0
-#define RTL_CONDITION_VARIABLE_INIT 0
-#define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 1
-
-#define CONDITION_VARIABLE_INIT RTL_CONDITION_VARIABLE_INIT
-#define CONDITION_VARIABLE_LOCKMODE_SHARED RTL_CONDITION_VARIABLE_LOCKMODE_SHARED
-#define SRWLOCK_INIT RTL_SRWLOCK_INIT
-
-/*Condition Variables http://msdn.microsoft.com/en-us/library/ms682052%28VS.85%29.aspx*/
-typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
-typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
-
-WINBASEAPI VOID WINAPI InitializeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
-WINBASEAPI WINBOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD dwMilliseconds);
-WINBASEAPI WINBOOL WINAPI SleepConditionVariableSRW(PCONDITION_VARIABLE ConditionVariable, PSRWLOCK SRWLock, DWORD dwMilliseconds, ULONG Flags);
-WINBASEAPI VOID WINAPI WakeAllConditionVariable(PCONDITION_VARIABLE ConditionVariable);
-WINBASEAPI VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
-
-/*Slim Reader/Writer (SRW) Locks http://msdn.microsoft.com/en-us/library/aa904937%28VS.85%29.aspx*/
-WINBASEAPI VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK SRWLock);
-WINBASEAPI VOID WINAPI AcquireSRWLockShared(PSRWLOCK SRWLock);
-WINBASEAPI VOID WINAPI InitializeSRWLock(PSRWLOCK SRWLock);
-WINBASEAPI VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK SRWLock);
-WINBASEAPI VOID WINAPI ReleaseSRWLockShared(PSRWLOCK SRWLock);
-
-WINBASEAPI BOOLEAN TryAcquireSRWLockExclusive(PSRWLOCK SRWLock);
-WINBASEAPI BOOLEAN TryAcquireSRWLockShared(PSRWLOCK SRWLock);
-
-/*One-Time Initialization http://msdn.microsoft.com/en-us/library/aa363808(VS.85).aspx*/
-#define INIT_ONCE_ASYNC 0x00000002UL
-#define INIT_ONCE_INIT_FAILED 0x00000004UL
-
-typedef PRTL_RUN_ONCE PINIT_ONCE;
-typedef PRTL_RUN_ONCE LPINIT_ONCE;
-typedef WINBOOL CALLBACK (*PINIT_ONCE_FN) (PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context);
-
-WINBASEAPI WINBOOL WINAPI InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL fPending, LPVOID *lpContext);
-WINBASEAPI WINBOOL WINAPI InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpContext);
-WINBASEAPI WINBOOL WINAPI InitOnceExecuteOnce(PINIT_ONCE InitOnce, PINIT_ONCE_FN InitFn, PVOID Parameter, LPVOID *Context);
-
-/* https://msdn.microsoft.com/en-us/library/windows/desktop/ms683477(v=vs.85).aspx */
-WINBASEAPI BOOL WINAPI InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags);
-
-#define CRITICAL_SECTION_NO_DEBUG_INFO 0x01000000
-
-#endif /* defined __MINGW32__ && !defined __MINGW64_VERSION_MAJOR && (_WIN32_WINNT >= 0x0600) */
-
 typedef CRITICAL_SECTION mono_mutex_t;
 typedef CONDITION_VARIABLE mono_cond_t;
 
-static inline void
-mono_os_mutex_init (mono_mutex_t *mutex)
-{
-       BOOL res;
-
-       res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
-       if (G_UNLIKELY (res == 0))
-               g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
-}
-
-static inline void
-mono_os_mutex_init_recursive (mono_mutex_t *mutex)
-{
-       BOOL res;
-
-       res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
-       if (G_UNLIKELY (res == 0))
-               g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
-}
-
-static inline int
-mono_os_mutex_destroy (mono_mutex_t *mutex)
-{
-       DeleteCriticalSection (mutex);
-       return 0;
-}
-
-static inline void
-mono_os_mutex_lock (mono_mutex_t *mutex)
-{
-       EnterCriticalSection (mutex);
-}
+#endif
 
-static inline int
-mono_os_mutex_trylock (mono_mutex_t *mutex)
-{
-       return TryEnterCriticalSection (mutex) == 0 ? -1 : 0;
-}
+/**
+ * mono_os_mutex_init:
+ */
+void
+mono_os_mutex_init (mono_mutex_t *mutex);
 
-static inline void
-mono_os_mutex_unlock (mono_mutex_t *mutex)
-{
-       LeaveCriticalSection (mutex);
-}
+/**
+ * mono_os_mutex_init_recursive:
+ */
+void
+mono_os_mutex_init_recursive (mono_mutex_t *mutex);
 
-static inline void
-mono_os_cond_init (mono_cond_t *cond)
-{
-       InitializeConditionVariable (cond);
-}
+/**
+ * mono_os_mutex_destroy:
+ *
+ * @returns:
+ *  -  0: success
+ *  - -1: the mutex is busy (used by the io-layer)
+ */
+gint
+mono_os_mutex_destroy (mono_mutex_t *mutex);
 
-static inline int
-mono_os_cond_destroy (mono_cond_t *cond)
-{
-       /* Beauty of win32 API: do not destroy it */
-       return 0;
-}
+/**
+ * mono_os_mutex_lock:
+ */
+void
+mono_os_mutex_lock (mono_mutex_t *mutex);
 
-static inline void
-mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
-{
-       BOOL res;
+/**
+ * mono_os_mutex_trylock:
+ *
+ * @returns:
+ *  -  0: success
+ *  - -1: the mutex is busy
+ */
+gint
+mono_os_mutex_trylock (mono_mutex_t *mutex);
 
-       res = SleepConditionVariableCS (cond, mutex, INFINITE);
-       if (G_UNLIKELY (res == 0))
-               g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
-}
+/**
+ * mono_os_mutex_unlock:
+ */
+void
+mono_os_mutex_unlock (mono_mutex_t *mutex);
 
-static inline int
-mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
-{
-       BOOL res;
+/**
+ * mono_os_cond_init:
+ */
+void
+mono_os_cond_init (mono_cond_t *cond);
 
-       res = SleepConditionVariableCS (cond, mutex, timeout_ms);
-       if (G_UNLIKELY (res == 0 && GetLastError () != ERROR_TIMEOUT))
-               g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
+/**
+ * mono_os_cond_destroy:
+ *
+ * @returns:
+ *  -  0: success
+ *  - -1: the cond is busy (used by the io-layer)
+ */
+gint
+mono_os_cond_destroy (mono_cond_t *cond);
 
-       return res == 0 ? -1 : 0;
-}
+/**
+ * mono_os_cond_wait:
+ */
+void
+mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex);
 
-static inline void
-mono_os_cond_signal (mono_cond_t *cond)
-{
-       WakeConditionVariable (cond);
-}
+/**
+ * mono_os_cond_timedwait:
+ *
+ * @returns:
+ *  -  0: success
+ *  - -1: wait timed out
+ */
+gint
+mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms);
 
-static inline void
-mono_os_cond_broadcast (mono_cond_t *cond)
-{
-       WakeAllConditionVariable (cond);
-}
+/**
+ * mono_os_cond_signal:
+ */
+void
+mono_os_cond_signal (mono_cond_t *cond);
 
-#endif
+/**
+ * mono_os_cond_broadcast:
+ */
+void
+mono_os_cond_broadcast (mono_cond_t *cond);
 
 G_END_DECLS
 
diff --git a/mono/utils/mono-os-semaphore.c b/mono/utils/mono-os-semaphore.c
new file mode 100644 (file)
index 0000000..1cb2093
--- /dev/null
@@ -0,0 +1,305 @@
+
+#include <config.h>
+#include <glib.h>
+
+#include <errno.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "mono-os-semaphore.h"
+
+#ifndef NSEC_PER_SEC
+#define NSEC_PER_SEC (1000 * 1000 * 1000)
+#endif
+
+#if defined(USE_MACH_SEMA)
+
+void
+mono_os_sem_init (MonoSemType *sem, gint value)
+{
+       kern_return_t res;
+
+       res = semaphore_create (current_task (), sem, SYNC_POLICY_FIFO, value);
+       if (G_UNLIKELY (res != KERN_SUCCESS))
+               g_error ("%s: semaphore_create failed with error %d", __func__, res);
+}
+
+void
+mono_os_sem_destroy (MonoSemType *sem)
+{
+       kern_return_t res;
+
+       res = semaphore_destroy (current_task (), *sem);
+       if (G_UNLIKELY (res != KERN_SUCCESS))
+               g_error ("%s: semaphore_destroy failed with error %d", __func__, res);
+}
+
+gint
+mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
+{
+       kern_return_t res;
+
+retry:
+       res = semaphore_wait (*sem);
+       if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
+               g_error ("%s: semaphore_wait failed with error %d", __func__, res);
+
+       if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE))
+               goto retry;
+
+       return res != KERN_SUCCESS ? -1 : 0;
+}
+
+MonoSemTimedwaitRet
+mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
+{
+       kern_return_t res;
+       gint resint;
+       mach_timespec_t ts, copy;
+       struct timeval start, current;
+
+       if (timeout_ms == MONO_INFINITE_WAIT)
+               return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
+
+       ts.tv_sec = timeout_ms / 1000;
+       ts.tv_nsec = (timeout_ms % 1000) * 1000000;
+       while (ts.tv_nsec >= NSEC_PER_SEC) {
+               ts.tv_nsec -= NSEC_PER_SEC;
+               ts.tv_sec++;
+       }
+
+       copy = ts;
+       resint = gettimeofday (&start, NULL);
+       if (G_UNLIKELY (resint != 0))
+               g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+retry:
+       res = semaphore_timedwait (*sem, ts);
+       if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED && res != KERN_OPERATION_TIMED_OUT))
+               g_error ("%s: semaphore_timedwait failed with error %d", __func__, res);
+
+       if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
+               ts = copy;
+
+               resint = gettimeofday (&current, NULL);
+               if (G_UNLIKELY (resint != 0))
+                       g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+               ts.tv_sec -= (current.tv_sec - start.tv_sec);
+               ts.tv_nsec -= (current.tv_usec - start.tv_usec) * 1000;
+               if (ts.tv_nsec < 0) {
+                       if (ts.tv_sec <= 0) {
+                               ts.tv_nsec = 0;
+                       } else {
+                               ts.tv_sec--;
+                               ts.tv_nsec += NSEC_PER_SEC;
+                       }
+               }
+               if (ts.tv_sec < 0) {
+                       ts.tv_sec = 0;
+                       ts.tv_nsec = 0;
+               }
+
+               goto retry;
+       }
+
+       switch (res) {
+       case KERN_SUCCESS:
+               return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+       case KERN_ABORTED:
+               return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+       case KERN_OPERATION_TIMED_OUT:
+               return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+       default:
+               g_assert_not_reached ();
+       }
+}
+
+void
+mono_os_sem_post (MonoSemType *sem)
+{
+       kern_return_t res;
+
+retry:
+       res = semaphore_signal (*sem);
+       if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
+               g_error ("%s: semaphore_signal failed with error %d", __func__, res);
+
+       if (res == KERN_ABORTED)
+               goto retry;
+}
+
+#elif !defined(HOST_WIN32) && defined(HAVE_SEMAPHORE_H)
+
+void
+mono_os_sem_init (MonoSemType *sem, gint value)
+{
+       gint res;
+
+       res = sem_init (sem, 0, value);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: sem_init failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+}
+
+void
+mono_os_sem_destroy (MonoSemType *sem)
+{
+       gint res;
+
+       res = sem_destroy (sem);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: sem_destroy failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+}
+
+gint
+mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
+{
+       gint res;
+
+retry:
+       res = sem_wait (sem);
+       if (G_UNLIKELY (res != 0 && errno != EINTR))
+               g_error ("%s: sem_wait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+       if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE))
+               goto retry;
+
+       return res != 0 ? -1 : 0;
+}
+
+MonoSemTimedwaitRet
+mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
+{
+       struct timespec ts, copy;
+       struct timeval t;
+       gint res;
+
+       if (timeout_ms == 0) {
+               res = sem_trywait (sem);
+               if (G_UNLIKELY (res != 0 && errno != EINTR && errno != EAGAIN))
+                       g_error ("%s: sem_trywait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+               if (res == 0)
+                       return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+               else if (errno == EINTR)
+                       return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+               else if (errno == EAGAIN)
+                       return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+               else
+                       g_assert_not_reached ();
+       }
+
+       if (timeout_ms == MONO_INFINITE_WAIT)
+               return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
+
+       res = gettimeofday (&t, NULL);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+       ts.tv_sec = timeout_ms / 1000 + t.tv_sec;
+       ts.tv_nsec = (timeout_ms % 1000) * 1000000 + t.tv_usec * 1000;
+       while (ts.tv_nsec >= NSEC_PER_SEC) {
+               ts.tv_nsec -= NSEC_PER_SEC;
+               ts.tv_sec++;
+       }
+
+       copy = ts;
+
+retry:
+       res = sem_timedwait (sem, &ts);
+       if (G_UNLIKELY (res != 0 && errno != EINTR && errno != ETIMEDOUT))
+               g_error ("%s: sem_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+       if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
+               ts = copy;
+               goto retry;
+       }
+
+       if (res == 0)
+               return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+       else if (errno == EINTR)
+               return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+       else if (errno == ETIMEDOUT)
+               return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+       else
+               g_assert_not_reached ();
+}
+
+void
+mono_os_sem_post (MonoSemType *sem)
+{
+       gint res;
+
+       res = sem_post (sem);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: sem_post failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+}
+
+#else
+
+void
+mono_os_sem_init (MonoSemType *sem, gint value)
+{
+       *sem = CreateSemaphore (NULL, value, 0x7FFFFFFF, NULL);
+       if (G_UNLIKELY (*sem == NULL))
+               g_error ("%s: CreateSemaphore failed with error %d", __func__, GetLastError ());
+}
+
+void
+mono_os_sem_destroy (MonoSemType *sem)
+{
+       BOOL res;
+
+       res = CloseHandle (*sem);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: CloseHandle failed with error %d", __func__, GetLastError ());
+}
+
+MonoSemTimedwaitRet
+mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
+{
+       BOOL res;
+
+retry:
+       res = WaitForSingleObjectEx (*sem, timeout_ms, flags & MONO_SEM_FLAGS_ALERTABLE);
+       if (G_UNLIKELY (res != WAIT_OBJECT_0 && res != WAIT_IO_COMPLETION && res != WAIT_TIMEOUT))
+               g_error ("%s: WaitForSingleObjectEx failed with error %d", __func__, GetLastError ());
+
+       if (res == WAIT_IO_COMPLETION && !(flags & MONO_SEM_FLAGS_ALERTABLE))
+               goto retry;
+
+       switch (res) {
+       case WAIT_OBJECT_0:
+               return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+       case WAIT_IO_COMPLETION:
+               return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+       case WAIT_TIMEOUT:
+               return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+       default:
+               g_assert_not_reached ();
+       }
+}
+
+gint
+mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
+{
+       return mono_os_sem_timedwait (sem, INFINITE, flags) != 0 ? -1 : 0;
+}
+
+void
+mono_os_sem_post (MonoSemType *sem)
+{
+       BOOL res;
+
+       res = ReleaseSemaphore (*sem, 1, NULL);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: ReleaseSemaphore failed with error %d", __func__, GetLastError ());
+}
+
+#endif
index 9f59ce1ea821df2fa3dd849edd89d8e3a8b8aee7..f78c68acbcdb3c8e2148e49a6678f7fdfafa9c1c 100644 (file)
 #include <config.h>
 #include <glib.h>
 
-#include <errno.h>
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
 #if defined(USE_MACH_SEMA)
 #include <mach/mach_init.h>
 #include <mach/task.h>
 #include <windows.h>
 #endif
 
-#define MONO_HAS_SEMAPHORES 1
-
-#ifndef NSEC_PER_SEC
-#define NSEC_PER_SEC (1000 * 1000 * 1000)
-#endif
-
 #ifndef MONO_INFINITE_WAIT
 #define MONO_INFINITE_WAIT ((guint32) 0xFFFFFFFF)
 #endif
 
 G_BEGIN_DECLS
 
-typedef enum {
-       MONO_SEM_FLAGS_NONE      = 0,
-       MONO_SEM_FLAGS_ALERTABLE = 1 << 0,
-} MonoSemFlags;
-
-typedef enum {
-       MONO_SEM_TIMEDWAIT_RET_SUCCESS  =  0,
-       MONO_SEM_TIMEDWAIT_RET_ALERTED  = -1,
-       MONO_SEM_TIMEDWAIT_RET_TIMEDOUT = -2,
-} MonoSemTimedwaitRet;
-
 #if defined(USE_MACH_SEMA)
 
 typedef semaphore_t MonoSemType;
 
-static inline void
-mono_os_sem_init (MonoSemType *sem, int value)
-{
-       kern_return_t res;
-
-       res = semaphore_create (current_task (), sem, SYNC_POLICY_FIFO, value);
-       if (G_UNLIKELY (res != KERN_SUCCESS))
-               g_error ("%s: semaphore_create failed with error %d", __func__, res);
-}
-
-static inline void
-mono_os_sem_destroy (MonoSemType *sem)
-{
-       kern_return_t res;
-
-       res = semaphore_destroy (current_task (), *sem);
-       if (G_UNLIKELY (res != KERN_SUCCESS))
-               g_error ("%s: semaphore_destroy failed with error %d", __func__, res);
-}
-
-static inline int
-mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
-{
-       kern_return_t res;
-
-retry:
-       res = semaphore_wait (*sem);
-       if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
-               g_error ("%s: semaphore_wait failed with error %d", __func__, res);
-
-       if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE))
-               goto retry;
-
-       return res != KERN_SUCCESS ? -1 : 0;
-}
-
-static inline MonoSemTimedwaitRet
-mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
-{
-       kern_return_t res;
-       int resint;
-       mach_timespec_t ts, copy;
-       struct timeval start, current;
-
-       if (timeout_ms == MONO_INFINITE_WAIT)
-               return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
-
-       ts.tv_sec = timeout_ms / 1000;
-       ts.tv_nsec = (timeout_ms % 1000) * 1000000;
-       while (ts.tv_nsec >= NSEC_PER_SEC) {
-               ts.tv_nsec -= NSEC_PER_SEC;
-               ts.tv_sec++;
-       }
-
-       copy = ts;
-       resint = gettimeofday (&start, NULL);
-       if (G_UNLIKELY (resint != 0))
-               g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
-retry:
-       res = semaphore_timedwait (*sem, ts);
-       if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED && res != KERN_OPERATION_TIMED_OUT))
-               g_error ("%s: semaphore_timedwait failed with error %d", __func__, res);
-
-       if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
-               ts = copy;
-
-               resint = gettimeofday (&current, NULL);
-               if (G_UNLIKELY (resint != 0))
-                       g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
-               ts.tv_sec -= (current.tv_sec - start.tv_sec);
-               ts.tv_nsec -= (current.tv_usec - start.tv_usec) * 1000;
-               if (ts.tv_nsec < 0) {
-                       if (ts.tv_sec <= 0) {
-                               ts.tv_nsec = 0;
-                       } else {
-                               ts.tv_sec--;
-                               ts.tv_nsec += NSEC_PER_SEC;
-                       }
-               }
-               if (ts.tv_sec < 0) {
-                       ts.tv_sec = 0;
-                       ts.tv_nsec = 0;
-               }
-
-               goto retry;
-       }
-
-       switch (res) {
-       case KERN_SUCCESS:
-               return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
-       case KERN_ABORTED:
-               return MONO_SEM_TIMEDWAIT_RET_ALERTED;
-       case KERN_OPERATION_TIMED_OUT:
-               return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
-       default:
-               g_assert_not_reached ();
-       }
-}
-
-static inline void
-mono_os_sem_post (MonoSemType *sem)
-{
-       kern_return_t res;
-
-retry:
-       res = semaphore_signal (*sem);
-       if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
-               g_error ("%s: semaphore_signal failed with error %d", __func__, res);
-
-       if (res == KERN_ABORTED)
-               goto retry;
-}
-
 #elif !defined(HOST_WIN32) && defined(HAVE_SEMAPHORE_H)
 
 typedef sem_t MonoSemType;
 
-static inline void
-mono_os_sem_init (MonoSemType *sem, int value)
-{
-       int res;
-
-       res = sem_init (sem, 0, value);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: sem_init failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-}
-
-static inline void
-mono_os_sem_destroy (MonoSemType *sem)
-{
-       int res;
-
-       res = sem_destroy (sem);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: sem_destroy failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-}
-
-static inline int
-mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
-{
-       int res;
-
-retry:
-       res = sem_wait (sem);
-       if (G_UNLIKELY (res != 0 && errno != EINTR))
-               g_error ("%s: sem_wait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
-       if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE))
-               goto retry;
-
-       return res != 0 ? -1 : 0;
-}
-
-static inline MonoSemTimedwaitRet
-mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
-{
-       struct timespec ts, copy;
-       struct timeval t;
-       int res;
-
-       if (timeout_ms == 0) {
-               res = sem_trywait (sem);
-               if (G_UNLIKELY (res != 0 && errno != EINTR && errno != EAGAIN))
-                       g_error ("%s: sem_trywait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
-               if (res == 0)
-                       return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
-               else if (errno == EINTR)
-                       return MONO_SEM_TIMEDWAIT_RET_ALERTED;
-               else if (errno == EAGAIN)
-                       return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
-               else
-                       g_assert_not_reached ();
-       }
-
-       if (timeout_ms == MONO_INFINITE_WAIT)
-               return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
-
-       res = gettimeofday (&t, NULL);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
-       ts.tv_sec = timeout_ms / 1000 + t.tv_sec;
-       ts.tv_nsec = (timeout_ms % 1000) * 1000000 + t.tv_usec * 1000;
-       while (ts.tv_nsec >= NSEC_PER_SEC) {
-               ts.tv_nsec -= NSEC_PER_SEC;
-               ts.tv_sec++;
-       }
-
-       copy = ts;
-
-retry:
-       res = sem_timedwait (sem, &ts);
-       if (G_UNLIKELY (res != 0 && errno != EINTR && errno != ETIMEDOUT))
-               g_error ("%s: sem_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
-       if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
-               ts = copy;
-               goto retry;
-       }
-
-       if (res == 0)
-               return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
-       else if (errno == EINTR)
-               return MONO_SEM_TIMEDWAIT_RET_ALERTED;
-       else if (errno == ETIMEDOUT)
-               return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
-       else
-               g_assert_not_reached ();
-}
-
-static inline void
-mono_os_sem_post (MonoSemType *sem)
-{
-       int res;
-
-       res = sem_post (sem);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: sem_post failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-}
-
 #else
 
 typedef HANDLE MonoSemType;
 
-static inline void
-mono_os_sem_init (MonoSemType *sem, int value)
-{
-       *sem = CreateSemaphore (NULL, value, 0x7FFFFFFF, NULL);
-       if (G_UNLIKELY (*sem == NULL))
-               g_error ("%s: CreateSemaphore failed with error %d", __func__, GetLastError ());
-}
-
-static inline void
-mono_os_sem_destroy (MonoSemType *sem)
-{
-       BOOL res;
-
-       res = CloseHandle (*sem);
-       if (G_UNLIKELY (res == 0))
-               g_error ("%s: CloseHandle failed with error %d", __func__, GetLastError ());
-}
-
-static inline MonoSemTimedwaitRet
-mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
-{
-       BOOL res;
+#endif
 
-retry:
-       res = WaitForSingleObjectEx (*sem, timeout_ms, flags & MONO_SEM_FLAGS_ALERTABLE);
-       if (G_UNLIKELY (res != WAIT_OBJECT_0 && res != WAIT_IO_COMPLETION && res != WAIT_TIMEOUT))
-               g_error ("%s: WaitForSingleObjectEx failed with error %d", __func__, GetLastError ());
+typedef enum {
+       MONO_SEM_FLAGS_NONE      = 0,
+       MONO_SEM_FLAGS_ALERTABLE = 1 << 0,
+} MonoSemFlags;
 
-       if (res == WAIT_IO_COMPLETION && !(flags & MONO_SEM_FLAGS_ALERTABLE))
-               goto retry;
+typedef enum {
+       MONO_SEM_TIMEDWAIT_RET_SUCCESS  =  0,
+       MONO_SEM_TIMEDWAIT_RET_ALERTED  = -1,
+       MONO_SEM_TIMEDWAIT_RET_TIMEDOUT = -2,
+} MonoSemTimedwaitRet;
 
-       switch (res) {
-       case WAIT_OBJECT_0:
-               return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
-       case WAIT_IO_COMPLETION:
-               return MONO_SEM_TIMEDWAIT_RET_ALERTED;
-       case WAIT_TIMEOUT:
-               return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
-       default:
-               g_assert_not_reached ();
-       }
-}
+/**
+ * mono_os_sem_init:
+ */
+void
+mono_os_sem_init (MonoSemType *sem, gint value);
 
-static inline int
-mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
-{
-       return mono_os_sem_timedwait (sem, INFINITE, flags) != 0 ? -1 : 0;
-}
+/**
+ * mono_os_sem_destroy:
+ */
+void
+mono_os_sem_destroy (MonoSemType *sem);
 
-static inline void
-mono_os_sem_post (MonoSemType *sem)
-{
-       BOOL res;
+/**
+ * mono_os_sem_wait:
+ *
+ * @returns:
+ *  -  0: success
+ *  - -1: the wait was interrupted
+ */
+gint
+mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags);
 
-       res = ReleaseSemaphore (*sem, 1, NULL);
-       if (G_UNLIKELY (res == 0))
-               g_error ("%s: ReleaseSemaphore failed with error %d", __func__, GetLastError ());
-}
+/**
+ * mono_os_sem_timedwait:
+ *
+ * @returns: see MonoSemTimedwaitRet
+ */
+MonoSemTimedwaitRet
+mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags);
 
-#endif
+/**
+ * mono_os_sem_post:
+ */
+void
+mono_os_sem_post (MonoSemType *sem);
 
 G_END_DECLS