9 #if !defined(HOST_WIN32)
17 #ifdef HAVE_SYS_TIME_H
21 #include "mono-os-mutex.h"
23 #if !defined(HOST_WIN32)
26 mono_os_mutex_init (mono_mutex_t *mutex)
30 res = pthread_mutex_init (mutex, NULL);
31 if (G_UNLIKELY (res != 0))
32 g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
36 mono_os_mutex_init_recursive (mono_mutex_t *mutex)
39 pthread_mutexattr_t attr;
41 res = pthread_mutexattr_init (&attr);
42 if (G_UNLIKELY (res != 0))
43 g_error ("%s: pthread_mutexattr_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
45 res = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
46 if (G_UNLIKELY (res != 0))
47 g_error ("%s: pthread_mutexattr_settype failed with \"%s\" (%d)", __func__, g_strerror (res), res);
49 res = pthread_mutex_init (mutex, &attr);
50 if (G_UNLIKELY (res != 0))
51 g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
53 res = pthread_mutexattr_destroy (&attr);
54 if (G_UNLIKELY (res != 0))
55 g_error ("%s: pthread_mutexattr_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
59 mono_os_mutex_destroy (mono_mutex_t *mutex)
63 res = pthread_mutex_destroy (mutex);
64 if (G_UNLIKELY (res != 0 && res != EBUSY))
65 g_error ("%s: pthread_mutex_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
67 return res != 0 ? -1 : 0;
71 mono_os_mutex_lock (mono_mutex_t *mutex)
75 res = pthread_mutex_lock (mutex);
76 if (G_UNLIKELY (res != 0))
77 g_error ("%s: pthread_mutex_lock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
81 mono_os_mutex_trylock (mono_mutex_t *mutex)
85 res = pthread_mutex_trylock (mutex);
86 if (G_UNLIKELY (res != 0 && res != EBUSY))
87 g_error ("%s: pthread_mutex_trylock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
89 return res != 0 ? -1 : 0;
93 mono_os_mutex_unlock (mono_mutex_t *mutex)
97 res = pthread_mutex_unlock (mutex);
98 if (G_UNLIKELY (res != 0))
99 g_error ("%s: pthread_mutex_unlock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
103 mono_os_cond_init (mono_cond_t *cond)
107 res = pthread_cond_init (cond, NULL);
108 if (G_UNLIKELY (res != 0))
109 g_error ("%s: pthread_cond_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
113 mono_os_cond_destroy (mono_cond_t *cond)
117 res = pthread_cond_destroy (cond);
118 if (G_UNLIKELY (res != 0 && res != EBUSY))
119 g_error ("%s: pthread_cond_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
121 return res != 0 ? -1 : 0;
125 mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
129 res = pthread_cond_wait (cond, mutex);
130 if (G_UNLIKELY (res != 0))
131 g_error ("%s: pthread_cond_wait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
135 mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
142 if (timeout_ms == MONO_INFINITE_WAIT) {
143 mono_os_cond_wait (cond, mutex);
147 /* ms = 10^-3, us = 10^-6, ns = 10^-9 */
149 res = gettimeofday (&tv, NULL);
150 if (G_UNLIKELY (res != 0))
151 g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
153 tv.tv_sec += timeout_ms / 1000;
154 usecs = tv.tv_usec + ((timeout_ms % 1000) * 1000);
155 if (usecs >= 1000000) {
159 ts.tv_sec = tv.tv_sec;
160 ts.tv_nsec = usecs * 1000;
162 res = pthread_cond_timedwait (cond, mutex, &ts);
163 if (G_UNLIKELY (res != 0 && res != ETIMEDOUT))
164 g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
166 return res != 0 ? -1 : 0;
170 mono_os_cond_signal (mono_cond_t *cond)
174 res = pthread_cond_signal (cond);
175 if (G_UNLIKELY (res != 0))
176 g_error ("%s: pthread_cond_signal failed with \"%s\" (%d)", __func__, g_strerror (res), res);
180 mono_os_cond_broadcast (mono_cond_t *cond)
184 res = pthread_cond_broadcast (cond);
185 if (G_UNLIKELY (res != 0))
186 g_error ("%s: pthread_cond_broadcast failed with \"%s\" (%d)", __func__, g_strerror (res), res);
191 /* Vanilla MinGW is missing some defs, load them from MinGW-w64. */
192 #if defined __MINGW32__ && !defined __MINGW64_VERSION_MAJOR && (_WIN32_WINNT >= 0x0600)
194 /* Fixme: Opaque structs */
195 typedef PVOID RTL_CONDITION_VARIABLE;
197 #define RTL_SRWLOCK_INIT 0
198 #define RTL_CONDITION_VARIABLE_INIT 0
199 #define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 1
201 /*Condition Variables http://msdn.microsoft.com/en-us/library/ms682052%28VS.85%29.aspx*/
202 typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
204 WINBASEAPI VOID WINAPI InitializeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
205 WINBASEAPI WINBOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD dwMilliseconds);
206 WINBASEAPI VOID WINAPI WakeAllConditionVariable(PCONDITION_VARIABLE ConditionVariable);
207 WINBASEAPI VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
209 /* https://msdn.microsoft.com/en-us/library/windows/desktop/ms683477(v=vs.85).aspx */
210 WINBASEAPI BOOL WINAPI InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags);
212 #define CRITICAL_SECTION_NO_DEBUG_INFO 0x01000000
214 #endif /* defined __MINGW32__ && !defined __MINGW64_VERSION_MAJOR && (_WIN32_WINNT >= 0x0600) */
217 mono_os_mutex_init (mono_mutex_t *mutex)
221 res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
222 if (G_UNLIKELY (res == 0))
223 g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
227 mono_os_mutex_init_recursive (mono_mutex_t *mutex)
231 res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
232 if (G_UNLIKELY (res == 0))
233 g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
237 mono_os_mutex_destroy (mono_mutex_t *mutex)
239 DeleteCriticalSection (mutex);
244 mono_os_mutex_lock (mono_mutex_t *mutex)
246 EnterCriticalSection (mutex);
250 mono_os_mutex_trylock (mono_mutex_t *mutex)
252 return TryEnterCriticalSection (mutex) == 0 ? -1 : 0;
256 mono_os_mutex_unlock (mono_mutex_t *mutex)
258 LeaveCriticalSection (mutex);
262 mono_os_cond_init (mono_cond_t *cond)
264 InitializeConditionVariable (cond);
268 mono_os_cond_destroy (mono_cond_t *cond)
270 /* Beauty of win32 API: do not destroy it */
275 mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
279 res = SleepConditionVariableCS (cond, mutex, INFINITE);
280 if (G_UNLIKELY (res == 0))
281 g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
285 mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
289 res = SleepConditionVariableCS (cond, mutex, timeout_ms);
290 if (G_UNLIKELY (res == 0 && GetLastError () != ERROR_TIMEOUT))
291 g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
293 return res == 0 ? -1 : 0;
297 mono_os_cond_signal (mono_cond_t *cond)
299 WakeConditionVariable (cond);
303 mono_os_cond_broadcast (mono_cond_t *cond)
305 WakeAllConditionVariable (cond);