Revert "[runtime] Add documentation to mono-os-{mutex,cond,sem} + Move to .c file"
authorLudovic Henry <ludovic@xamarin.com>
Fri, 29 Jul 2016 10:35:44 +0000 (12:35 +0200)
committerLudovic Henry <ludovic@xamarin.com>
Fri, 29 Jul 2016 10:35:44 +0000 (12:35 +0200)
This reverts commit 9ba062e5a183f3ace3a21e2e3d240adc3db0e5a4.

mono/utils/Makefile.am
mono/utils/mono-os-mutex.c [deleted file]
mono/utils/mono-os-mutex.h
mono/utils/mono-os-semaphore.c [deleted file]
mono/utils/mono-os-semaphore.h

index 8451be86f54fa3c954ff178fa097899538a3f31b..7db91094593e6c34716b2602b8f027c05f52fb3c 100644 (file)
@@ -41,7 +41,6 @@ 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                \
@@ -59,7 +58,6 @@ 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
deleted file mode 100644 (file)
index 8e590b1..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-
-#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 766094777b66c411b5efefb4d2cc54da36b94516..ece9bd410f6142aa38b59773fbdd144ed1d60c07 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;
 
-#endif
+static inline void
+mono_os_mutex_init (mono_mutex_t *mutex)
+{
+       BOOL res;
 
-/**
- * mono_os_mutex_init:
- */
-void
-mono_os_mutex_init (mono_mutex_t *mutex);
+       res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
+}
 
-/**
- * mono_os_mutex_init_recursive:
- */
-void
-mono_os_mutex_init_recursive (mono_mutex_t *mutex);
+static inline void
+mono_os_mutex_init_recursive (mono_mutex_t *mutex)
+{
+       BOOL res;
 
-/**
- * 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);
+       res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
+}
 
-/**
- * mono_os_mutex_lock:
- */
-void
-mono_os_mutex_lock (mono_mutex_t *mutex);
+static inline int
+mono_os_mutex_destroy (mono_mutex_t *mutex)
+{
+       DeleteCriticalSection (mutex);
+       return 0;
+}
 
-/**
- * mono_os_mutex_trylock:
- *
- * @returns:
- *  -  0: success
- *  - -1: the mutex is busy
- */
-gint
-mono_os_mutex_trylock (mono_mutex_t *mutex);
+static inline void
+mono_os_mutex_lock (mono_mutex_t *mutex)
+{
+       EnterCriticalSection (mutex);
+}
 
-/**
- * mono_os_mutex_unlock:
- */
-void
-mono_os_mutex_unlock (mono_mutex_t *mutex);
+static inline int
+mono_os_mutex_trylock (mono_mutex_t *mutex)
+{
+       return TryEnterCriticalSection (mutex) == 0 ? -1 : 0;
+}
 
-/**
- * mono_os_cond_init:
- */
-void
-mono_os_cond_init (mono_cond_t *cond);
+static inline void
+mono_os_mutex_unlock (mono_mutex_t *mutex)
+{
+       LeaveCriticalSection (mutex);
+}
 
-/**
- * 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);
+static inline void
+mono_os_cond_init (mono_cond_t *cond)
+{
+       InitializeConditionVariable (cond);
+}
 
-/**
- * mono_os_cond_wait:
- */
-void
-mono_os_cond_wait (mono_cond_t *cond, 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_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_wait (mono_cond_t *cond, mono_mutex_t *mutex)
+{
+       BOOL res;
 
-/**
- * mono_os_cond_signal:
- */
-void
-mono_os_cond_signal (mono_cond_t *cond);
+       res = SleepConditionVariableCS (cond, mutex, INFINITE);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
+}
 
-/**
- * mono_os_cond_broadcast:
- */
-void
-mono_os_cond_broadcast (mono_cond_t *cond);
+static inline int
+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;
+}
+
+static inline void
+mono_os_cond_signal (mono_cond_t *cond)
+{
+       WakeConditionVariable (cond);
+}
+
+static inline void
+mono_os_cond_broadcast (mono_cond_t *cond)
+{
+       WakeAllConditionVariable (cond);
+}
+
+#endif
 
 G_END_DECLS
 
diff --git a/mono/utils/mono-os-semaphore.c b/mono/utils/mono-os-semaphore.c
deleted file mode 100644 (file)
index 1cb2093..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-
-#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 f78c68acbcdb3c8e2148e49a6678f7fdfafa9c1c..9f59ce1ea821df2fa3dd849edd89d8e3a8b8aee7 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;
 
-#endif
+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 ());
+}
 
-typedef enum {
-       MONO_SEM_FLAGS_NONE      = 0,
-       MONO_SEM_FLAGS_ALERTABLE = 1 << 0,
-} MonoSemFlags;
+static inline void
+mono_os_sem_destroy (MonoSemType *sem)
+{
+       BOOL res;
 
-typedef enum {
-       MONO_SEM_TIMEDWAIT_RET_SUCCESS  =  0,
-       MONO_SEM_TIMEDWAIT_RET_ALERTED  = -1,
-       MONO_SEM_TIMEDWAIT_RET_TIMEDOUT = -2,
-} MonoSemTimedwaitRet;
+       res = CloseHandle (*sem);
+       if (G_UNLIKELY (res == 0))
+               g_error ("%s: CloseHandle failed with error %d", __func__, GetLastError ());
+}
 
-/**
- * mono_os_sem_init:
- */
-void
-mono_os_sem_init (MonoSemType *sem, gint value);
+static inline MonoSemTimedwaitRet
+mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
+{
+       BOOL res;
 
-/**
- * mono_os_sem_destroy:
- */
-void
-mono_os_sem_destroy (MonoSemType *sem);
+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 ());
 
-/**
- * mono_os_sem_wait:
- *
- * @returns:
- *  -  0: success
- *  - -1: the wait was interrupted
- */
-gint
-mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags);
+       if (res == WAIT_IO_COMPLETION && !(flags & MONO_SEM_FLAGS_ALERTABLE))
+               goto retry;
 
-/**
- * mono_os_sem_timedwait:
- *
- * @returns: see MonoSemTimedwaitRet
- */
-MonoSemTimedwaitRet
-mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags);
+       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_post:
- */
-void
-mono_os_sem_post (MonoSemType *sem);
+static inline int
+mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
+{
+       return mono_os_sem_timedwait (sem, INFINITE, flags) != 0 ? -1 : 0;
+}
+
+static inline 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
 
 G_END_DECLS