2 * mono-semaphore.c: mono-semaphore functions
5 * Gonzalo Paniagua Javier <gonzalo@novell.com>
7 * (C) 2010 Novell, Inc.
12 #include "utils/mono-semaphore.h"
13 #ifdef HAVE_SYS_TIME_H
20 #if (defined(HAVE_SEMAPHORE_H) || defined(USE_MACH_SEMA))
21 /* sem_* or semaphore_* functions in use */
23 # define TIMESPEC mach_timespec_t
24 # define WAIT_BLOCK(a,b) semaphore_timedwait (*(a), *(b))
25 # elif defined(__OpenBSD__)
26 # define TIMESPEC struct timespec
27 # define WAIT_BLOCK(a) sem_trywait(a)
29 # define TIMESPEC struct timespec
30 # define WAIT_BLOCK(a,b) sem_timedwait (a, b)
33 #define NSEC_PER_SEC 1000000000
35 mono_sem_timedwait (MonoSemType
*sem
, guint32 timeout_ms
, gboolean alertable
)
40 #if defined(__OpenBSD__)
46 return (!sem_trywait (sem
));
48 if (timeout_ms
== (guint32
) 0xFFFFFFFF)
49 return mono_sem_wait (sem
, alertable
);
51 gettimeofday (&t
, NULL
);
52 ts
.tv_sec
= timeout_ms
/ 1000 + t
.tv_sec
;
53 ts
.tv_nsec
= (timeout_ms
% 1000) * 1000000 + t
.tv_usec
* 1000;
54 while (ts
.tv_nsec
> NSEC_PER_SEC
) {
55 ts
.tv_nsec
-= NSEC_PER_SEC
;
58 #if defined(__OpenBSD__)
61 if ((res
= WAIT_BLOCK (sem
)) == 0)
67 usleep (ts
.tv_nsec
/ 1000);
72 while ((res
= WAIT_BLOCK (sem
, &ts
) == -1) && errno
== EINTR
) {
73 struct timeval current
;
76 gettimeofday (¤t
, NULL
);
78 ts
.tv_sec
-= (current
.tv_sec
- t
.tv_sec
);
79 ts
.tv_nsec
-= (current
.tv_usec
- t
.tv_usec
) * 1000;
85 ts
.tv_nsec
+= NSEC_PER_SEC
;
98 mono_sem_wait (MonoSemType
*sem
, gboolean alertable
)
101 #ifndef USE_MACH_SEMA
102 while ((res
= sem_wait (sem
) == -1) && errno
== EINTR
)
104 while ((res
= semaphore_wait (*sem
) == -1) && errno
== EINTR
)
114 mono_sem_post (MonoSemType
*sem
)
117 #ifndef USE_MACH_SEMA
118 while ((res
= sem_post (sem
) == -1) && errno
== EINTR
);
120 while ((res
= semaphore_signal (*sem
) == -1) && errno
== EINTR
);
126 /* Windows or io-layer functions in use */
128 mono_sem_wait (MonoSemType
*sem
, gboolean alertable
)
130 return mono_sem_timedwait (sem
, INFINITE
, alertable
);
134 mono_sem_timedwait (MonoSemType
*sem
, guint32 timeout_ms
, gboolean alertable
)
138 while (res
= WaitForSingleObjectEx (*sem
, timeout_ms
, TRUE
) == WAIT_IO_COMPLETION
)
148 // WAIT_TIMEOUT and WAIT_FAILED
155 mono_sem_post (MonoSemType
*sem
)
157 if (!ReleaseSemaphore (*sem
, 1, NULL
))