[libdispatch-changes] [82] trunk
source_changes at macosforge.org
source_changes at macosforge.org
Mon Nov 2 03:19:17 PST 2009
Revision: 82
http://trac.macosforge.org/projects/libdispatch/changeset/82
Author: robert at fledge.watson.org
Date: 2009-11-02 03:19:15 -0800 (Mon, 02 Nov 2009)
Log Message:
-----------
Rework configure and conditional compilation logic for OS-provided
semaphores: generate USE_MACH_SEM and USE_POSIX_SEM definitions so that
precedence is selected in configure.ac rather than in the source code.
This makes the policy of "use Mach semaphores even if POSIX semaphoresare
available" explicit in the configuration process rather than implicit in
the ifdefs.
While here, migrate to defining a value of '1' rather than a simple
define, as suggested by Kevin Van Vechten.
In the future, we might want to add a --enable-posix-sem to allow forcing
the use of POSIX semaphores on Mac OS X.
Modified Paths:
--------------
trunk/configure.ac
trunk/src/internal.h
trunk/src/legacy.h
trunk/src/queue.c
trunk/src/semaphore.c
trunk/src/semaphore_internal.h
Modified: trunk/configure.ac
===================================================================
--- 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
===================================================================
--- 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
===================================================================
--- 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
===================================================================
--- 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
===================================================================
--- 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
===================================================================
--- 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"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/libdispatch-changes/attachments/20091102/8176a3d3/attachment-0001.html>
More information about the libdispatch-changes
mailing list