[libdispatch-changes] [27] trunk/src

source_changes at macosforge.org source_changes at macosforge.org
Mon Sep 14 11:46:19 PDT 2009


Revision: 27
          http://trac.macosforge.org/projects/libdispatch/changeset/27
Author:   robert at fledge.watson.org
Date:     2009-09-14 11:46:18 -0700 (Mon, 14 Sep 2009)
Log Message:
-----------
Port of libdispatch to the FreeBSD operating system, which consisted of
disabling various Mac OS X-specific portions of the library (such as Mach),
providing portable versions of certain services internally (POSIX semaphores
instead of Mach semaphores, clock_gettime() instead of mac_absolute_time()),
and providing an autoconf/automake/libtool build infrastructure.  This is
just a first cut, refinement to follow.

Conditionalize portions of the libdispatch build as follows:

HAVE_MACH
	If Mach is present, support Mach ports throughout libdispatch.

USE_LIBDISPATCH_INIT_CONSTRUCTOR
	If defined, add the 'constructor' attribute to libdispatch_init so
	that it runs as part of library initialization.  This is not needed
	in Mac OS X libSystem due to explicit invocation of libpthread_init
	by libsyscall, but is for a stand-alone library.

HAVE_DECL_EVFILT_SESSION, HAVE_DECL_NOTE_SIGNAL, HAVE_DECL_NOTE_REAP,
HAVE_DECL_NOTE_NONE, HAVE_DECL_VQ_UPDATE, HAVE_DECL_VQ_VERYLOWDISK
	Conditionally support kqueue events that are not present on FreeBSD.

DISPATCH_NO_LEGACY
	Expand the scope of this existing macro to allow libdispatch to
	build without legacy.c.

HAVE_MACH_ABSOLUTE_TIME
	Wrap mach_absolute_time() in _dispatch_absolute_time(), and
	provide a portable clock_gettime() implementation.  Some further
	refinment will be required here.

USE_APPLE_SEMAPHORE_OPTIMIZATIONS
	Only use non-portable assembly optimizations of dispatch semaphores
	if supported.

HAVE_SEM_INIT
	Use POSIX semaphores if Mach semaphores aren't present; further
	ifdef'ing possibly required here.  If neither HAVE_MACH nor
	HAVE_SEM_INIT are present, the compile will fail.

USE_APPLE_CRASHREPORTER_INFO
	Only define Mac OS X crashreporter state if requested.

HAVE_PTHREAD_WORKQUEUES
	Only compile in support for pthread work queues if present;
	otherwise force use of normal worker threads.

HAVE_PTHREAD_KEY_INIT_NP
	If defined, use non-portable allocation of pthread keys--otherwise,
	use pthread_create_key().

USE_APPLE_TSD_OPTIMIZATIONS
	Only use non-portable assembly optimizations if dispatch thread-
	specific data if this is defined.

HAVE_MALLOC_CREATE_ZONE
	If not present, use compat/malloc_zone.h which implements the malloc
	zone APIs using normal malloc(3).

Also fix some portability nits for building, such as casting before using
long as a format string for several types.  Note that this port will not
build or run on a stock FreeBSD release or svn distribution yet, as it
relies on kqueue extensions not committed back to FreeBSD yet.

There are several known issues, such as how best to map CLOCK_UPTIME or
CLOCK_MONOTONIC struct timespec timestamps into a Mach absolute time
int64_t number space.  Also, the POSIX semaphore ifdefing is adequate but
not complete.

Modified Paths:
--------------
    trunk/src/benchmark.c
    trunk/src/dispatch.h
    trunk/src/internal.h
    trunk/src/legacy.h
    trunk/src/os_shims.h
    trunk/src/private.h
    trunk/src/queue.c
    trunk/src/queue_internal.h
    trunk/src/semaphore.c
    trunk/src/semaphore_internal.h
    trunk/src/shims.c
    trunk/src/source.c
    trunk/src/source.h
    trunk/src/source_private.h
    trunk/src/time.c

Modified: trunk/src/benchmark.c
===================================================================
--- trunk/src/benchmark.c	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/benchmark.c	2009-09-14 18:46:18 UTC (rev 27)
@@ -22,7 +22,9 @@
 
 
 struct __dispatch_benchmark_data_s {
+#ifdef HAVE_MACH_ABSOLUTE_TIME
 	mach_timebase_info_data_t tbi;
+#endif
 	uint64_t loop_cost;
 	void (*func)(void *);
 	void *ctxt;
@@ -38,28 +40,32 @@
 	register void (*f)(void *) = bdata->func;
 	register void *c = bdata->ctxt;
 	register size_t cnt = bdata->count;
+	size_t i = 0;
 	uint64_t start, delta;
 #ifdef __LP64__
 	__uint128_t lcost;
 #else
 	long double lcost;
 #endif
+#ifdef HAVE_MACH_ABSOLUTE_TIME
 	kern_return_t kr;
-	size_t i = 0;
 
 	kr = mach_timebase_info(&bdata->tbi);
 	dispatch_assert_zero(kr);
+#endif
 
-	start = mach_absolute_time();
+	start = _dispatch_absolute_time();
 	do {
 		i++;
 		f(c);
 	} while (i < cnt);
-	delta = mach_absolute_time() - start;
+	delta = _dispatch_absolute_time() - start;
 
 	lcost = delta;
+#ifdef HAVE_MACH_ABSOLUTE_TIME
 	lcost *= bdata->tbi.numer;
 	lcost /= bdata->tbi.denom;
+#endif
 	lcost /= cnt;
 
 	bdata->loop_cost = lcost;
@@ -96,16 +102,20 @@
 		return 0;
 	}
 
-	start = mach_absolute_time();
+	start = _dispatch_absolute_time();
 	do {
 		i++;
 		func(ctxt);
 	} while (i < count);
-	delta = mach_absolute_time() - start;
+	delta = _dispatch_absolute_time() - start;
 
 	conversion = delta;
+#ifdef HAVE_MACH_ABSOLUTE_TIME
 	conversion *= bdata.tbi.numer;
 	big_denom = bdata.tbi.denom;
+#else
+	big_denom = delta;
+#endif
 	big_denom *= count;
 	conversion /= big_denom;
 	ns = conversion;

Modified: trunk/src/dispatch.h
===================================================================
--- trunk/src/dispatch.h	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/dispatch.h	2009-09-14 18:46:18 UTC (rev 27)
@@ -21,7 +21,9 @@
 #ifndef __DISPATCH_PUBLIC__
 #define __DISPATCH_PUBLIC__
 
+#ifdef __APPLE__
 #include <Availability.h>
+#endif
 #include <sys/cdefs.h>
 #include <stddef.h>
 #include <stdint.h>

Modified: trunk/src/internal.h
===================================================================
--- trunk/src/internal.h	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/internal.h	2009-09-14 18:46:18 UTC (rev 27)
@@ -27,8 +27,21 @@
 #ifndef __DISPATCH_INTERNAL__
 #define __DISPATCH_INTERNAL__
 
+#include <config/config.h>
+
 #define __DISPATCH_BUILDING_DISPATCH__
 #define __DISPATCH_INDIRECT__
+
+#ifndef HAVE_MALLOC_CREATE_ZONE
+#include <compat/malloc_zone.h>
+#endif
+
+#ifdef HAVE_AVAILABILITY_H
+#include <Availability.h>
+#else
+#include <compat/Availability.h>
+#endif
+
 #include "dispatch.h"
 #include "base.h"
 #include "time.h"
@@ -54,8 +67,13 @@
 #endif
 
 
+#ifdef HAVE_LIBKERN_OSCROSSENDIAN_H
 #include <libkern/OSCrossEndian.h>
+#endif
+#ifdef HAVE_LIBKERN_OSATOMIC_H
 #include <libkern/OSAtomic.h>
+#endif
+#ifdef HAVE_MACH
 #include <mach/boolean.h>
 #include <mach/clock_types.h>
 #include <mach/clock.h>
@@ -70,7 +88,10 @@
 #include <mach/mig_errors.h>
 #include <mach/host_info.h>
 #include <mach/notify.h>
+#endif /* HAVE_MACH */
+#ifdef HAVE_MALLOC_MALLOC_H
 #include <malloc/malloc.h>
+#endif
 #include <sys/event.h>
 #include <sys/mount.h>
 #include <sys/queue.h>
@@ -89,6 +110,9 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <search.h>
+#if !defined(HAVE_MACH) && defined(HAVE_SEM_INIT)
+#include <semaphore.h>
+#endif
 #include <signal.h>
 #include <stdarg.h>
 #include <stdbool.h>
@@ -261,6 +285,9 @@
 #include "semaphore_internal.h"
 #include "source_internal.h"
 
+#ifdef USE_APPLE_CRASHREPORTER_INFO
+
+#ifdef HAVE_MACH
 // MIG_REPLY_MISMATCH means either:
 // 1) A signal handler is NOT using async-safe API. See the sigaction(2) man page for more info.
 // 2) A hand crafted call to mach_msg*() screwed up. Use MIG.
@@ -270,6 +297,7 @@
 			_dispatch_hardware_crash();	\
 		}	\
 	} while (0)
+#endif
 
 #if defined(__x86_64__) || defined(__i386__)
 // total hack to ensure that return register of a function is not trashed
@@ -283,7 +311,7 @@
 		_dispatch_hardware_crash();	\
 	} while (0)
 
-#else
+#else /* !(defined(__x86_64__) || defined(__i386__)) */
 
 #define DISPATCH_CRASH(x)	do {	\
 		__crashreporter_info__ = "BUG IN LIBDISPATCH: " x;	\
@@ -294,8 +322,21 @@
 		__crashreporter_info__ = "BUG IN CLIENT OF LIBDISPATCH: " x;	\
 		_dispatch_hardware_crash();	\
 	} while (0)
+#endif /* defined(__x86_64__) || defined(__i386__) */
 
+#else /* !USE_APPLE_CRASHREPORTER_INFO */
+
+#ifdef HAVE_MACH
+#define DISPATCH_VERIFY_MIG(x) do {	\
+		if ((x) == MIG_REPLY_MISMATCH) {	\
+			_dispatch_hardware_crash();	\
+		}	\
+	} while (0)
 #endif
 
+#define	DISPATCH_CRASH(x)		_dispatch_hardware_crash()
+#define	DISPATCH_CLIENT_CRASH(x)	_dispatch_hardware_crash()
 
+#endif /* USE_APPLE_CRASHREPORTER_INFO */
+
 #endif /* __DISPATCH_INTERNAL__ */

Modified: trunk/src/legacy.h
===================================================================
--- trunk/src/legacy.h	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/legacy.h	2009-09-14 18:46:18 UTC (rev 27)
@@ -37,7 +37,9 @@
 #include <dispatch/base.h> // for HeaderDoc
 #endif
 
+#ifdef HAVE_MACH
 #include <mach/mach_types.h>
+#endif
 
 #define DISPATCH_DEPRECATED __attribute__((deprecated))
 #define DISPATCH_PUBLIC_API __attribute__((visibility("default")))
@@ -49,7 +51,9 @@
 	struct dispatch_item_s *volatile        di_next;
 	dispatch_queue_t                        di_cback_q;
 	uint32_t                                di_flags;
+#ifdef HAVE_MACH
 	semaphore_t                             di_semaphore;
+#endif
 	void *					di_work_func;
 	void *                                  di_work_ctxt;
 	void *					di_cback_func;
@@ -302,11 +306,13 @@
 long
 dispatch_source_get_error(dispatch_source_t source, long* error);
 
+#ifdef HAVE_MACH
 // Use: dispatch_source_get_handle
 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
 DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_NOTHROW
 mach_port_t
 dispatch_source_get_machport(dispatch_source_t source);
+#endif
 
 // Use: dispatch_source_get_handle
 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
@@ -414,6 +420,7 @@
 	dispatch_source_attr_t attr,
 	void *context);
 
+#ifdef HAVE_MACH
 // Use: dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, ...)
 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
 DISPATCH_MALLOC DISPATCH_NONNULL4 DISPATCH_NONNULL5 DISPATCH_NOTHROW
@@ -424,6 +431,7 @@
 	dispatch_source_attr_t attr,
 	dispatch_queue_t queue,
 	dispatch_mig_callback_t mig_callback);
+#endif
 
 enum {
 	DISPATCH_TIMER_WALL_CLOCK	= 0x4,
@@ -588,6 +596,7 @@
 };
 
 // Use: dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, ...)
+#ifdef HAVE_MACH
 #ifdef __BLOCKS__
 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
 DISPATCH_MALLOC DISPATCH_NOTHROW
@@ -611,6 +620,7 @@
 	dispatch_queue_t queue,
 	void *h_context,
 	dispatch_source_handler_function_t handler);
+#endif /* HAVE_MACH */
 
 enum {
 	DISPATCH_SOURCE_DATA_ADD = 1,
@@ -691,6 +701,7 @@
 							 void *h_context,
 							 dispatch_source_handler_function_t handler);
 
+#ifdef HAVE_MACH
 /*
  * Raw Mach message support from MIG source.
  *
@@ -743,6 +754,8 @@
 new_callback(mach_msg_header_t *msg, mach_msg_header_t *reply) \
 { return _dispatch_CFMachPortCallBack(msg, reply, existing_callback); }
 
+#endif /* HAVE_MACH */
+
 __END_DECLS
 
 #endif

Modified: trunk/src/os_shims.h
===================================================================
--- trunk/src/os_shims.h	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/os_shims.h	2009-09-14 18:46:18 UTC (rev 27)
@@ -28,19 +28,35 @@
 #define __DISPATCH_OS_SHIMS__
 
 #include <pthread.h>
+#ifdef HAVE_PTHREAD_MACHDEP_H
 #include <pthread_machdep.h>
+#endif
+#ifdef HAVE_PTHREAD_WORKQUEUES
 #include <pthread_workqueue.h>
+#endif
+#ifdef HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
 
+#ifdef USE_APPLE_CRASHREPORTER_INFO
 __private_extern__ const char *__crashreporter_info__;
+#endif
 
+#ifdef HAVE_PTHREAD_KEY_INIT_NP
 static const unsigned long dispatch_queue_key = __PTK_LIBDISPATCH_KEY0;
 static const unsigned long dispatch_sema4_key = __PTK_LIBDISPATCH_KEY1;
 static const unsigned long dispatch_cache_key = __PTK_LIBDISPATCH_KEY2;
 static const unsigned long dispatch_bcounter_key = __PTK_LIBDISPATCH_KEY3;
 //__PTK_LIBDISPATCH_KEY4
 //__PTK_LIBDISPATCH_KEY5
+#else
+pthread_key_t dispatch_queue_key;
+pthread_key_t dispatch_sema4_key;
+pthread_key_t dispatch_cache_key;
+pthread_key_t dispatch_bcounter_key;
+#endif
 
-
+#ifdef USE_APPLE_TSD_OPTIMIZATIONS
 #define SIMULATE_5491082 1
 #ifndef _PTHREAD_TSD_OFFSET
 #define _PTHREAD_TSD_OFFSET 0
@@ -80,18 +96,46 @@
 #endif
 }
 
+#else /* !USE_APPLE_TSD_OPTIMIZATIONS */
+
 static inline void
+_dispatch_thread_setspecific(pthread_key_t k, void *v)
+{
+	int res;
+
+	res = pthread_setspecific(k, v);
+	dispatch_assert_zero(res);
+}
+
+static inline void *
+_dispatch_thread_getspecific(pthread_key_t k)
+{
+
+	return pthread_getspecific(k);
+}
+#endif /* USE_APPLE_TSD_OPTIMIZATIONS */
+
+#ifdef HAVE_PTHREAD_KEY_INIT_NP
+static inline void
 _dispatch_thread_key_init_np(unsigned long k, void (*d)(void *))
 {
 	dispatch_assert_zero(pthread_key_init_np((int)k, d));
 }
+#else
+static inline void
+_dispatch_thread_key_create(pthread_key_t *key, void (*destructor)(void *))
+{
 
+	dispatch_assert_zero(pthread_key_create(key, destructor));
+}
+#endif
+
 #define _dispatch_thread_self pthread_self
 
 
 #if DISPATCH_PERF_MON
 
-#if defined(SIMULATE_5491082) && (defined(__i386__) || defined(__x86_64__))
+#if defined (USE_APPLE_TSD_OPTIMIZATIONS) && defined(SIMULATE_5491082) && (defined(__i386__) || defined(__x86_64__))
 #ifdef __LP64__
 #define _dispatch_workitem_inc()	asm("incq %%gs:%0" : "+m"	\
 		(*(void **)(dispatch_bcounter_key * sizeof(void *) + _PTHREAD_TSD_OFFSET)) :: "cc")
@@ -103,7 +147,7 @@
 #define _dispatch_workitem_dec()	asm("decl %%gs:%0" : "+m"	\
 		(*(void **)(dispatch_bcounter_key * sizeof(void *) + _PTHREAD_TSD_OFFSET)) :: "cc")
 #endif
-#else
+#else /* !USE_APPLE_TSD_OPTIMIZATIONS */
 static inline void
 _dispatch_workitem_inc(void)
 {
@@ -116,7 +160,7 @@
 	unsigned long cnt = (unsigned long)_dispatch_thread_getspecific(dispatch_bcounter_key);
 	_dispatch_thread_setspecific(dispatch_bcounter_key, (void *)--cnt);
 }
-#endif
+#endif /* USE_APPLE_TSD_OPTIMIZATIONS */
 
 // C99 doesn't define flsll() or ffsll()
 #ifdef __LP64__
@@ -149,4 +193,21 @@
 #define _dispatch_workitem_dec()
 #endif	// DISPATCH_PERF_MON
 
+static inline uint64_t
+_dispatch_absolute_time(void)
+{
+#ifndef HAVE_MACH_ABSOLUTE_TIME
+	struct timespec ts;
+	int ret;
+
+	ret = clock_gettime(CLOCK_UPTIME, &ts);
+	dispatch_assume_zero(ret);
+
+	/* XXXRW: Some kind of overflow detection needed? */
+	return (ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec);
+#else
+	return mach_absolute_time();
 #endif
+}
+
+#endif

Modified: trunk/src/private.h
===================================================================
--- trunk/src/private.h	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/private.h	2009-09-14 18:46:18 UTC (rev 27)
@@ -27,9 +27,11 @@
 #ifndef __DISPATCH_PRIVATE__
 #define __DISPATCH_PRIVATE__
 
+#ifdef HAVE_MACH
 #include <mach/boolean.h>
 #include <mach/mach.h>
 #include <mach/message.h>
+#endif
 #include <unistd.h>
 #include <sys/cdefs.h>
 #include <sys/event.h>
@@ -66,8 +68,13 @@
 
 DISPATCH_NOTHROW
 void
+#ifdef USE_LIBDISPATCH_INIT_CONSTRUCTOR
+libdispatch_init(void) __attribute__ ((constructor));
+#else
 libdispatch_init(void);
+#endif
 
+#ifdef HAVE_MACH
 #define DISPATCH_COCOA_COMPAT 1
 #if DISPATCH_COCOA_COMPAT
 
@@ -94,6 +101,7 @@
 extern void (*_dispatch_end_NSAutoReleasePool)(void *);
 
 #endif
+#endif /* HAVE_MACH */
 
 /* pthreads magic */
 
@@ -102,12 +110,14 @@
 DISPATCH_NOTHROW void dispatch_atfork_child(void);
 DISPATCH_NOTHROW void dispatch_init_pthread(pthread_t);
 
+#ifdef HAVE_MACH
 /*
  * Extract the context pointer from a mach message trailer.
  */
 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
 void *
 dispatch_mach_msg_get_context(mach_msg_header_t *msg);
+#endif
 
 __END_DECLS
 

Modified: trunk/src/queue.c
===================================================================
--- trunk/src/queue.c	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/queue.c	2009-09-14 18:46:18 UTC (rev 27)
@@ -19,7 +19,9 @@
  */
 
 #include "internal.h"
+#ifdef HAVE_MACH
 #include "protocol.h"
+#endif
 
 void
 dummy_function(void)
@@ -190,7 +192,9 @@
 #define MAX_THREAD_COUNT 255
 
 struct dispatch_root_queue_context_s {
+#ifdef HAVE_PTHREAD_WORKQUEUES
 	pthread_workqueue_t dgq_kworkqueue;
+#endif
 	uint32_t dgq_pending;
 	uint32_t dgq_thread_pool_size;
 	dispatch_semaphore_t dgq_thread_mediator;
@@ -449,21 +453,35 @@
 _dispatch_queue_set_width_init(void)
 {
 	size_t valsz = sizeof(uint32_t);
+	int ret;
 
-	errno = 0;
-	sysctlbyname("hw.activecpu", &_dispatch_hw_config.cc_max_active, &valsz, NULL, 0);
-	dispatch_assume_zero(errno);
+#ifdef __APPLE__
+	ret = sysctlbyname("hw.activecpu", &_dispatch_hw_config.cc_max_active,
+	    &valsz, NULL, 0);
+	dispatch_assume_zero(ret);
 	dispatch_assume(valsz == sizeof(uint32_t));
 
-	errno = 0;
-	sysctlbyname("hw.logicalcpu_max", &_dispatch_hw_config.cc_max_logical, &valsz, NULL, 0);
-	dispatch_assume_zero(errno);
+	ret = sysctlbyname("hw.logicalcpu_max",
+	    &_dispatch_hw_config.cc_max_logical, &valsz, NULL, 0);
+	dispatch_assume_zero(ret);
 	dispatch_assume(valsz == sizeof(uint32_t));
 
-	errno = 0;
-	sysctlbyname("hw.physicalcpu_max", &_dispatch_hw_config.cc_max_physical, &valsz, NULL, 0);
-	dispatch_assume_zero(errno);
+	ret = sysctlbyname("hw.physicalcpu_max",
+	    &_dispatch_hw_config.cc_max_physical, &valsz, NULL, 0);
+	dispatch_assume_zero(ret);
 	dispatch_assume(valsz == sizeof(uint32_t));
+#elif defined(__FreeBSD__)
+	ret = sysctlbyname("kern.smp.cpus", &_dispatch_hw_config.cc_max_active,
+	    &valsz, NULL, 0);
+	dispatch_assume_zero(ret);
+	dispatch_assume(valsz == sizeof(uint32_t));
+
+	_dispatch_hw_config.cc_max_logical =
+	    _dispatch_hw_config.cc_max_physical =
+	    _dispatch_hw_config.cc_max_active;
+#else
+#error "_dispatch_queue_set_width_init: no supported way to query CPU count"
+#endif
 }
 
 void
@@ -966,12 +984,24 @@
 	dispatch_assert(countof(_dispatch_thread_mediator) == DISPATCH_ROOT_QUEUE_COUNT);
 	dispatch_assert(countof(_dispatch_root_queue_contexts) == DISPATCH_ROOT_QUEUE_COUNT);
 
+#ifdef HAVE_PTHREAD_KEY_INIT_NP
 	_dispatch_thread_key_init_np(dispatch_queue_key, _dispatch_queue_cleanup);
 	_dispatch_thread_key_init_np(dispatch_sema4_key, (void (*)(void *))dispatch_release);	// use the extern release
 	_dispatch_thread_key_init_np(dispatch_cache_key, _dispatch_cache_cleanup2);
 #if DISPATCH_PERF_MON
 	_dispatch_thread_key_init_np(dispatch_bcounter_key, NULL);
 #endif
+#else /* !HAVE_PTHREAD_KEY_INIT_NP */
+	_dispatch_thread_key_create(&dispatch_queue_key,
+	    _dispatch_queue_cleanup);
+	_dispatch_thread_key_create(&dispatch_sema4_key,
+	    (void (*)(void *))dispatch_release); // use the extern release
+	_dispatch_thread_key_create(&dispatch_cache_key,
+	    _dispatch_cache_cleanup2);
+#ifdef DISPATCH_PERF_MON
+	_dispatch_thread_key_create(&dispatch_bcounter_key, NULL);
+#endif
+#endif /* HAVE_PTHREAD_KEY_INIT_NP */
 
 	_dispatch_thread_setspecific(dispatch_queue_key, &_dispatch_main_q);
 
@@ -1040,6 +1070,7 @@
 }
 #endif
 
+#ifdef HAVE_PTHREAD_WORKQUEUES
 static inline int
 _dispatch_rootq2wq_pri(long idx)
 {
@@ -1060,19 +1091,30 @@
 	return pri;
 #endif
 }
+#endif
 
 static void
 _dispatch_root_queues_init(void *context __attribute__((unused)))
 {
+#ifdef HAVE_PTHREAD_WORKQUEUES
 	bool disable_wq = getenv("LIBDISPATCH_DISABLE_KWQ");
 	pthread_workqueue_attr_t pwq_attr;
+	int r;
+#endif
+#ifdef HAVE_MACH
 	kern_return_t kr;
-	int i, r;
+#else
+	int ret;
+#endif
+	int i;
 
+#ifdef HAVE_PTHREAD_WORKQUEUES
 	r = pthread_workqueue_attr_init_np(&pwq_attr);
 	dispatch_assume_zero(r);
+#endif
 
 	for (i = 0; i < DISPATCH_ROOT_QUEUE_COUNT; i++) {
+#ifdef HAVE_PTHREAD_WORKQUEUES
 		r = pthread_workqueue_attr_setqueuepriority_np(&pwq_attr, _dispatch_rootq2wq_pri(i));
 		dispatch_assume_zero(r);
 		r = pthread_workqueue_attr_setovercommit_np(&pwq_attr, i & 1);
@@ -1089,18 +1131,29 @@
 			if (r != ENOTSUP) {
 				dispatch_assume_zero(r);
 			}
+#endif /* HAVE_PTHREAD_WORKQUEUES */
+#ifdef HAVE_MACH
 			// 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
+			/* XXXRW: POSIX semaphores don't support LIFO? */
+			ret = sem_init(&_dispatch_thread_mediator[i].dsema_sem, 0, 0);
+			dispatch_assume_zero(ret);
+#endif
+#ifdef HAVE_PTHREAD_WORKQUEUES
 		} else {
 			dispatch_assume(_dispatch_root_queue_contexts[i].dgq_kworkqueue);
 		}
+#endif
 	}
 
+#ifdef HAVE_PTHREAD_WORKQUEUES
 	r = pthread_workqueue_attr_destroy_np(&pwq_attr);
 	dispatch_assume_zero(r);
+#endif
 }
 
 bool
@@ -1108,8 +1161,10 @@
 {
 	static dispatch_once_t pred;
 	struct dispatch_root_queue_context_s *qc = dq->do_ctxt;
+#ifdef HAVE_PTHREAD_WORKQUEUES
 	pthread_workitem_handle_t wh;
 	unsigned int gen_cnt;
+#endif
 	pthread_t pthr;
 	int r, t_count;
 
@@ -1123,6 +1178,7 @@
 
 	dispatch_once_f(&pred, NULL, _dispatch_root_queues_init);
 
+#ifdef HAVE_PTHREAD_WORKQUEUES
 	if (qc->dgq_kworkqueue) {
 		if (dispatch_atomic_cmpxchg(&qc->dgq_pending, 0, 1)) {
 			_dispatch_debug("requesting new worker thread");
@@ -1134,6 +1190,7 @@
 		}
 		goto out;
 	}
+#endif
 
 	if (dispatch_semaphore_signal(qc->dgq_thread_mediator)) {
 		goto out;
@@ -1164,7 +1221,7 @@
 _dispatch_queue_serial_drain_till_empty(dispatch_queue_t dq)
 {
 #if DISPATCH_PERF_MON
-	uint64_t start = mach_absolute_time();
+	uint64_t start = _dispatch_absolute_time();
 #endif
 	_dispatch_queue_drain(dq);
 #if DISPATCH_PERF_MON
@@ -1390,7 +1447,7 @@
 #endif
 
 #if DISPATCH_PERF_MON
-	uint64_t start = mach_absolute_time();
+	uint64_t start = _dispatch_absolute_time();
 #endif
 	while ((item = fastpath(_dispatch_queue_concurrent_drain_one(dq)))) {
 		_dispatch_continuation_pop(item);
@@ -1413,7 +1470,7 @@
 void
 _dispatch_queue_merge_stats(uint64_t start)
 {
-	uint64_t avg, delta = mach_absolute_time() - start;
+	uint64_t avg, delta = _dispatch_absolute_time() - start;
 	unsigned long count, bucket;
 
 	count = (size_t)_dispatch_thread_getspecific(dispatch_bcounter_key);
@@ -1489,7 +1546,7 @@
 static void
 dispatch_queue_attr_dispose(dispatch_queue_attr_t attr)
 {
-	dispatch_queue_attr_set_finalizer(attr, NULL);
+	dispatch_queue_attr_set_finalizer_f(attr, NULL, NULL);
 	_dispatch_dispose(attr);
 }
 
@@ -1622,13 +1679,20 @@
 
 static char _dispatch_build[16];
 
+/*
+ * XXXRW: What to do here for !Mac OS X?
+ */
 static void
 _dispatch_bug_init(void *context __attribute__((unused)))
 {
+#ifdef __APPLE__
 	int mib[] = { CTL_KERN, KERN_OSVERSION };
 	size_t bufsz = sizeof(_dispatch_build);
 
 	sysctl(mib, 2, _dispatch_build, &bufsz, NULL, 0);
+#else
+	bzero(_dispatch_build, sizeof(_dispatch_build));
+#endif
 }
 
 void
@@ -1641,7 +1705,7 @@
 	dispatch_once_f(&pred, NULL, _dispatch_bug_init);
 	if (last_seen != ra) {
 		last_seen = ra;
-		_dispatch_log("BUG in libdispatch: %s - %lu - 0x%lx", _dispatch_build, line, val);
+		_dispatch_log("BUG in libdispatch: %s - %lu - 0x%lx", _dispatch_build, (unsigned long)line, val);
 	}
 }
 

Modified: trunk/src/queue_internal.h
===================================================================
--- trunk/src/queue_internal.h	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/queue_internal.h	2009-09-14 18:46:18 UTC (rev 27)
@@ -62,6 +62,7 @@
 
 #define DISPATCH_QUEUE_MIN_LABEL_SIZE	64
 
+#ifndef DISPATCH_NO_LEGACY
 #define DISPATCH_QUEUE_HEADER \
 	uint32_t dq_running; \
 	uint32_t dq_width; \
@@ -70,6 +71,15 @@
 	unsigned long dq_serialnum; \
 	void *dq_finalizer_ctxt; \
 	dispatch_queue_finalizer_function_t dq_finalizer_func
+#else
+#define DISPATCH_QUEUE_HEADER \
+	uint32_t dq_running; \
+	uint32_t dq_width; \
+	struct dispatch_object_s *dq_items_tail; \
+	struct dispatch_object_s *volatile dq_items_head; \
+	unsigned long dq_serialnum; \
+	void *dq_finalizer_ctxt;
+#endif
 
 struct dispatch_queue_s {
 	DISPATCH_STRUCT_HEADER(dispatch_queue_s, dispatch_queue_vtable_s);

Modified: trunk/src/semaphore.c
===================================================================
--- trunk/src/semaphore.c	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/semaphore.c	2009-09-14 18:46:18 UTC (rev 27)
@@ -21,11 +21,19 @@
 #include "internal.h"
 
 // semaphores are too fundamental to use the dispatch_assume*() macros
+#ifdef HAVE_MACH
 #define DISPATCH_SEMAPHORE_VERIFY_KR(x)	do {	\
 		if (x) {	\
 			DISPATCH_CRASH("flawed group/semaphore logic");	\
 		}	\
 	} while (0)
+#else
+#define	DISPATCH_SEMAPHORE_VERIFY_RET(x) do {				\
+		if ((x) == -1) {					\
+			DISPATCH_CRASH("flawed group/semaphore logic");	\
+		}							\
+	} while (0)
+#endif
 
 struct dispatch_semaphore_vtable_s {
 	DISPATCH_VTABLE_HEADER(dispatch_semaphore_s);
@@ -100,6 +108,7 @@
 	return dsema;
 }
 
+#ifdef HAVE_MACH
 static void
 _dispatch_semaphore_create_port(semaphore_t *s4)
 {
@@ -129,13 +138,32 @@
 
 	_dispatch_safe_fork = false;
 }
+#else /* !HAVE_MACH */
+static void
+_dispatch_posix_semaphore_create(sem_t *s4)
+{
+	int ret;
 
+	if (*s4) {
+		return;
+	}
+
+	ret = sem_init(s4, 0, 0);
+	dispatch_assume_zero(ret);
+}
+#endif /* HAVE_MACH */
+
 DISPATCH_NOINLINE
 static long
 _dispatch_semaphore_wait_slow(dispatch_semaphore_t dsema, dispatch_time_t timeout)
 {
+#ifdef HAVE_MACH
 	mach_timespec_t _timeout;
 	kern_return_t kr;
+#else
+	struct timespec _timeout;
+	int ret;
+#endif
 	uint64_t nsec;
 	long orig;
 	
@@ -149,7 +177,11 @@
 		}
 	}
 
+#ifdef HAVE_MACH
 	_dispatch_semaphore_create_port(&dsema->dsema_port);
+#else
+	_dispatch_posix_semaphore_create(&dsema->dsema_sem);
+#endif
 
 	// From xnu/osfmk/kern/sync_sema.c:
 	// wait_semaphore->count = -1;  /* we don't keep an actual count */
@@ -161,6 +193,7 @@
 
 	switch (timeout) {
 	default:
+#ifdef HAVE_MACH
 		do {
 			// timeout() already calculates relative time left
 			nsec = _dispatch_timeout(timeout);
@@ -173,20 +206,48 @@
 			DISPATCH_SEMAPHORE_VERIFY_KR(kr);
 			break;
 		}
+#else /* !HAVE_MACH */
+		do {
+			nsec = _dispatch_timeout(timeout);
+			_timeout.tv_sec = (typeof(_timeout.tv_sec))
+			    (nsec / NSEC_PER_SEC);
+			_timeout.tv_nsec = (typeof(_timeout.tv_nsec))
+			    (nsec % NSEC_PER_SEC);
+			ret = slowpath(sem_timedwait(&dsema->dsema_sem,
+			    &_timeout));
+		} while (ret == -1 && errno == EINTR);
+
+		if (ret == -1 && errno != ETIMEDOUT) {
+			DISPATCH_SEMAPHORE_VERIFY_RET(ret);
+			break;
+		}
+#endif /* HAVE_MACH */
 		// 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
 				return KERN_OPERATION_TIMED_OUT;
+#else
+				errno = ETIMEDOUT;
+				return -1;
+#endif
 			}
 		}
 		// Another thread called semaphore_signal().
 		// Fall through and drain the wakeup.
 	case DISPATCH_TIME_FOREVER:
+#ifdef HAVE_MACH
 		do {
 			kr = semaphore_wait(dsema->dsema_port);
 		} while (kr == KERN_ABORTED);
 		DISPATCH_SEMAPHORE_VERIFY_KR(kr);
+#else
+		do {
+			ret = sem_wait(&dsema->dsema_sem);
+		} while (ret != 0);
+		DISPATCH_SEMAPHORE_VERIFY_RET(ret);
+#endif
 		break;
 	}
 
@@ -198,7 +259,7 @@
 dispatch_group_enter(dispatch_group_t dg)
 {
 	dispatch_semaphore_t dsema = (dispatch_semaphore_t)dg;
-#if defined(__OPTIMIZE__) && defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__llvm__)
+#if defined(USE_APPLE_SEMAPHORE_OPTIMIZATIONS) && defined(__OPTIMIZE__) && defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__llvm__)
 	// This assumes:
 	// 1) Way too much about the optimizer of GCC.
 	// 2) There will never be more than LONG_MAX threads.
@@ -226,7 +287,7 @@
 long
 dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout)
 {
-#if defined(__OPTIMIZE__) && defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__llvm__)
+#if defined(USE_APPLE_SEMAPHORE_OPTIMIZATIONS) && defined(__OPTIMIZE__) && defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__llvm__)
 	// This assumes:
 	// 1) Way too much about the optimizer of GCC.
 	// 2) There will never be more than LONG_MAX threads.
@@ -257,9 +318,13 @@
 static long
 _dispatch_semaphore_signal_slow(dispatch_semaphore_t dsema)
 {
+#ifndef HAVE_MACH
+	int ret;
+#else
 	kern_return_t kr;
 	
 	_dispatch_semaphore_create_port(&dsema->dsema_port);
+#endif
 
 	// Before dsema_sent_ksignals is incremented we can rely on the reference
 	// held by the waiter. However, once this value is incremented the waiter
@@ -270,8 +335,12 @@
 	
 	dispatch_atomic_inc(&dsema->dsema_sent_ksignals);
 	
+#ifdef HAVE_MACH
 	kr = semaphore_signal(dsema->dsema_port);
 	DISPATCH_SEMAPHORE_VERIFY_KR(kr);
+#else
+	ret = sem_post(&dsema->dsema_sem);
+#endif
 
 	_dispatch_release(dsema);
 	
@@ -294,7 +363,7 @@
 long
 dispatch_semaphore_signal(dispatch_semaphore_t dsema)
 {
-#if defined(__OPTIMIZE__) && defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__llvm__)
+#if defined(USE_APPLE_SEMAPHORE_OPTIMIZATIONS) && defined(__OPTIMIZE__) && defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__llvm__)
 	// overflow detection
 	// this assumes way too much about the optimizer of GCC
 	asm(
@@ -329,16 +398,27 @@
 	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
 	long kr;
+#else
+	int ret;
+#endif
 
 	// wake any "group" waiter or notify blocks
 	
 	if (rval) {
+#ifdef HAVE_MACH
 		_dispatch_semaphore_create_port(&dsema->dsema_waiter_port);
 		do {
 			kr = semaphore_signal(dsema->dsema_waiter_port);
 			DISPATCH_SEMAPHORE_VERIFY_KR(kr);
 		} while (--rval);
+#else
+		do {
+			ret = sem_post(&dsema->dsema_sem);
+			DISPATCH_SEMAPHORE_VERIFY_RET(ret);
+		} while (--rval);
+#endif
 	}
 	while (head) {
 		dispatch_async_f(head->dsn_queue, head->dsn_ctxt, head->dsn_func);
@@ -359,8 +439,13 @@
 static long
 _dispatch_group_wait_slow(dispatch_semaphore_t dsema, dispatch_time_t timeout)
 {
+#ifdef HAVE_MACH
 	mach_timespec_t _timeout;
 	kern_return_t kr;
+#else
+	struct timespec _timeout;
+	int ret;
+#endif
 	uint64_t nsec;
 	long orig;
 	
@@ -378,7 +463,9 @@
 		return _dispatch_group_wake(dsema);
 	}
 
+#ifdef HAVE_MACH
 	_dispatch_semaphore_create_port(&dsema->dsema_waiter_port);
+#endif
 	
 	// From xnu/osfmk/kern/sync_sema.c:
 	// wait_semaphore->count = -1;  /* we don't keep an actual count */
@@ -390,6 +477,7 @@
 	
 	switch (timeout) {
 	default:
+#ifdef HAVE_MACH
 		do {
 			nsec = _dispatch_timeout(timeout);
 			_timeout.tv_sec = (typeof(_timeout.tv_sec))(nsec / NSEC_PER_SEC);
@@ -400,20 +488,47 @@
 			DISPATCH_SEMAPHORE_VERIFY_KR(kr);
 			break;
 		}
+#else
+		do {
+			nsec = _dispatch_timeout(timeout);
+			_timeout.tv_sec = (typeof(_timeout.tv_sec))
+			    (nsec / NSEC_PER_SEC);
+			_timeout.tv_nsec = (typeof(_timeout.tv_nsec))
+			    (nsec % NSEC_PER_SEC);
+			ret = slowpath(sem_timedwait(&dsema->dsema_sem,
+			    &_timeout));
+		} while (ret == -1 && errno == EINTR);
+		if (ret == 0 || errno != ETIMEDOUT) {
+			DISPATCH_SEMAPHORE_VERIFY_RET(ret);
+			break;
+		}
+#endif
 		// Fall through and try to undo the earlier change to dsema->dsema_group_waiters
 	case DISPATCH_TIME_NOW:
 		while ((orig = dsema->dsema_group_waiters)) {
 			if (dispatch_atomic_cmpxchg(&dsema->dsema_group_waiters, orig, orig - 1)) {
+#ifdef HAVE_MACH
 				return KERN_OPERATION_TIMED_OUT;
+#else
+				errno = ETIMEDOUT;
+				return -1;
+#endif
 			}
 		}
 		// Another thread called semaphore_signal().
 		// Fall through and drain the wakeup.
 	case DISPATCH_TIME_FOREVER:
+#ifdef HAVE_MACH
 		do {
 			kr = semaphore_wait(dsema->dsema_waiter_port);
 		} while (kr == KERN_ABORTED);
 		DISPATCH_SEMAPHORE_VERIFY_KR(kr);
+#else
+		do {
+			ret = sem_wait(&dsema->dsema_sem);
+		} while (ret == -1 && errno == EINTR);
+		DISPATCH_SEMAPHORE_VERIFY_RET(ret);
+#endif
 		break;
 	}
 
@@ -429,7 +544,12 @@
 		return 0;
 	}
 	if (timeout == 0) {
+#ifdef HAVE_MACH
 		return KERN_OPERATION_TIMED_OUT;
+#else
+		errno = ETIMEDOUT;
+		return (-1);
+#endif
 	}
 	return _dispatch_group_wait_slow(dsema, timeout);
 }
@@ -474,12 +594,17 @@
 void
 _dispatch_semaphore_dispose(dispatch_semaphore_t dsema)
 {
+#ifdef HAVE_MACH
 	kern_return_t kr;
+#else
+	int ret;
+#endif
 	
 	if (dsema->dsema_value < dsema->dsema_orig) {
 		DISPATCH_CLIENT_CRASH("Semaphore/group object deallocated while in use");
 	}
 	
+#ifdef HAVE_MACH
 	if (dsema->dsema_port) {
 		kr = semaphore_destroy(mach_task_self(), dsema->dsema_port);
 		DISPATCH_SEMAPHORE_VERIFY_KR(kr);
@@ -488,6 +613,10 @@
 		kr = semaphore_destroy(mach_task_self(), dsema->dsema_waiter_port);
 		DISPATCH_SEMAPHORE_VERIFY_KR(kr);
 	}
+#else
+	ret = sem_destroy(&dsema->dsema_sem);
+	DISPATCH_SEMAPHORE_VERIFY_RET(ret);
+#endif
 	
 	_dispatch_dispose(dsema);
 }
@@ -498,8 +627,12 @@
 	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);
-	offset += snprintf(&buf[offset], bufsiz - offset, "port = 0x%u, value = %ld, orig = %ld }",
-					   dsema->dsema_port, dsema->dsema_value, dsema->dsema_orig);
+#ifdef HAVE_MACH
+	offset += snprintf(&buf[offset], bufsiz - offset, "port = 0x%u, ",
+	    dsema->dsema_port);
+#endif
+	offset += snprintf(&buf[offset], bufsiz - offset,
+	    "value = %ld, orig = %ld }", dsema->dsema_value, dsema->dsema_orig);
 	return offset;
 }
 

Modified: trunk/src/semaphore_internal.h
===================================================================
--- trunk/src/semaphore_internal.h	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/semaphore_internal.h	2009-09-14 18:46:18 UTC (rev 27)
@@ -39,8 +39,14 @@
 	long dsema_value;
 	long dsema_orig;
 	size_t dsema_sent_ksignals;
+#ifdef HAVE_MACH
 	semaphore_t dsema_port;
 	semaphore_t dsema_waiter_port;
+#elif defined(HAVE_SEM_INIT)
+	sem_t dsema_sem;
+#else
+#error "No supported semaphore type"
+#endif
 	size_t dsema_group_waiters;
 	struct dispatch_sema_notify_s *dsema_notify_head;
 	struct dispatch_sema_notify_s *dsema_notify_tail;

Modified: trunk/src/shims.c
===================================================================
--- trunk/src/shims.c	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/shims.c	2009-09-14 18:46:18 UTC (rev 27)
@@ -20,6 +20,7 @@
 
 #include "internal.h"
 
+#ifdef HAVE_MACH
 void *
 dispatch_mach_msg_get_context(mach_msg_header_t *msg)
 {
@@ -63,3 +64,4 @@
 
 	return TRUE;
 }
+#endif /* HAVE_MACH */

Modified: trunk/src/source.c
===================================================================
--- trunk/src/source.c	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/source.c	2009-09-14 18:46:18 UTC (rev 27)
@@ -19,8 +19,10 @@
  */
 
 #include "internal.h"
+#ifdef HAVE_MACH
 #include "protocol.h"
 #include "protocolServer.h"
+#endif
 #include <sys/mount.h>
 
 #define DISPATCH_EVFILT_TIMER	(-EVFILT_SYSCOUNT - 1)
@@ -92,15 +94,19 @@
 static void _dispatch_kevent_merge(dispatch_source_t ds);
 static void _dispatch_kevent_release(dispatch_source_t ds);
 static void _dispatch_kevent_resume(dispatch_kevent_t dk, uint32_t new_flags, uint32_t del_flags);
+#ifdef HAVE_MACH
 static void _dispatch_kevent_machport_resume(dispatch_kevent_t dk, uint32_t new_flags, uint32_t del_flags);
 static void _dispatch_kevent_machport_enable(dispatch_kevent_t dk);
 static void _dispatch_kevent_machport_disable(dispatch_kevent_t dk);
 
 static void _dispatch_drain_mach_messages(struct kevent *ke);
+#endif
 static void _dispatch_timer_list_update(dispatch_source_t ds);
 
+#ifdef HAVE_MACH
 static void
 _dispatch_mach_notify_source_init(void *context __attribute__((unused)));
+#endif
 
 static const char *
 _evfiltstr(short filt)
@@ -114,10 +120,14 @@
 	_evfilt2(EVFILT_PROC);
 	_evfilt2(EVFILT_SIGNAL);
 	_evfilt2(EVFILT_TIMER);
+#ifdef HAVE_MACH
 	_evfilt2(EVFILT_MACHPORT);
+#endif
 	_evfilt2(EVFILT_FS);
 	_evfilt2(EVFILT_USER);
+#if HAVE_DECL_EVFILT_SESSION
 	_evfilt2(EVFILT_SESSION);
+#endif
 
 	_evfilt2(DISPATCH_EVFILT_TIMER);
 	_evfilt2(DISPATCH_EVFILT_CUSTOM_ADD);
@@ -135,7 +145,11 @@
 static dispatch_kevent_t
 _dispatch_kevent_find(uintptr_t ident, short filter)
 {
+#ifdef HAVE_MACH
 	uintptr_t hash = DSL_HASH(filter == EVFILT_MACHPORT ? MACH_PORT_INDEX(ident) : ident);
+#else
+	uintptr_t hash = DSL_HASH(ident);
+#endif
 	dispatch_kevent_t dki;
 
 	TAILQ_FOREACH(dki, &_dispatch_sources[hash], dk_list) {
@@ -150,7 +164,11 @@
 _dispatch_kevent_insert(dispatch_kevent_t dk)
 {
 	uintptr_t ident = dk->dk_kevent.ident;
+#ifdef HAVE_MACH
 	uintptr_t hash = DSL_HASH(dk->dk_kevent.filter == EVFILT_MACHPORT ? MACH_PORT_INDEX(ident) : ident);
+#else
+	uintptr_t hash = DSL_HASH(ident);
+#endif
 
 	TAILQ_INSERT_TAIL(&_dispatch_sources[hash], dk, dk_list);
 }
@@ -306,9 +324,11 @@
 	case DISPATCH_EVFILT_CUSTOM_OR:
 		// these types not registered with kevent
 		return;
+#ifdef HAVE_MACH
 	case EVFILT_MACHPORT:
 		_dispatch_kevent_machport_resume(dk, new_flags, del_flags);
 		break;
+#endif
 	case EVFILT_PROC:
 		if (dk->dk_kevent.flags & EV_ONESHOT) {
 			return;
@@ -413,6 +433,7 @@
 	_dispatch_queue_dispose((dispatch_queue_t)ds);
 }
 
+#ifndef DISPATCH_NO_LEGACY
 static void
 _dispatch_kevent_debugger2(void *context, dispatch_source_t unused __attribute__((unused)))
 {
@@ -457,8 +478,8 @@
 		}
 		TAILQ_FOREACH(dk, &_dispatch_sources[i], dk_list) {
 			fprintf(debug_stream, "\t<br><li>DK %p ident %lu filter %s flags 0x%hx fflags 0x%x data 0x%lx udata %p\n",
-					dk, dk->dk_kevent.ident, _evfiltstr(dk->dk_kevent.filter), dk->dk_kevent.flags,
-					dk->dk_kevent.fflags, dk->dk_kevent.data, dk->dk_kevent.udata);
+					dk, (unsigned long)dk->dk_kevent.ident, _evfiltstr(dk->dk_kevent.filter), dk->dk_kevent.flags,
+					dk->dk_kevent.fflags, (unsigned long)dk->dk_kevent.data, dk->dk_kevent.udata);
 			fprintf(debug_stream, "\t\t<ul>\n");
 			TAILQ_FOREACH(ds, &dk->dk_sources, ds_list) {
 				fprintf(debug_stream, "\t\t\t<li>DS %p refcnt 0x%x suspend 0x%x data 0x%lx mask 0x%lx flags 0x%x</li>\n",
@@ -546,21 +567,28 @@
 out_bad:
 	close(fd);
 }
+#endif /* DISPATCH_NO_LEGACY */
 
 void
 _dispatch_source_drain_kevent(struct kevent *ke)
 {
+#ifndef DISPATCH_NO_LEGACY
 	static dispatch_once_t pred;
+#endif
 	dispatch_kevent_t dk = ke->udata;
 	dispatch_source_t dsi;
 
+#ifndef DISPATCH_NO_LEGACY
 	dispatch_once_f(&pred, NULL, _dispatch_kevent_debugger);
+#endif
 
 	dispatch_debug_kevents(ke, 1, __func__);
 
+#ifdef HAVE_MACH
 	if (ke->filter == EVFILT_MACHPORT) {
 		return _dispatch_drain_mach_messages(ke);
 	}
+#endif
 	dispatch_assert(dk);
 
 	if (ke->flags & EV_ONESHOT) {
@@ -583,9 +611,11 @@
 	case DISPATCH_EVFILT_CUSTOM_OR:
 		// these sources live on statically allocated lists
 		return;
+#ifdef HAVE_MACH
 	case EVFILT_MACHPORT:
 		_dispatch_kevent_machport_resume(dk, 0, dk->dk_kevent.fflags);
 		break;
+#endif
 	case EVFILT_PROC:
 		if (dk->dk_kevent.flags & EV_ONESHOT) {
 			break;	// implicitly deleted
@@ -599,11 +629,15 @@
 		break;
 	}
 
+#ifdef HAVE_MACH
 	if (dk->dk_kevent.filter == EVFILT_MACHPORT) {
 		key = MACH_PORT_INDEX(dk->dk_kevent.ident);
 	} else {
+#endif
 		key = dk->dk_kevent.ident;
+#ifdef HAVE_MACH
 	}
+#endif
 
 	TAILQ_REMOVE(&_dispatch_sources[DSL_HASH(key)], dk, dk_list);
 	free(dk);
@@ -923,7 +957,14 @@
 		.filter = EVFILT_PROC,
 		.flags = EV_CLEAR,
 	},
-	.mask = NOTE_EXIT|NOTE_FORK|NOTE_EXEC|NOTE_SIGNAL|NOTE_REAP,
+	.mask = NOTE_EXIT|NOTE_FORK|NOTE_EXEC
+#if HAVE_DECL_NOTE_SIGNAL
+	    |NOTE_SIGNAL
+#endif
+#if HAVE_DECL_NOTE_REAP
+	    |NOTE_REAP
+#endif
+	    ,
 };
 
 const struct dispatch_source_type_s _dispatch_source_type_signal = {
@@ -937,7 +978,12 @@
 		.filter = EVFILT_VNODE,
 		.flags = EV_CLEAR,
 	},
-	.mask = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|NOTE_RENAME|NOTE_REVOKE|NOTE_NONE,
+	.mask = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|
+	    NOTE_RENAME|NOTE_REVOKE
+#if HAVE_DECL_NOTE_NONE
+	    |NOTE_NONE
+#endif
+	    ,
 };
 
 const struct dispatch_source_type_s _dispatch_source_type_vfs = {
@@ -945,9 +991,18 @@
 		.filter = EVFILT_FS,
 		.flags = EV_CLEAR,
 	},
-	.mask = VQ_NOTRESP|VQ_NEEDAUTH|VQ_LOWDISK|VQ_MOUNT|VQ_UNMOUNT|VQ_DEAD|VQ_ASSIST|VQ_NOTRESPLOCK|VQ_UPDATE|VQ_VERYLOWDISK,
+	.mask = VQ_NOTRESP|VQ_NEEDAUTH|VQ_LOWDISK|VQ_MOUNT|VQ_UNMOUNT|VQ_DEAD|
+	    VQ_ASSIST|VQ_NOTRESPLOCK
+#if HAVE_DECL_VQ_UPDATE
+	    |VQ_UPDATE
+#endif
+#if HAVE_DECL_VQ_VERYLOWDISK
+	    |VQ_VERYLOWDISK
+#endif
+	    ,
 };
 
+#ifdef HAVE_MACH
 const struct dispatch_source_type_s _dispatch_source_type_mach_send = {
 	.ke = {
 		.filter = EVFILT_MACHPORT,
@@ -964,6 +1019,7 @@
 		.fflags = DISPATCH_MACHPORT_RECV,
 	},
 };
+#endif
 
 const struct dispatch_source_type_s _dispatch_source_type_data_add = {
 	.ke = {
@@ -1044,9 +1100,11 @@
 	ds->ds_dkev = dk;
 	ds->ds_pending_data_mask = dk->dk_kevent.fflags;
 	if ((EV_DISPATCH|EV_ONESHOT) & proto_kev->flags) {
+#ifdef HAVE_MACH
 		if (proto_kev->filter != EVFILT_MACHPORT) {
 			ds->ds_is_level = true;
 		}
+#endif
 		ds->ds_needs_rearm = true;
 	} else if (!(EV_CLEAR & proto_kev->flags)) {
 		// we cheat and use EV_CLEAR to mean a "flag thingy"
@@ -1064,10 +1122,13 @@
 #endif
 
 	// Some sources require special processing
+#ifdef HAVE_MACH
 	if (type == DISPATCH_SOURCE_TYPE_MACH_SEND) {
 		static dispatch_once_t pred;
 		dispatch_once_f(&pred, NULL, _dispatch_mach_notify_source_init);
-	} else if (type == DISPATCH_SOURCE_TYPE_TIMER) {
+	} else
+#endif
+	if (type == DISPATCH_SOURCE_TYPE_TIMER) {
 		ds->ds_timer.flags = mask;
 	}
 
@@ -1320,7 +1381,7 @@
 	uint64_t now, missed;
 
 	if (timer == DISPATCH_TIMER_INDEX_MACH) {
-		now = mach_absolute_time();
+		now = _dispatch_absolute_time();
 	} else {
 		now = _dispatch_get_nanoseconds();
 	}
@@ -1365,7 +1426,7 @@
 	}
 }
 
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__) || !defined(HAVE_MACH_ABSOLUTE_TIME)
 // these architectures always return mach_absolute_time() in nanoseconds
 #define _dispatch_convert_mach2nano(x) (x)
 #define _dispatch_convert_nano2mach(x) (x)
@@ -1452,7 +1513,7 @@
 		if (ds->ds_timer.flags & DISPATCH_TIMER_WALL_CLOCK) {
 			now = _dispatch_get_nanoseconds();
 		} else {
-			now = mach_absolute_time();
+			now = _dispatch_absolute_time();
 		}
 		if (ds->ds_timer.target <= now) {
 			howsoon->tv_sec = 0;
@@ -1521,7 +1582,7 @@
 	dispatch_suspend(ds);
 	
 	if (start == DISPATCH_TIME_NOW) {
-		start = mach_absolute_time();
+		start = _dispatch_absolute_time();
 	} else if (start == DISPATCH_TIME_FOREVER) {
 		start = INT64_MAX;
 	}
@@ -1542,7 +1603,7 @@
 		params->values.leeway = leeway;
 		params->values.flags |= DISPATCH_TIMER_WALL_CLOCK;
 	} else {
-		// mach clock
+		// absolute clock
 		params->ident = DISPATCH_TIMER_INDEX_MACH;
 		params->values.start = start;
 		params->values.target = start;
@@ -1591,6 +1652,7 @@
 }
 #endif /* DISPATCH_NO_LEGACY */
 
+#ifdef HAVE_MACH
 static dispatch_source_t _dispatch_mach_notify_source;
 static mach_port_t _dispatch_port_set;
 static mach_port_t _dispatch_event_port;
@@ -2010,3 +2072,4 @@
 
 	return kr;
 }
+#endif /* HAVE_MACH */

Modified: trunk/src/source.h
===================================================================
--- trunk/src/source.h	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/source.h	2009-09-14 18:46:18 UTC (rev 27)
@@ -26,8 +26,10 @@
 #include <dispatch/base.h> // for HeaderDoc
 #endif
 
+#ifdef HAVE_MACH
 #include <mach/port.h>
 #include <mach/message.h>
+#endif
 #include <sys/signal.h>
 
 /*!

Modified: trunk/src/source_private.h
===================================================================
--- trunk/src/source_private.h	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/source_private.h	2009-09-14 18:46:18 UTC (rev 27)
@@ -111,6 +111,7 @@
 
 __BEGIN_DECLS
 
+#ifdef HAVE_MACH
 /*!
  * @typedef dispatch_mig_callback_t
  *
@@ -123,6 +124,7 @@
 DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
 mach_msg_return_t
 dispatch_mig_server(dispatch_source_t ds, size_t maxmsgsz, dispatch_mig_callback_t callback);
+#endif
 
 __END_DECLS
 

Modified: trunk/src/time.c
===================================================================
--- trunk/src/time.c	2009-09-14 18:31:33 UTC (rev 26)
+++ trunk/src/time.c	2009-09-14 18:46:18 UTC (rev 27)
@@ -128,7 +128,7 @@
 	// mach clock
 	delta = _dispatch_time_nano2mach(delta);
    	if (inval == 0) {
-		inval = mach_absolute_time();
+		inval = _dispatch_absolute_time();
 	}
 	if (delta >= 0) {
 		if ((int64_t)(inval += delta) <= 0) {
@@ -178,6 +178,6 @@
 		now = _dispatch_get_nanoseconds();
 		return now >= when ? 0 : when - now;
 	}
-	now = mach_absolute_time();
+	now = _dispatch_absolute_time();
 	return now >= when ? 0 : _dispatch_time_mach2nano(when - now);
 }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/libdispatch-changes/attachments/20090914/1f94a77f/attachment-0001.html>


More information about the libdispatch-changes mailing list