Diff
Modified: trunk/configure.ac (81 => 82)
--- trunk/configure.ac 2009-11-02 10:58:46 UTC (rev 81)
+++ trunk/configure.ac 2009-11-02 11:19:15 UTC (rev 82)
@@ -137,10 +137,10 @@
#
AC_CHECK_HEADER([mach/mach.h],
[AC_DEFINE(HAVE_MACH,,Define if mach is present)
- use_mig=true],
- [use_mig=false]
+ have_mach=true],
+ [have_mach=false]
)
-AM_CONDITIONAL(USE_MIG, $use_mig)
+AM_CONDITIONAL(USE_MIG, $have_mach)
#
# We use the availability of pthread_workqueue.h to decide whether to compile
@@ -160,8 +160,27 @@
AC_CHECK_DECLS([FD_COPY], [], [], [[#include <sys/select.h>]])
AC_CHECK_DECLS([SIGEMT], [], [], [[#include <signal.h>]])
AC_CHECK_DECLS([VQ_UPDATE, VQ_VERYLOWDISK], [], [], [[#include <sys/mount.h>]])
-AC_CHECK_FUNCS([pthread_key_init_np pthread_main_np mach_absolute_time malloc_create_zone sem_init])
+AC_CHECK_FUNCS([pthread_key_init_np pthread_main_np mach_absolute_time malloc_create_zone])
+AC_CHECK_FUNC([sem_init],
+ [have_sem_init=true],
+ [have_sem_init=false]
+)
+
+#
+# We support both Mach semaphores and POSIX semaphores; if the former are
+# available, prefer them.
+#
+AC_MSG_CHECKING([what semaphore type to use]);
+AS_IF([test "x$have_mach" = "xtrue"],
+ [AC_DEFINE(USE_MACH_SEM,1,[Define to use Mach semaphores])
+ AC_MSG_RESULT([Mach semaphores])],
+ [test "x$have_sem_init" = "xtrue"],
+ [AC_DEFINE(USE_POSIX_SEM,1,[Define to use POSIX semaphores])
+ AC_MSG_RESULT([POSIX semaphores])],
+ [AC_MSG_ERROR([no supported semaphore type])]
+)
+
AC_CHECK_HEADERS([sys/cdefs.h], [], [],
[#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
Modified: trunk/src/internal.h (81 => 82)
--- trunk/src/internal.h 2009-11-02 10:58:46 UTC (rev 81)
+++ trunk/src/internal.h 2009-11-02 11:19:15 UTC (rev 82)
@@ -105,7 +105,7 @@
#include <fcntl.h>
#include <limits.h>
#include <search.h>
-#if !defined(HAVE_MACH) && defined(HAVE_SEM_INIT)
+#if USE_POSIX_SEM
#include <semaphore.h>
#endif
#include <signal.h>
Modified: trunk/src/legacy.h (81 => 82)
--- trunk/src/legacy.h 2009-11-02 10:58:46 UTC (rev 81)
+++ trunk/src/legacy.h 2009-11-02 11:19:15 UTC (rev 82)
@@ -51,9 +51,12 @@
struct dispatch_item_s *volatile di_next;
dispatch_queue_t di_cback_q;
uint32_t di_flags;
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
semaphore_t di_semaphore;
#endif
+#if USE_POSIX_SEM
+ /* Legacy API not supported except with Mach semaphores. */
+#endif
void * di_work_func;
void * di_work_ctxt;
void * di_cback_func;
Modified: trunk/src/queue.c (81 => 82)
--- trunk/src/queue.c 2009-11-02 10:58:46 UTC (rev 81)
+++ trunk/src/queue.c 2009-11-02 11:19:15 UTC (rev 82)
@@ -1110,9 +1110,10 @@
pthread_workqueue_attr_t pwq_attr;
int r;
#endif
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
kern_return_t kr;
-#else
+#endif
+#if USE_POSIX_SEM
int ret;
#endif
int i;
@@ -1141,13 +1142,14 @@
dispatch_assume_zero(r);
}
#endif /* HAVE_PTHREAD_WORKQUEUES */
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
// override the default FIFO behavior for the pool semaphores
kr = semaphore_create(mach_task_self(), &_dispatch_thread_mediator[i].dsema_port, SYNC_POLICY_LIFO, 0);
DISPATCH_VERIFY_MIG(kr);
dispatch_assume_zero(kr);
dispatch_assume(_dispatch_thread_mediator[i].dsema_port);
-#else
+#endif
+#if USE_POSIX_SEM
/* XXXRW: POSIX semaphores don't support LIFO? */
ret = sem_init(&_dispatch_thread_mediator[i].dsema_sem, 0, 0);
dispatch_assume_zero(ret);
Modified: trunk/src/semaphore.c (81 => 82)
--- trunk/src/semaphore.c 2009-11-02 10:58:46 UTC (rev 81)
+++ trunk/src/semaphore.c 2009-11-02 11:19:15 UTC (rev 82)
@@ -21,13 +21,14 @@
#include "internal.h"
// semaphores are too fundamental to use the dispatch_assume*() macros
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
#define DISPATCH_SEMAPHORE_VERIFY_KR(x) do { \
if (x) { \
DISPATCH_CRASH("flawed group/semaphore logic"); \
} \
} while (0)
-#else
+#endif
+#if USE_POSIX_SEM
#define DISPATCH_SEMAPHORE_VERIFY_RET(x) do { \
if ((x) == -1) { \
DISPATCH_CRASH("flawed group/semaphore logic"); \
@@ -108,7 +109,7 @@
return dsema;
}
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
static void
_dispatch_semaphore_create_port(semaphore_t *s4)
{
@@ -138,7 +139,8 @@
_dispatch_safe_fork = false;
}
-#else /* !HAVE_MACH */
+#endif
+#if USE_POSIX_SEM
static void
_dispatch_posix_semaphore_create(sem_t *s4)
{
@@ -151,16 +153,17 @@
ret = sem_init(s4, 0, 0);
dispatch_assume_zero(ret);
}
-#endif /* HAVE_MACH */
+#endif
DISPATCH_NOINLINE
static long
_dispatch_semaphore_wait_slow(dispatch_semaphore_t dsema, dispatch_time_t timeout)
{
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
mach_timespec_t _timeout;
kern_return_t kr;
-#else
+#endif
+#if USE_POSIX_SEM
struct timespec _timeout;
int ret;
#endif
@@ -177,9 +180,10 @@
}
}
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
_dispatch_semaphore_create_port(&dsema->dsema_port);
-#else
+#endif
+#if USE_POSIX_SEM
_dispatch_posix_semaphore_create(&dsema->dsema_sem);
#endif
@@ -193,7 +197,7 @@
switch (timeout) {
default:
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
do {
// timeout() already calculates relative time left
nsec = _dispatch_timeout(timeout);
@@ -206,7 +210,8 @@
DISPATCH_SEMAPHORE_VERIFY_KR(kr);
break;
}
-#else /* !HAVE_MACH */
+#endif
+#if USE_POSIX_SEM
do {
nsec = _dispatch_timeout(timeout);
_timeout.tv_sec = (typeof(_timeout.tv_sec))
@@ -221,14 +226,15 @@
DISPATCH_SEMAPHORE_VERIFY_RET(ret);
break;
}
-#endif /* HAVE_MACH */
+#endif
// Fall through and try to undo what the fast path did to dsema->dsema_value
case DISPATCH_TIME_NOW:
while ((orig = dsema->dsema_value) < 0) {
if (dispatch_atomic_cmpxchg(&dsema->dsema_value, orig, orig + 1)) {
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
return KERN_OPERATION_TIMED_OUT;
-#else
+#endif
+#if USE_POSIX_SEM
errno = ETIMEDOUT;
return -1;
#endif
@@ -237,12 +243,13 @@
// Another thread called semaphore_signal().
// Fall through and drain the wakeup.
case DISPATCH_TIME_FOREVER:
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
do {
kr = semaphore_wait(dsema->dsema_port);
} while (kr == KERN_ABORTED);
DISPATCH_SEMAPHORE_VERIFY_KR(kr);
-#else
+#endif
+#if USE_POSIX_SEM
do {
ret = sem_wait(&dsema->dsema_sem);
} while (ret != 0);
@@ -318,9 +325,10 @@
static long
_dispatch_semaphore_signal_slow(dispatch_semaphore_t dsema)
{
-#ifndef HAVE_MACH
+#if USE_POSIX_SEM
int ret;
-#else
+#endif
+#if USE_MACH_SEM
kern_return_t kr;
_dispatch_semaphore_create_port(&dsema->dsema_port);
@@ -335,10 +343,11 @@
dispatch_atomic_inc(&dsema->dsema_sent_ksignals);
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
kr = semaphore_signal(dsema->dsema_port);
DISPATCH_SEMAPHORE_VERIFY_KR(kr);
-#else
+#endif
+#if USE_POSIX_SEM
ret = sem_post(&dsema->dsema_sem);
#endif
@@ -398,22 +407,24 @@
struct dispatch_sema_notify_s *tmp, *head = dispatch_atomic_xchg(&dsema->dsema_notify_head, NULL);
long rval = dispatch_atomic_xchg(&dsema->dsema_group_waiters, 0);
bool do_rel = head;
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
long kr;
-#else
+#endif
+#if USE_POSIX_SEM
int ret;
#endif
// wake any "group" waiter or notify blocks
if (rval) {
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
_dispatch_semaphore_create_port(&dsema->dsema_waiter_port);
do {
kr = semaphore_signal(dsema->dsema_waiter_port);
DISPATCH_SEMAPHORE_VERIFY_KR(kr);
} while (--rval);
-#else
+#endif
+#if USE_POSIX_SEM
do {
ret = sem_post(&dsema->dsema_sem);
DISPATCH_SEMAPHORE_VERIFY_RET(ret);
@@ -439,10 +450,11 @@
static long
_dispatch_group_wait_slow(dispatch_semaphore_t dsema, dispatch_time_t timeout)
{
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
mach_timespec_t _timeout;
kern_return_t kr;
-#else
+#endif
+#if USE_POSIX_SEM
struct timespec _timeout;
int ret;
#endif
@@ -463,7 +475,7 @@
return _dispatch_group_wake(dsema);
}
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
_dispatch_semaphore_create_port(&dsema->dsema_waiter_port);
#endif
@@ -477,7 +489,7 @@
switch (timeout) {
default:
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
do {
nsec = _dispatch_timeout(timeout);
_timeout.tv_sec = (typeof(_timeout.tv_sec))(nsec / NSEC_PER_SEC);
@@ -488,7 +500,8 @@
DISPATCH_SEMAPHORE_VERIFY_KR(kr);
break;
}
-#else
+#endif
+#if USE_POSIX_SEM
do {
nsec = _dispatch_timeout(timeout);
_timeout.tv_sec = (typeof(_timeout.tv_sec))
@@ -507,9 +520,10 @@
case DISPATCH_TIME_NOW:
while ((orig = dsema->dsema_group_waiters)) {
if (dispatch_atomic_cmpxchg(&dsema->dsema_group_waiters, orig, orig - 1)) {
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
return KERN_OPERATION_TIMED_OUT;
-#else
+#endif
+#if USE_POSIX_SEM
errno = ETIMEDOUT;
return -1;
#endif
@@ -518,12 +532,13 @@
// Another thread called semaphore_signal().
// Fall through and drain the wakeup.
case DISPATCH_TIME_FOREVER:
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
do {
kr = semaphore_wait(dsema->dsema_waiter_port);
} while (kr == KERN_ABORTED);
DISPATCH_SEMAPHORE_VERIFY_KR(kr);
-#else
+#endif
+#if USE_POSIX_SEM
do {
ret = sem_wait(&dsema->dsema_sem);
} while (ret == -1 && errno == EINTR);
@@ -544,9 +559,10 @@
return 0;
}
if (timeout == 0) {
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
return KERN_OPERATION_TIMED_OUT;
-#else
+#endif
+#if USE_POSIX_SEM
errno = ETIMEDOUT;
return (-1);
#endif
@@ -594,9 +610,10 @@
void
_dispatch_semaphore_dispose(dispatch_semaphore_t dsema)
{
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
kern_return_t kr;
-#else
+#endif
+#if USE_POSIX_SEM
int ret;
#endif
@@ -604,7 +621,7 @@
DISPATCH_CLIENT_CRASH("Semaphore/group object deallocated while in use");
}
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
if (dsema->dsema_port) {
kr = semaphore_destroy(mach_task_self(), dsema->dsema_port);
DISPATCH_SEMAPHORE_VERIFY_KR(kr);
@@ -613,7 +630,8 @@
kr = semaphore_destroy(mach_task_self(), dsema->dsema_waiter_port);
DISPATCH_SEMAPHORE_VERIFY_KR(kr);
}
-#else
+#endif
+#if USE_POSIX_SEM
ret = sem_destroy(&dsema->dsema_sem);
DISPATCH_SEMAPHORE_VERIFY_RET(ret);
#endif
@@ -627,7 +645,7 @@
size_t offset = 0;
offset += snprintf(&buf[offset], bufsiz - offset, "%s[%p] = { ", dx_kind(dsema), dsema);
offset += dispatch_object_debug_attr(dsema, &buf[offset], bufsiz - offset);
-#ifdef HAVE_MACH
+#if USE_MACH_SEM
offset += snprintf(&buf[offset], bufsiz - offset, "port = 0x%u, ",
dsema->dsema_port);
#endif
Modified: trunk/src/semaphore_internal.h (81 => 82)
--- trunk/src/semaphore_internal.h 2009-11-02 10:58:46 UTC (rev 81)
+++ trunk/src/semaphore_internal.h 2009-11-02 11:19:15 UTC (rev 82)
@@ -39,10 +39,12 @@
long dsema_value;
long dsema_orig;
size_t dsema_sent_ksignals;
-#ifdef HAVE_MACH
+#if USE_MACH_SEM && USE_POSIX_SEM
+#error "Too many supported semaphore types"
+#elif USE_MACH_SEM
semaphore_t dsema_port;
semaphore_t dsema_waiter_port;
-#elif defined(HAVE_SEM_INIT)
+#elif USE_POSIX_SEM
sem_t dsema_sem;
#else
#error "No supported semaphore type"