Merge branch 'master' into das-darwin-008-merge-master

Signed-off-by: Daniel A. Steffen <dsteffen@apple.com>
diff --git a/configure.ac b/configure.ac
index 7db3d60..3221112 100644
--- a/configure.ac
+++ b/configure.ac
@@ -320,7 +320,11 @@
 AC_CHECK_HEADERS([pthread_machdep.h pthread/qos.h])
 
 # pthread_workqueues.
-# Look for own version first, than see if there is a system version.
+# We can either use libdispatch's internal_workqueue or pthread_workqueue.
+# If not specifically configured, default to internal_workqueues on
+# Linux and pthread_workqueue on all other platforms.
+# On any platform, if pthread_workqueue is not available, fall back
+# to using internal_workqueue.
 AC_ARG_ENABLE([internal-libpwq],
   [AS_HELP_STRING([--enable-internal-libpwq],
     [Use libdispatch's own implementation of pthread workqueues.])],,
@@ -333,15 +337,15 @@
    esac]
 )
 AS_IF([test "x$enable_internal_libpwq" = "xyes"],
-  [AC_DEFINE(DISPATCH_USE_INTERNAL_WORKQUEUE, 1, [Use libdispatch's own implementation of pthread_workqueue API])
-   AC_DEFINE(HAVE_PTHREAD_WORKQUEUES, 1, [Define if pthread work queues are present])
-   dispatch_use_internal_workqueue=true
-   have_pthread_workqueues=true],
-  [dispatch_use_internal_workqueue=false
-   AC_CHECK_HEADERS([pthread/workqueue_private.h pthread_workqueue.h],
+  [AC_DEFINE(DISPATCH_USE_INTERNAL_WORKQUEUE, 1, [Use libdispatch's own implementation of pthread workqueues])
+   have_pthread_workqueues=false,
+   dispatch_use_internal_workqueue=true],
+  [AC_CHECK_HEADERS([pthread/workqueue_private.h pthread_workqueue.h],
      [AC_DEFINE(HAVE_PTHREAD_WORKQUEUES, 1, [Define if pthread work queues are present])
-      have_pthread_workqueues=true],
-     [have_pthread_workqueues=false]
+      have_pthread_workqueues=true,
+	  dispatch_use_internal_workqueue=false],
+     [have_pthread_workqueues=false,
+	  dispatch_use_internal_workqueue=true]
   )]
 )
 AM_CONDITIONAL(DISPATCH_USE_INTERNAL_WORKQUEUE, $dispatch_use_internal_workqueue)
diff --git a/src/Makefile.am b/src/Makefile.am
index ac2f74c..8beaf1e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -84,15 +84,10 @@
 AM_CXXFLAGS=$(PTHREAD_WORKQUEUE_CFLAGS) $(DISPATCH_CFLAGS) $(CXXBLOCKS_FLAGS)
 AM_OBJCXXFLAGS=$(DISPATCH_CFLAGS) $(CXXBLOCKS_FLAGS)
 
-if DISPATCH_USE_INTERNAL_WORKQUEUE
-  PTHREAD_WORKQUEUE_LIBS=
-  PTHREAD_WORKQUEUE_CFLAGS=
-else
 if HAVE_PTHREAD_WORKQUEUES
   PTHREAD_WORKQUEUE_LIBS=-lpthread_workqueue
   PTHREAD_WORKQUEUE_CFLAGS=
 endif
-endif
 
 if BUILD_OWN_BLOCKS_RUNTIME
 libdispatch_la_SOURCES+= BlocksRuntime/data.c BlocksRuntime/runtime.c
diff --git a/src/internal.h b/src/internal.h
index 489da74..688d5dd 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -630,11 +630,11 @@
 
 // Older Mac OS X and iOS Simulator fallbacks
 
-#if HAVE_PTHREAD_WORKQUEUES
+#if HAVE_PTHREAD_WORKQUEUES || DISPATCH_USE_INTERNAL_WORKQUEUE
 #ifndef WORKQ_ADDTHREADS_OPTION_OVERCOMMIT
 #define WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 0x00000001
 #endif
-#endif // HAVE_PTHREAD_WORKQUEUES
+#endif // HAVE_PTHREAD_WORKQUEUES || DISPATCH_USE_INTERNAL_WORKQUEUE
 #if HAVE__PTHREAD_WORKQUEUE_INIT && PTHREAD_WORKQUEUE_SPI_VERSION >= 20140213 \
 		&& !defined(HAVE_PTHREAD_WORKQUEUE_QOS)
 #define HAVE_PTHREAD_WORKQUEUE_QOS 1
diff --git a/src/queue.c b/src/queue.c
index 394ed7c..6d74b79 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -23,8 +23,10 @@
 #include "protocol.h" // _dispatch_send_wakeup_runloop_thread
 #endif
 
-#if (!HAVE_PTHREAD_WORKQUEUES || DISPATCH_DEBUG || DISPATCH_USE_INTERNAL_WORKQUEUE) && \
-		!defined(DISPATCH_ENABLE_THREAD_POOL)
+#if HAVE_PTHREAD_WORKQUEUES || DISPATCH_USE_INTERNAL_WORKQUEUE
+#define DISPATCH_USE_WORKQUEUES 1
+#endif
+#if (!HAVE_PTHREAD_WORKQUEUES || DISPATCH_DEBUG) && !defined(DISPATCH_ENABLE_THREAD_POOL)
 #define DISPATCH_ENABLE_THREAD_POOL 1
 #endif
 #if DISPATCH_ENABLE_PTHREAD_ROOT_QUEUES || DISPATCH_ENABLE_THREAD_POOL
@@ -32,11 +34,10 @@
 #endif
 #if HAVE_PTHREAD_WORKQUEUES && (!HAVE_PTHREAD_WORKQUEUE_QOS || DISPATCH_DEBUG) && \
 		!HAVE_PTHREAD_WORKQUEUE_SETDISPATCH_NP && \
-		!DISPATCH_USE_INTERNAL_WORKQUEUE && \
 		!defined(DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK)
 #define DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK 1
 #endif
-#if HAVE_PTHREAD_WORKQUEUES && DISPATCH_USE_PTHREAD_POOL && \
+#if DISPATCH_USE_WORKQUEUES && DISPATCH_USE_PTHREAD_POOL && \
 		!DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK
 #define pthread_workqueue_t void*
 #endif
@@ -151,13 +152,13 @@
 	union {
 		struct {
 			int volatile dgq_pending;
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 			qos_class_t dgq_qos;
 			int dgq_wq_priority, dgq_wq_options;
 #if DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK || DISPATCH_USE_PTHREAD_POOL
 			pthread_workqueue_t dgq_kworkqueue;
 #endif
-#endif // HAVE_PTHREAD_WORKQUEUES
+#endif // DISPATCH_USE_WORKQUEUES
 #if DISPATCH_USE_PTHREAD_POOL
 			void *dgq_ctxt;
 			int32_t volatile dgq_thread_pool_size;
@@ -179,7 +180,7 @@
 DISPATCH_CACHELINE_ALIGN
 static struct dispatch_root_queue_context_s _dispatch_root_queue_contexts[] = {
 	[DISPATCH_ROOT_QUEUE_IDX_MAINTENANCE_QOS] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_MAINTENANCE,
 		.dgq_wq_priority = WORKQ_BG_PRIOQUEUE,
 		.dgq_wq_options = 0,
@@ -190,7 +191,7 @@
 #endif
 	}}},
 	[DISPATCH_ROOT_QUEUE_IDX_MAINTENANCE_QOS_OVERCOMMIT] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_MAINTENANCE,
 		.dgq_wq_priority = WORKQ_BG_PRIOQUEUE,
 		.dgq_wq_options = WORKQ_ADDTHREADS_OPTION_OVERCOMMIT,
@@ -201,7 +202,7 @@
 #endif
 	}}},
 	[DISPATCH_ROOT_QUEUE_IDX_BACKGROUND_QOS] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_BACKGROUND,
 		.dgq_wq_priority = WORKQ_BG_PRIOQUEUE_CONDITIONAL,
 		.dgq_wq_options = 0,
@@ -212,7 +213,7 @@
 #endif
 	}}},
 	[DISPATCH_ROOT_QUEUE_IDX_BACKGROUND_QOS_OVERCOMMIT] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_BACKGROUND,
 		.dgq_wq_priority = WORKQ_BG_PRIOQUEUE_CONDITIONAL,
 		.dgq_wq_options = WORKQ_ADDTHREADS_OPTION_OVERCOMMIT,
@@ -223,7 +224,7 @@
 #endif
 	}}},
 	[DISPATCH_ROOT_QUEUE_IDX_UTILITY_QOS] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_UTILITY,
 		.dgq_wq_priority = WORKQ_LOW_PRIOQUEUE,
 		.dgq_wq_options = 0,
@@ -234,7 +235,7 @@
 #endif
 	}}},
 	[DISPATCH_ROOT_QUEUE_IDX_UTILITY_QOS_OVERCOMMIT] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_UTILITY,
 		.dgq_wq_priority = WORKQ_LOW_PRIOQUEUE,
 		.dgq_wq_options = WORKQ_ADDTHREADS_OPTION_OVERCOMMIT,
@@ -245,7 +246,7 @@
 #endif
 	}}},
 	[DISPATCH_ROOT_QUEUE_IDX_DEFAULT_QOS] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_DEFAULT,
 		.dgq_wq_priority = WORKQ_DEFAULT_PRIOQUEUE,
 		.dgq_wq_options = 0,
@@ -256,7 +257,7 @@
 #endif
 	}}},
 	[DISPATCH_ROOT_QUEUE_IDX_DEFAULT_QOS_OVERCOMMIT] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_DEFAULT,
 		.dgq_wq_priority = WORKQ_DEFAULT_PRIOQUEUE,
 		.dgq_wq_options = WORKQ_ADDTHREADS_OPTION_OVERCOMMIT,
@@ -267,7 +268,7 @@
 #endif
 	}}},
 	[DISPATCH_ROOT_QUEUE_IDX_USER_INITIATED_QOS] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_USER_INITIATED,
 		.dgq_wq_priority = WORKQ_HIGH_PRIOQUEUE,
 		.dgq_wq_options = 0,
@@ -278,7 +279,7 @@
 #endif
 	}}},
 	[DISPATCH_ROOT_QUEUE_IDX_USER_INITIATED_QOS_OVERCOMMIT] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_USER_INITIATED,
 		.dgq_wq_priority = WORKQ_HIGH_PRIOQUEUE,
 		.dgq_wq_options = WORKQ_ADDTHREADS_OPTION_OVERCOMMIT,
@@ -289,7 +290,7 @@
 #endif
 	}}},
 	[DISPATCH_ROOT_QUEUE_IDX_USER_INTERACTIVE_QOS] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_USER_INTERACTIVE,
 		.dgq_wq_priority = WORKQ_HIGH_PRIOQUEUE_CONDITIONAL,
 		.dgq_wq_options = 0,
@@ -300,7 +301,7 @@
 #endif
 	}}},
 	[DISPATCH_ROOT_QUEUE_IDX_USER_INTERACTIVE_QOS_OVERCOMMIT] = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 		.dgq_qos = QOS_CLASS_USER_INTERACTIVE,
 		.dgq_wq_priority = WORKQ_HIGH_PRIOQUEUE_CONDITIONAL,
 		.dgq_wq_options = WORKQ_ADDTHREADS_OPTION_OVERCOMMIT,
@@ -576,11 +577,11 @@
 static inline bool
 _dispatch_root_queues_init_workq(int *wq_supported)
 {
-	int r;
+	int r; (void)r;
 	bool result = false;
 	*wq_supported = 0;
-#if HAVE_PTHREAD_WORKQUEUES
-	bool disable_wq = false;
+#if DISPATCH_USE_WORKQUEUES
+	bool disable_wq = false; (void)disable_wq;
 #if DISPATCH_ENABLE_THREAD_POOL && DISPATCH_DEBUG
 	disable_wq = slowpath(getenv("LIBDISPATCH_DISABLE_KWQ"));
 #endif
@@ -683,7 +684,7 @@
 #endif
 	}
 #endif // DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK || DISPATCH_ENABLE_THREAD_POOL
-#endif // HAVE_PTHREAD_WORKQUEUES
+#endif // DISPATCH_USE_WORKQUEUES
 	return result;
 }
 
@@ -699,7 +700,7 @@
 		thread_pool_size = pool_size;
 	}
 	qc->dgq_thread_pool_size = thread_pool_size;
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 	if (qc->dgq_qos) {
 		(void)dispatch_assume_zero(pthread_attr_init(&pqc->dpq_thread_attr));
 		(void)dispatch_assume_zero(pthread_attr_setdetachstate(
@@ -1757,7 +1758,7 @@
 		_dispatch_mgr_root_queue_pthread_context;
 static struct dispatch_root_queue_context_s
 		_dispatch_mgr_root_queue_context = {{{
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 	.dgq_kworkqueue = (void*)(~0ul),
 #endif
 	.dgq_ctxt = &_dispatch_mgr_root_queue_pthread_context,
@@ -2019,7 +2020,7 @@
 
 	pqc->dpq_thread_mediator.do_vtable = DISPATCH_VTABLE(semaphore);
 	qc->dgq_ctxt = pqc;
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 	qc->dgq_kworkqueue = (void*)(~0ul);
 #endif
 	_dispatch_root_queue_init_pthread_pool(qc, pool_size, true);
@@ -3963,7 +3964,7 @@
 
 	_dispatch_root_queues_init();
 	_dispatch_debug_root_queue(dq, __func__);
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 #if DISPATCH_USE_PTHREAD_POOL
 	if (qc->dgq_kworkqueue != (void*)(~0ul))
 #endif
@@ -3992,7 +3993,7 @@
 		(void)dispatch_assume_zero(r);
 		return;
 	}
-#endif // HAVE_PTHREAD_WORKQUEUES
+#endif // DISPATCH_USE_WORKQUEUES
 #if DISPATCH_USE_PTHREAD_POOL
 	dispatch_pthread_root_queue_context_t pqc = qc->dgq_ctxt;
 	if (fastpath(pqc->dpq_thread_mediator.do_vtable)) {
@@ -4061,7 +4062,7 @@
 	if (!_dispatch_queue_class_probe(dq)) {
 		return;
 	}
-#if HAVE_PTHREAD_WORKQUEUES
+#if DISPATCH_USE_WORKQUEUES
 	dispatch_root_queue_context_t qc = dq->do_ctxt;
 	if (
 #if DISPATCH_USE_PTHREAD_POOL
@@ -4072,7 +4073,7 @@
 				"global queue: %p", dq);
 		return;
 	}
-#endif // HAVE_PTHREAD_WORKQUEUES
+#endif // DISPATCH_USE_WORKQUEUES
 	return _dispatch_global_queue_poke_slow(dq, n, floor);
 }
 
diff --git a/src/shims.h b/src/shims.h
index eba2774..8dd23ee 100644
--- a/src/shims.h
+++ b/src/shims.h
@@ -41,8 +41,6 @@
 #if HAVE_PTHREAD_WORKQUEUES
 #if __has_include(<pthread/workqueue_private.h>)
 #include <pthread/workqueue_private.h>
-#elif DISPATCH_USE_INTERNAL_WORKQUEUE
-#include "event/workqueue_internal.h"
 #else
 #include <pthread_workqueue.h>
 #endif
@@ -51,6 +49,10 @@
 #endif
 #endif // HAVE_PTHREAD_WORKQUEUES
 
+#if DISPATCH_USE_INTERNAL_WORKQUEUE
+#include "event/workqueue_internal.h"
+#endif
+
 #if HAVE_PTHREAD_NP_H
 #include <pthread_np.h>
 #endif
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a6526fc..56e5b58 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -74,6 +74,11 @@
 	dispatch_select				\
 	$(ADDITIONAL_TESTS)
 
+# For testing in swift.org CI system; make deadlines lenient by default
+# to reduce probability of test failures due to machine load.
+if HAVE_SWIFT
+CI_CFLAGS=-DLENIENT_DEADLINES=1
+endif
 
 dispatch_c99_CFLAGS=$(DISPATCH_TESTS_CFLAGS) $(CBLOCKS_FLAGS) -std=c99
 dispatch_plusplus_SOURCES=dispatch_plusplus.cpp
@@ -82,17 +87,15 @@
 
 AM_CPPFLAGS=-I$(top_builddir) -I$(top_srcdir)
 
-DISPATCH_TESTS_CFLAGS=-Wall -Wno-deprecated-declarations $(MARCH_FLAGS)
+DISPATCH_TESTS_CFLAGS=-Wall -Wno-deprecated-declarations $(MARCH_FLAGS) $(CI_CFLAGS)
 AM_CFLAGS=$(DISPATCH_TESTS_CFLAGS) $(CBLOCKS_FLAGS) $(BSD_OVERLAY_CFLAGS)
 AM_OBJCFLAGS=$(DISPATCH_TESTS_CFLAGS) $(CBLOCKS_FLAGS)
 AM_CXXFLAGS=$(DISPATCH_TESTS_CFLAGS) $(CXXBLOCKS_FLAGS) $(BSD_OVERLAY_CFLAGS)
 AM_OBJCXXFLAGS=$(DISPATCH_TESTS_CFLAGS) $(CXXBLOCKS_FLAGS)
 
-if !DISPATCH_USE_INTERNAL_WORKQUEUE
 if HAVE_PTHREAD_WORKQUEUES
   PTHREAD_WORKQUEUE_LIBS=-lpthread_workqueue
 endif
-endif
 
 if BUILD_OWN_BLOCKS_RUNTIME
 CBLOCKS_FLAGS+= -I$(top_srcdir)/src/BlocksRuntime
diff --git a/tests/dispatch_drift.c b/tests/dispatch_drift.c
index 3e1ef97..22f82ee 100644
--- a/tests/dispatch_drift.c
+++ b/tests/dispatch_drift.c
@@ -32,7 +32,11 @@
 #include <bsdtests.h>
 #include "dispatch_test.h"
 
+#if LENIENT_DEADLINES
+#define ACCEPTABLE_DRIFT 0.1
+#else
 #define ACCEPTABLE_DRIFT 0.001
+#endif
 
 int
 main(int argc __attribute__((unused)), char* argv[] __attribute__((unused)))
diff --git a/tests/dispatch_starfish.c b/tests/dispatch_starfish.c
index e5d3fab..66ebdd0 100644
--- a/tests/dispatch_starfish.c
+++ b/tests/dispatch_starfish.c
@@ -37,7 +37,9 @@
 #define COUNT	1000ul
 #define LAPS	10ul
 
-#if TARGET_OS_EMBEDDED
+#if LENIENT_DEADLINES
+#define ACCEPTABLE_LATENCY 10000
+#elif TARGET_OS_EMBEDDED
 #define ACCEPTABLE_LATENCY 3000
 #else
 #define ACCEPTABLE_LATENCY 1000