3 * Portability wrappers around POSIX Mutexes
5 * Authors: Jeffrey Stedfast <fejj@ximian.com>
7 * Copyright 2002 Ximian, Inc. (www.ximian.com)
9 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
15 #if !defined(HOST_WIN32)
17 #if defined(TARGET_OSX)
18 /* So we can use the declaration of pthread_cond_timedwait_relative_np () */
23 #include "mono-os-mutex.h"
26 mono_os_cond_timedwait (mono_cond_t
*cond
, mono_mutex_t
*mutex
, guint32 timeout_ms
)
31 if (timeout_ms
== MONO_INFINITE_WAIT
) {
32 mono_os_cond_wait (cond
, mutex
);
36 /* ms = 10^-3, us = 10^-6, ns = 10^-9 */
38 /* This function only seems to be available on 64bit osx */
39 #if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP) && defined(TARGET_OSX)
40 memset (&ts
, 0, sizeof (struct timespec
));
41 ts
.tv_sec
= timeout_ms
/ 1000;
42 ts
.tv_nsec
= (timeout_ms
% 1000) * 1000 * 1000;
44 res
= pthread_cond_timedwait_relative_np (cond
, mutex
, &ts
);
45 if (G_UNLIKELY (res
!= 0 && res
!= ETIMEDOUT
)) {
46 g_print ("cond: %p mutex: %p\n", *(gpointer
*)cond
, *(gpointer
*)mutex
);
47 g_error ("%s: pthread_cond_timedwait_relative_np failed with \"%s\" (%d) %ld %ld %d", __func__
, g_strerror (res
), res
, ts
.tv_sec
, ts
.tv_nsec
, timeout_ms
);
49 return res
!= 0 ? -1 : 0;
51 #ifdef BROKEN_CLOCK_SOURCE
54 /* clock_gettime is not supported in MAC OS x */
55 res
= gettimeofday (&tv
, NULL
);
56 if (G_UNLIKELY (res
!= 0))
57 g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__
, g_strerror (errno
), errno
);
59 ts
.tv_sec
= tv
.tv_sec
;
60 ts
.tv_nsec
= tv
.tv_usec
* 1000;
62 /* cond is using CLOCK_MONOTONIC as time source */
63 res
= clock_gettime (CLOCK_MONOTONIC
, &ts
);
64 if (G_UNLIKELY (res
!= 0))
65 g_error ("%s: clock_gettime failed with \"%s\" (%d)", __func__
, g_strerror (errno
), errno
);
68 ts
.tv_sec
+= timeout_ms
/ 1000;
69 ts
.tv_nsec
+= (timeout_ms
% 1000) * 1000 * 1000;
70 if (ts
.tv_nsec
>= 1000 * 1000 * 1000) {
71 ts
.tv_nsec
-= 1000 * 1000 * 1000;
75 res
= pthread_cond_timedwait (cond
, mutex
, &ts
);
76 if (G_UNLIKELY (res
!= 0 && res
!= ETIMEDOUT
)) {
77 g_print ("cond: %p mutex: %p\n", *(gpointer
*)cond
, *(gpointer
*)mutex
);
78 g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d) %ld %ld %d", __func__
, g_strerror (res
), res
, ts
.tv_sec
, ts
.tv_nsec
, timeout_ms
);
80 return res
!= 0 ? -1 : 0;
81 #endif /* !HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP */
84 #endif /* HOST_WIN32 */