Merge pull request #255 from apple/revert-254-das-darwin-libdispatch-890-merge-master

Revert "Merge darwin/libdispatch-890 to master"
diff --git a/INSTALL.md b/INSTALL.md
index 9940c2c..b758f2b 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -87,6 +87,11 @@
 Specify the path to Apple's libplatform package, so that appropriate headers
 	can be found and used.
 
+`--with-apple-libclosure-source`
+
+Specify the path to Apple's Libclosure package, so that appropriate headers
+	can be found and used.
+
 `--with-apple-xnu-source`
 
 Specify the path to Apple's XNU package, so that appropriate headers can be
@@ -99,6 +104,11 @@
 The following options are likely to only be useful when building libdispatch on
 OS X as a replacement for /usr/lib/system/libdispatch.dylib:
 
+`--with-apple-objc4-source`
+
+Specify the path to Apple's objc4 package, so that appropriate headers can
+	be found and used.
+
 `--disable-libdispatch-init-constructor`
 
 Do not tag libdispatch's init routine as __constructor, in which case it must be run manually before libdispatch routines can be called. This is the default when building on OS X. For /usr/lib/system/libdispatch.dylib the init routine is called automatically during process start.
@@ -121,7 +131,9 @@
 		--enable-apple-tsd-optimizations \
 		--with-apple-libpthread-source=/path/to/10.11.0/libpthread-137.1.1 \
 		--with-apple-libplatform-source=/path/to/10.11.0/libplatform-73.1.1 \
+		--with-apple-libclosure-source=/path/to/10.11.0/libclosure-65 \
 		--with-apple-xnu-source=/path/to/10.11.0/xnu-3247.1.106 \
+		--with-apple-objc4-source=/path/to/10.11.0/objc4-680
 	make check
 
 ### Building and installing for FreeBSD
diff --git a/configure.ac b/configure.ac
index 5599cb0..3221112 100644
--- a/configure.ac
+++ b/configure.ac
@@ -125,6 +125,13 @@
   CPPFLAGS="$CPPFLAGS -isystem $apple_libplatform_source_include_path"
 ])
 
+AC_ARG_WITH([apple-libclosure-source],
+  [AS_HELP_STRING([--with-apple-libclosure-source],
+    [Specify path to Apple libclosure source])], [
+  apple_libclosure_source_path=${withval}
+  CPPFLAGS="$CPPFLAGS -isystem $apple_libclosure_source_path"
+])
+
 AC_ARG_WITH([apple-xnu-source],
   [AS_HELP_STRING([--with-apple-xnu-source],
     [Specify path to Apple XNU source])], [
@@ -136,6 +143,12 @@
   CPPFLAGS="$CPPFLAGS -idirafter $apple_xnu_source_libkern_path -isystem $apple_xnu_source_bsd_path -isystem $apple_xnu_source_libsyscall_path -isystem $apple_xnu_source_libproc_path "
 ])
 
+AC_ARG_WITH([apple-objc4-source],
+  [AS_HELP_STRING([--with-apple-objc4-source],
+    [Specify path to Apple objc4 source])], [
+  apple_objc4_source_runtime_path=${withval}/runtime
+])
+
 AC_CACHE_CHECK([for System.framework/PrivateHeaders], dispatch_cv_system_privateheaders,
   [AS_IF([test -d /System/Library/Frameworks/System.framework/PrivateHeaders],
     [dispatch_cv_system_privateheaders=yes], [dispatch_cv_system_privateheaders=no])]
@@ -374,11 +387,24 @@
   [have_foundation=true], [have_foundation=false]
 )
 AM_CONDITIONAL(HAVE_FOUNDATION, $have_foundation)
-AC_CHECK_HEADER([objc/runtime.h], [
+# hack for objc4/runtime/objc-internal.h
+AS_IF([test -n "$apple_objc4_source_runtime_path"], [
+  saveCPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS -I."
+  ln -fsh "$apple_objc4_source_runtime_path" objc
+])
+AC_CHECK_HEADER([objc/objc-internal.h], [
   AC_DEFINE(HAVE_OBJC, 1, [Define if you have the Objective-C runtime])
   have_objc=true], [have_objc=false],
   [#include <objc/runtime.h>]
 )
+AS_IF([test -n "$apple_objc4_source_runtime_path"], [
+  rm -f objc
+  CPPFLAGS="$saveCPPFLAGS"
+  AC_CONFIG_COMMANDS([src/objc],
+    [ln -fsh "$apple_objc4_source_runtime_path" src/objc],
+    [apple_objc4_source_runtime_path="$apple_objc4_source_runtime_path"])
+])
 AM_CONDITIONAL(USE_OBJC, $have_objc)
 AC_LANG_POP([Objective C])
 
diff --git a/dispatch/dispatch.h b/dispatch/dispatch.h
index 2d45b83..6f8b31b 100644
--- a/dispatch/dispatch.h
+++ b/dispatch/dispatch.h
@@ -23,7 +23,6 @@
 
 #ifdef __APPLE__
 #include <Availability.h>
-#include <os/availability.h>
 #include <TargetConditionals.h>
 #include <os/base.h>
 #elif defined(__linux__)
@@ -48,7 +47,7 @@
 #endif
 #endif
 
-#define DISPATCH_API_VERSION 20170124
+#define DISPATCH_API_VERSION 20160831
 
 #ifndef __DISPATCH_BUILDING_DISPATCH__
 
diff --git a/dispatch/queue.h b/dispatch/queue.h
index 606bd30..b1dd8e5 100644
--- a/dispatch/queue.h
+++ b/dispatch/queue.h
@@ -206,49 +206,15 @@
 	void *_Nullable context,
 	dispatch_function_t work);
 
-
-#if !defined(__APPLE__) || TARGET_OS_WATCH || TARGET_OS_TV || \
-		(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
-		__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0) || \
-		(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
-		__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_9)
-#define DISPATCH_APPLY_AUTO_AVAILABLE 1
-#else
-#define DISPATCH_APPLY_AUTO_AVAILABLE 0
-#endif
-
-/*!
- * @constant DISPATCH_APPLY_AUTO
- *
- * @abstract
- * Constant to pass to dispatch_apply() or dispatch_apply_f() to request that
- * the system automatically use worker threads that match the configuration of
- * the current thread most closely.
- *
- * @discussion
- * When submitting a block for parallel invocation, passing this constant as the
- * queue argument will automatically use the global concurrent queue that
- * matches the Quality of Service of the caller most closely.
- *
- * No assumptions should be made about which global concurrent queue will
- * actually be used.
- *
- * Using this constant deploys backward to macOS 10.9, iOS 7.0 and any tvOS or
- * watchOS version.
- */
-#if DISPATCH_APPLY_AUTO_AVAILABLE
-#define DISPATCH_APPLY_AUTO ((dispatch_queue_t _Nonnull)0)
-#endif
-
 /*!
  * @function dispatch_apply
  *
  * @abstract
- * Submits a block to a dispatch queue for parallel invocation.
+ * Submits a block to a dispatch queue for multiple invocations.
  *
  * @discussion
- * Submits a block to a dispatch queue for parallel invocation. This function
- * waits for the task block to complete before returning. If the specified queue
+ * Submits a block to a dispatch queue for multiple invocations. This function
+ * waits for the task block to complete before returning. If the target queue
  * is concurrent, the block may be invoked concurrently, and it must therefore
  * be reentrant safe.
  *
@@ -258,9 +224,8 @@
  * The number of iterations to perform.
  *
  * @param queue
- * The dispatch queue to which the block is submitted.
- * The preferred value to pass is DISPATCH_APPLY_AUTO to automatically use
- * a queue appropriate for the calling thread.
+ * The target dispatch queue to which the block is submitted.
+ * The result of passing NULL in this parameter is undefined.
  *
  * @param block
  * The block to be invoked the specified number of iterations.
@@ -278,7 +243,7 @@
  * @function dispatch_apply_f
  *
  * @abstract
- * Submits a function to a dispatch queue for parallel invocation.
+ * Submits a function to a dispatch queue for multiple invocations.
  *
  * @discussion
  * See dispatch_apply() for details.
@@ -287,15 +252,14 @@
  * The number of iterations to perform.
  *
  * @param queue
- * The dispatch queue to which the function is submitted.
- * The preferred value to pass is DISPATCH_APPLY_AUTO to automatically use
- * a queue appropriate for the calling thread.
+ * The target dispatch queue to which the function is submitted.
+ * The result of passing NULL in this parameter is undefined.
  *
  * @param context
  * The application-defined context parameter to pass to the function.
  *
  * @param work
- * The application-defined function to invoke on the specified queue. The first
+ * The application-defined function to invoke on the target queue. The first
  * parameter passed to this function is the context provided to
  * dispatch_apply_f(). The second parameter passed to this function is the
  * current index of iteration.
diff --git a/libdispatch.xcodeproj/project.pbxproj b/libdispatch.xcodeproj/project.pbxproj
index 361994f..ce73d95 100644
--- a/libdispatch.xcodeproj/project.pbxproj
+++ b/libdispatch.xcodeproj/project.pbxproj
@@ -331,37 +331,6 @@
 		E48EC97C1835BADD00EAC4F1 /* yield.h in Headers */ = {isa = PBXBuildFile; fileRef = E48EC97B1835BADD00EAC4F1 /* yield.h */; };
 		E48EC97D1835BADD00EAC4F1 /* yield.h in Headers */ = {isa = PBXBuildFile; fileRef = E48EC97B1835BADD00EAC4F1 /* yield.h */; };
 		E48EC97E1835BADD00EAC4F1 /* yield.h in Headers */ = {isa = PBXBuildFile; fileRef = E48EC97B1835BADD00EAC4F1 /* yield.h */; };
-		E49BB6D11E70748100868613 /* provider.d in Sources */ = {isa = PBXBuildFile; fileRef = E43570B8126E93380097AB9F /* provider.d */; };
-		E49BB6D21E70748100868613 /* protocol.defs in Sources */ = {isa = PBXBuildFile; fileRef = FC7BED950E8361E600161930 /* protocol.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; };
-		E49BB6D31E70748100868613 /* venture.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E9955CE1C3B218E0071D40C /* venture.c */; };
-		E49BB6D41E70748100868613 /* firehose.defs in Sources */ = {isa = PBXBuildFile; fileRef = 72DEAA9B1AE1B0BD00289540 /* firehose.defs */; };
-		E49BB6D51E70748100868613 /* firehose_buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 72DEAA971AE181D300289540 /* firehose_buffer.c */; };
-		E49BB6D61E70748100868613 /* event_kevent.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E5ACCB01D3C4CFB007DA2B4 /* event_kevent.c */; };
-		E49BB6D71E70748100868613 /* resolver.c in Sources */ = {isa = PBXBuildFile; fileRef = E44EBE371251656400645D88 /* resolver.c */; };
-		E49BB6D81E70748100868613 /* mach.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E4BACBC1D48A41500B562AE /* mach.c */; };
-		E49BB6D91E70748100868613 /* init.c in Sources */ = {isa = PBXBuildFile; fileRef = E44EBE3B1251659900645D88 /* init.c */; };
-		E49BB6DA1E70748100868613 /* queue.c in Sources */ = {isa = PBXBuildFile; fileRef = FC7BED8A0E8361E600161930 /* queue.c */; };
-		E49BB6DB1E70748100868613 /* semaphore.c in Sources */ = {isa = PBXBuildFile; fileRef = 721F5CCE0F15553500FF03A6 /* semaphore.c */; };
-		E49BB6DC1E70748100868613 /* lock.c in Sources */ = {isa = PBXBuildFile; fileRef = 6EF2CAAB1C8899D5001ABE83 /* lock.c */; };
-		E49BB6DD1E70748100868613 /* firehose_reply.defs in Sources */ = {isa = PBXBuildFile; fileRef = 72406A031AF95DF800DF4E2B /* firehose_reply.defs */; settings = {ATTRIBUTES = (Server, ); }; };
-		E49BB6DE1E70748100868613 /* once.c in Sources */ = {isa = PBXBuildFile; fileRef = 96DF70BD0F38FE3C0074BD99 /* once.c */; };
-		E49BB6DF1E70748100868613 /* apply.c in Sources */ = {isa = PBXBuildFile; fileRef = 9676A0E00F3E755D00713ADB /* apply.c */; };
-		E49BB6E01E70748100868613 /* object.c in Sources */ = {isa = PBXBuildFile; fileRef = 9661E56A0F3E7DDF00749F3E /* object.c */; };
-		E49BB6E11E70748100868613 /* benchmark.c in Sources */ = {isa = PBXBuildFile; fileRef = 965CD6340F3E806200D4E28D /* benchmark.c */; };
-		E49BB6E21E70748100868613 /* event_epoll.c in Sources */ = {isa = PBXBuildFile; fileRef = 6EA7937D1D456D1300929B1B /* event_epoll.c */; };
-		E49BB6E31E70748100868613 /* source.c in Sources */ = {isa = PBXBuildFile; fileRef = 96A8AA860F41E7A400CD570B /* source.c */; };
-		E49BB6E41E70748100868613 /* time.c in Sources */ = {isa = PBXBuildFile; fileRef = 96032E4A0F5CC8C700241C5F /* time.c */; };
-		E49BB6E51E70748100868613 /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = 5AAB45BF10D30B79004407EA /* data.c */; };
-		E49BB6E61E70748100868613 /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = 5A27262510F26F1900751FBC /* io.c */; };
-		E49BB6E71E70748100868613 /* block.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43A724F1AF85BBC00BAA921 /* block.cpp */; };
-		E49BB6E81E70748100868613 /* event.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E5ACCBD1D3C6719007DA2B4 /* event.c */; };
-		E49BB6E91E70748100868613 /* transform.c in Sources */ = {isa = PBXBuildFile; fileRef = C9C5F80D143C1771006DC718 /* transform.c */; };
-		E49BB6EA1E70748100868613 /* object.m in Sources */ = {isa = PBXBuildFile; fileRef = E4FC3263145F46C9002FBDDB /* object.m */; };
-		E49BB6EB1E70748100868613 /* allocator.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BBF5A62154B64F5002B20F9 /* allocator.c */; };
-		E49BB6EC1E70748100868613 /* data.m in Sources */ = {isa = PBXBuildFile; fileRef = E420866F16027AE500EEE210 /* data.m */; };
-		E49BB6ED1E70748100868613 /* voucher.c in Sources */ = {isa = PBXBuildFile; fileRef = E44A8E6A1805C3E0009FFDB6 /* voucher.c */; };
-		E49BB7091E70A39700868613 /* venture.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E9955CE1C3B218E0071D40C /* venture.c */; };
-		E49BB70A1E70A3B000868613 /* venture.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E9955CE1C3B218E0071D40C /* venture.c */; };
 		E49F2423125D3C960057C971 /* resolver.c in Sources */ = {isa = PBXBuildFile; fileRef = E44EBE371251656400645D88 /* resolver.c */; };
 		E49F2424125D3C970057C971 /* resolver.c in Sources */ = {isa = PBXBuildFile; fileRef = E44EBE371251656400645D88 /* resolver.c */; };
 		E49F2499125D48D80057C971 /* resolver.c in Sources */ = {isa = PBXBuildFile; fileRef = E44EBE371251656400645D88 /* resolver.c */; };
@@ -590,13 +559,6 @@
 			remoteGlobalIDString = E4EC121612514715000DDBD1;
 			remoteInfo = "libdispatch mp resolved";
 		};
-		E49BB6F71E7074C100868613 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = E49BB6CE1E70748100868613;
-			remoteInfo = "libdispatch alt resolved";
-		};
 		E4B515DA164B317700E003AF /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
@@ -658,6 +620,7 @@
 		6E326B161C239431002A6505 /* dispatch_timer_short.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dispatch_timer_short.c; sourceTree = "<group>"; };
 		6E326B171C239431002A6505 /* dispatch_timer_timeout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dispatch_timer_timeout.c; sourceTree = "<group>"; };
 		6E326B441C239B61002A6505 /* dispatch_priority.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dispatch_priority.c; sourceTree = "<group>"; };
+		6E4130C91B431697001A152D /* backward-compat.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "backward-compat.xcconfig"; sourceTree = "<group>"; };
 		6E4BACBC1D48A41500B562AE /* mach.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mach.c; sourceTree = "<group>"; };
 		6E4BACC91D48A89500B562AE /* mach_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mach_internal.h; sourceTree = "<group>"; };
 		6E4FC9D11C84123600520351 /* os_venture_basic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = os_venture_basic.c; sourceTree = "<group>"; };
@@ -695,7 +658,6 @@
 		6EB4E4421BA8BD7800D7B9D2 /* libfirehose.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = libfirehose.xcconfig; sourceTree = "<group>"; };
 		6EB60D291BBB19640092FA94 /* firehose_inline_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = firehose_inline_internal.h; sourceTree = "<group>"; };
 		6EC5ABE31D4436E4004F8674 /* dispatch_deadname.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dispatch_deadname.c; sourceTree = "<group>"; };
-		6EC670C61E37E201004F10D6 /* dispatch_network_event_thread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dispatch_network_event_thread.c; sourceTree = "<group>"; };
 		6EC670C71E37E201004F10D6 /* perf_mach_async.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = perf_mach_async.c; sourceTree = "<group>"; };
 		6EC670C81E37E201004F10D6 /* perf_pipepingpong.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = perf_pipepingpong.c; sourceTree = "<group>"; };
 		6EDB888D1CB73BDC006776D6 /* dispatch_kevent_cancel_races.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dispatch_kevent_cancel_races.c; sourceTree = "<group>"; };
@@ -739,9 +701,6 @@
 		96BC39BC0F3EBAB100C59689 /* queue_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = queue_private.h; sourceTree = "<group>"; };
 		96C9553A0F3EAEDD000D2CA4 /* once.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = once.h; sourceTree = "<group>"; };
 		96DF70BD0F38FE3C0074BD99 /* once.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = once.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
-		B63B793F1E8F004F0060C1E1 /* dispatch_no_blocks.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dispatch_no_blocks.c; sourceTree = "<group>"; };
-		B68330BC1EBCF6080003E71C /* dispatch_wl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dispatch_wl.c; sourceTree = "<group>"; };
-		B6AC73FD1EB10973009FB2F2 /* perf_thread_request.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = perf_thread_request.c; sourceTree = "<group>"; };
 		B6AE9A4A1D7F53B300AC007F /* dispatch_queue_create.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dispatch_queue_create.c; sourceTree = "<group>"; };
 		B6AE9A561D7F53C100AC007F /* perf_async_bench.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = perf_async_bench.m; sourceTree = "<group>"; };
 		B6AE9A581D7F53CB00AC007F /* perf_bench.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = perf_bench.m; sourceTree = "<group>"; };
@@ -780,13 +739,12 @@
 		E44F9DA816543F79001DCD38 /* introspection_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = introspection_internal.h; sourceTree = "<group>"; };
 		E454569214746F1B00106147 /* object_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = object_private.h; sourceTree = "<group>"; };
 		E463024F1761603C00E11F4C /* atomic_sfb.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = atomic_sfb.h; sourceTree = "<group>"; };
-		E46DBC5714EE10C80001F9F6 /* libdispatch_up.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libdispatch_up.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		E46DBC5714EE10C80001F9F6 /* libdispatch.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libdispatch.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		E46DBC5814EE11BC0001F9F6 /* libdispatch-up-static.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "libdispatch-up-static.xcconfig"; sourceTree = "<group>"; };
 		E47D6BB5125F0F800070D91C /* resolved.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resolved.h; sourceTree = "<group>"; };
 		E482F1CD12DBAB590030614D /* postprocess-headers.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "postprocess-headers.sh"; sourceTree = "<group>"; };
 		E48AF55916E70FD9004105FF /* io_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = io_private.h; path = private/io_private.h; sourceTree = SOURCE_ROOT; tabWidth = 8; };
 		E48EC97B1835BADD00EAC4F1 /* yield.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yield.h; sourceTree = "<group>"; };
-		E49BB6F21E70748100868613 /* libdispatch_alt.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libdispatch_alt.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		E49F24DF125D57FA0057C971 /* libdispatch.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libdispatch.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 		E49F251D125D630A0057C971 /* install-manpages.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-manpages.sh"; sourceTree = "<group>"; };
 		E49F251E125D631D0057C971 /* mig-headers.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "mig-headers.sh"; sourceTree = "<group>"; };
@@ -955,16 +913,15 @@
 			isa = PBXGroup;
 			children = (
 				D2AAC046055464E500DB518D /* libdispatch.dylib */,
-				E4B515D6164B2DA300E003AF /* libdispatch.dylib */,
-				E49F24DF125D57FA0057C971 /* libdispatch.dylib */,
-				E4EC122D12514715000DDBD1 /* libdispatch_mp.a */,
 				E4EC11C312514302000DDBD1 /* libdispatch_up.a */,
-				E49BB6F21E70748100868613 /* libdispatch_alt.a */,
-				E46DBC5714EE10C80001F9F6 /* libdispatch_up.a */,
+				E4EC122D12514715000DDBD1 /* libdispatch_mp.a */,
+				E49F24DF125D57FA0057C971 /* libdispatch.dylib */,
+				E46DBC5714EE10C80001F9F6 /* libdispatch.a */,
+				E4B515D6164B2DA300E003AF /* libdispatch.dylib */,
+				6EB4E4091BA8BCAD00D7B9D2 /* libfirehose_server.a */,
+				6E040C631C499B1B00411A2E /* libfirehose_kernel.a */,
 				C01866BD1C5973210040FC07 /* libdispatch.a */,
 				C00B0E0A1C5AEBBE000330B3 /* libdispatch_dyld_stub.a */,
-				6E040C631C499B1B00411A2E /* libfirehose_kernel.a */,
-				6EB4E4091BA8BCAD00D7B9D2 /* libfirehose_server.a */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -1053,8 +1010,6 @@
 				6E326ABD1C22A577002A6505 /* dispatch_io_net.c */,
 				6E326ABE1C22A577002A6505 /* dispatch_io.c */,
 				6EDB888D1CB73BDC006776D6 /* dispatch_kevent_cancel_races.c */,
-				6EC670C61E37E201004F10D6 /* dispatch_network_event_thread.c */,
-				B63B793F1E8F004F0060C1E1 /* dispatch_no_blocks.c */,
 				C96CE17A1CEB851600F4B8E6 /* dispatch_objc.m */,
 				6E67D9131C17676D00FC98AC /* dispatch_overcommit.c */,
 				6E67D9151C1768B300FC98AC /* dispatch_pingpong.c */,
@@ -1084,14 +1039,12 @@
 				6E62B0531C55806200D2C7C0 /* dispatch_trysync.c */,
 				6E8E4EC91C1A670B0004F5CC /* dispatch_vm.c */,
 				6E326AB71C225FCA002A6505 /* dispatch_vnode.c */,
-				B68330BC1EBCF6080003E71C /* dispatch_wl.c */,
 				6E67D9171C17BA7200FC98AC /* nsoperation.m */,
 				6E4FC9D11C84123600520351 /* os_venture_basic.c */,
 				B6AE9A561D7F53C100AC007F /* perf_async_bench.m */,
 				B6AE9A581D7F53CB00AC007F /* perf_bench.m */,
 				6EC670C71E37E201004F10D6 /* perf_mach_async.c */,
 				6EC670C81E37E201004F10D6 /* perf_pipepingpong.c */,
-				B6AC73FD1EB10973009FB2F2 /* perf_thread_request.c */,
 				92F3FE921BEC686300025962 /* Makefile */,
 				6E8E4E6E1C1A35EE0004F5CC /* test_lib.c */,
 				6E8E4E6F1C1A35EE0004F5CC /* test_lib.h */,
@@ -1136,6 +1089,7 @@
 		E40041E4125E71150022B135 /* xcodeconfig */ = {
 			isa = PBXGroup;
 			children = (
+				6E4130C91B431697001A152D /* backward-compat.xcconfig */,
 				E43D93F11097917E004F6A62 /* libdispatch.xcconfig */,
 				E40041AA125D705F0022B135 /* libdispatch-resolver.xcconfig */,
 				E40041A9125D70590022B135 /* libdispatch-resolved.xcconfig */,
@@ -1633,9 +1587,8 @@
 			);
 			dependencies = (
 				6EF0B27E1BA8C5BF007FA4F6 /* PBXTargetDependency */,
-				E47D6ECD125FEBA10070D91C /* PBXTargetDependency */,
 				E47D6ECB125FEB9D0070D91C /* PBXTargetDependency */,
-				E49BB6F81E7074C100868613 /* PBXTargetDependency */,
+				E47D6ECD125FEBA10070D91C /* PBXTargetDependency */,
 				E4B515DB164B317700E003AF /* PBXTargetDependency */,
 				C01866C21C597AEA0040FC07 /* PBXTargetDependency */,
 				E437F0D614F7441F00F0B997 /* PBXTargetDependency */,
@@ -1658,24 +1611,7 @@
 			);
 			name = "libdispatch up static";
 			productName = libdispatch;
-			productReference = E46DBC5714EE10C80001F9F6 /* libdispatch_up.a */;
-			productType = "com.apple.product-type.library.static";
-		};
-		E49BB6CE1E70748100868613 /* libdispatch alt resolved */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = E49BB6EF1E70748100868613 /* Build configuration list for PBXNativeTarget "libdispatch alt resolved" */;
-			buildPhases = (
-				E49BB6CF1E70748100868613 /* Mig Headers */,
-				E49BB6D01E70748100868613 /* Sources */,
-				E49BB6EE1E70748100868613 /* Symlink normal variant */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = "libdispatch alt resolved";
-			productName = libdispatch;
-			productReference = E49BB6F21E70748100868613 /* libdispatch_alt.a */;
+			productReference = E46DBC5714EE10C80001F9F6 /* libdispatch.a */;
 			productType = "com.apple.product-type.library.static";
 		};
 		E49F24A9125D57FA0057C971 /* libdispatch no resolver */ = {
@@ -1756,7 +1692,7 @@
 			isa = PBXProject;
 			attributes = {
 				BuildIndependentTargetsInParallel = YES;
-				LastUpgradeCheck = 0900;
+				LastUpgradeCheck = 0820;
 				TargetAttributes = {
 					3F3C9326128E637B0042B1F7 = {
 						ProvisioningStyle = Manual;
@@ -1840,7 +1776,6 @@
 				E49F24A9125D57FA0057C971 /* libdispatch no resolver */,
 				E4EC121612514715000DDBD1 /* libdispatch mp resolved */,
 				E4EC118F12514302000DDBD1 /* libdispatch up resolved */,
-				E49BB6CE1E70748100868613 /* libdispatch alt resolved */,
 				E4B51595164B2DA300E003AF /* libdispatch introspection */,
 				E46DBC1A14EE10C80001F9F6 /* libdispatch up static */,
 				C01866A41C5973210040FC07 /* libdispatch mp static */,
@@ -1996,47 +1931,6 @@
 			shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"";
 			showEnvVarsInLog = 0;
 		};
-		E49BB6CF1E70748100868613 /* Mig Headers */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-				"$(SRCROOT)/src/protocol.defs",
-				"$(SRCROOT)/src/firehose/firehose.defs",
-				"$(SRCROOT)/src/firehose/firehose_reply.defs",
-				"$(SRCROOT)/xcodescripts/mig-headers.sh",
-			);
-			name = "Mig Headers";
-			outputPaths = (
-				"$(DERIVED_FILE_DIR)/protocol.h",
-				"$(DERIVED_FILE_DIR)/protocolServer.h",
-				"$(DERIVED_FILE_DIR)/firehose.h",
-				"$(DERIVED_FILE_DIR)/firehoseServer.h",
-				"$(DERIVED_FILE_DIR)/firehose_reply.h",
-				"$(DERIVED_FILE_DIR)/firehose_replyServer.h",
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = "/bin/bash -e";
-			shellScript = ". \"${SCRIPT_INPUT_FILE_3}\"";
-			showEnvVarsInLog = 0;
-		};
-		E49BB6EE1E70748100868613 /* Symlink normal variant */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			name = "Symlink normal variant";
-			outputPaths = (
-				"$(CONFIGURATION_BUILD_DIR)/$(PRODUCT_NAME)_normal.a",
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = "/bin/bash -e";
-			shellScript = "ln -fs \"${PRODUCT_NAME}.a\" \"${SCRIPT_OUTPUT_FILE_0}\"";
-			showEnvVarsInLog = 0;
-		};
 		E49F24D7125D57FA0057C971 /* Install Manpages */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 8;
@@ -2202,10 +2096,10 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				6E90269C1BB9BD50004DC3AD /* firehose.defs in Sources */,
-				6EF0B2781BA8C56E007FA4F6 /* firehose_reply.defs in Sources */,
 				6EF0B27A1BA8C57D007FA4F6 /* firehose_server_object.m in Sources */,
+				6E90269C1BB9BD50004DC3AD /* firehose.defs in Sources */,
 				6E21F2E91BBB240E0000C6A5 /* firehose_server.c in Sources */,
+				6EF0B2781BA8C56E007FA4F6 /* firehose_reply.defs in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2214,31 +2108,30 @@
 			buildActionMask = 2147483647;
 			files = (
 				C00B0DF21C5AEBBE000330B3 /* protocol.defs in Sources */,
-				C00B0DF71C5AEBBE000330B3 /* firehose.defs in Sources */,
-				C00B0DFA1C5AEBBE000330B3 /* firehose_reply.defs in Sources */,
 				C00B0DF31C5AEBBE000330B3 /* resolver.c in Sources */,
-				C00B0DF41C5AEBBE000330B3 /* init.c in Sources */,
-				C00B0DFE1C5AEBBE000330B3 /* object.c in Sources */,
-				C00B0DF81C5AEBBE000330B3 /* block.cpp in Sources */,
-				6EF2CAB31C8899ED001ABE83 /* lock.c in Sources */,
-				C00B0DF91C5AEBBE000330B3 /* semaphore.c in Sources */,
-				C00B0DFB1C5AEBBE000330B3 /* once.c in Sources */,
-				C00B0DF51C5AEBBE000330B3 /* queue.c in Sources */,
-				C00B0DFD1C5AEBBE000330B3 /* apply.c in Sources */,
-				C00B0E001C5AEBBE000330B3 /* source.c in Sources */,
-				6E4BACC81D48A42400B562AE /* mach.c in Sources */,
-				6EA9629E1D48622C00759D53 /* event.c in Sources */,
-				6EA962A61D48625500759D53 /* event_kevent.c in Sources */,
 				6E4BACFC1D49A04A00B562AE /* event_epoll.c in Sources */,
-				C00B0DFC1C5AEBBE000330B3 /* voucher.c in Sources */,
+				6EF2CAB31C8899ED001ABE83 /* lock.c in Sources */,
+				C00B0DF41C5AEBBE000330B3 /* init.c in Sources */,
+				C00B0DF51C5AEBBE000330B3 /* queue.c in Sources */,
 				C00B0DF61C5AEBBE000330B3 /* firehose_buffer.c in Sources */,
-				C00B0E031C5AEBBE000330B3 /* io.c in Sources */,
-				C00B0E021C5AEBBE000330B3 /* data.c in Sources */,
-				C00B0E041C5AEBBE000330B3 /* transform.c in Sources */,
-				C00B0E011C5AEBBE000330B3 /* time.c in Sources */,
-				C00B0E051C5AEBBE000330B3 /* allocator.c in Sources */,
+				C00B0DF71C5AEBBE000330B3 /* firehose.defs in Sources */,
+				C00B0DF81C5AEBBE000330B3 /* block.cpp in Sources */,
+				C00B0DF91C5AEBBE000330B3 /* semaphore.c in Sources */,
+				6E4BACC81D48A42400B562AE /* mach.c in Sources */,
+				C00B0DFA1C5AEBBE000330B3 /* firehose_reply.defs in Sources */,
+				C00B0DFB1C5AEBBE000330B3 /* once.c in Sources */,
+				C00B0DFC1C5AEBBE000330B3 /* voucher.c in Sources */,
+				C00B0DFD1C5AEBBE000330B3 /* apply.c in Sources */,
+				C00B0DFE1C5AEBBE000330B3 /* object.c in Sources */,
 				C00B0DFF1C5AEBBE000330B3 /* benchmark.c in Sources */,
-				E49BB70A1E70A3B000868613 /* venture.c in Sources */,
+				C00B0E001C5AEBBE000330B3 /* source.c in Sources */,
+				C00B0E011C5AEBBE000330B3 /* time.c in Sources */,
+				C00B0E021C5AEBBE000330B3 /* data.c in Sources */,
+				6EA962A61D48625500759D53 /* event_kevent.c in Sources */,
+				C00B0E031C5AEBBE000330B3 /* io.c in Sources */,
+				C00B0E041C5AEBBE000330B3 /* transform.c in Sources */,
+				6EA9629E1D48622C00759D53 /* event.c in Sources */,
+				C00B0E051C5AEBBE000330B3 /* allocator.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2247,31 +2140,30 @@
 			buildActionMask = 2147483647;
 			files = (
 				C01866A61C5973210040FC07 /* protocol.defs in Sources */,
-				C01866AB1C5973210040FC07 /* firehose.defs in Sources */,
-				C01866AE1C5973210040FC07 /* firehose_reply.defs in Sources */,
 				C01866A71C5973210040FC07 /* resolver.c in Sources */,
-				C01866A81C5973210040FC07 /* init.c in Sources */,
-				C01866B21C5973210040FC07 /* object.c in Sources */,
-				C01866AC1C5973210040FC07 /* block.cpp in Sources */,
-				6EF2CAB21C8899EC001ABE83 /* lock.c in Sources */,
-				C01866AD1C5973210040FC07 /* semaphore.c in Sources */,
-				C01866AF1C5973210040FC07 /* once.c in Sources */,
-				C01866A91C5973210040FC07 /* queue.c in Sources */,
-				C01866B11C5973210040FC07 /* apply.c in Sources */,
-				C01866B41C5973210040FC07 /* source.c in Sources */,
-				6E4BACC71D48A42300B562AE /* mach.c in Sources */,
-				6EA9629D1D48622B00759D53 /* event.c in Sources */,
-				6EA962A51D48625400759D53 /* event_kevent.c in Sources */,
 				6E4BACFB1D49A04A00B562AE /* event_epoll.c in Sources */,
-				C01866B01C5973210040FC07 /* voucher.c in Sources */,
+				6EF2CAB21C8899EC001ABE83 /* lock.c in Sources */,
+				C01866A81C5973210040FC07 /* init.c in Sources */,
+				C01866A91C5973210040FC07 /* queue.c in Sources */,
 				C01866AA1C5973210040FC07 /* firehose_buffer.c in Sources */,
-				C01866B71C5973210040FC07 /* io.c in Sources */,
-				C01866B61C5973210040FC07 /* data.c in Sources */,
-				C01866B81C5973210040FC07 /* transform.c in Sources */,
-				C01866B51C5973210040FC07 /* time.c in Sources */,
-				C01866B91C5973210040FC07 /* allocator.c in Sources */,
+				C01866AB1C5973210040FC07 /* firehose.defs in Sources */,
+				C01866AC1C5973210040FC07 /* block.cpp in Sources */,
+				C01866AD1C5973210040FC07 /* semaphore.c in Sources */,
+				6E4BACC71D48A42300B562AE /* mach.c in Sources */,
+				C01866AE1C5973210040FC07 /* firehose_reply.defs in Sources */,
+				C01866AF1C5973210040FC07 /* once.c in Sources */,
+				C01866B01C5973210040FC07 /* voucher.c in Sources */,
+				C01866B11C5973210040FC07 /* apply.c in Sources */,
+				C01866B21C5973210040FC07 /* object.c in Sources */,
 				C01866B31C5973210040FC07 /* benchmark.c in Sources */,
-				E49BB7091E70A39700868613 /* venture.c in Sources */,
+				C01866B41C5973210040FC07 /* source.c in Sources */,
+				C01866B51C5973210040FC07 /* time.c in Sources */,
+				C01866B61C5973210040FC07 /* data.c in Sources */,
+				6EA962A51D48625400759D53 /* event_kevent.c in Sources */,
+				C01866B71C5973210040FC07 /* io.c in Sources */,
+				C01866B81C5973210040FC07 /* transform.c in Sources */,
+				6EA9629D1D48622B00759D53 /* event.c in Sources */,
+				C01866B91C5973210040FC07 /* allocator.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2281,33 +2173,33 @@
 			files = (
 				E43570B9126E93380097AB9F /* provider.d in Sources */,
 				FC7BEDA40E8361E600161930 /* protocol.defs in Sources */,
-				6ED64B471BBD89AF00C35F4D /* firehose.defs in Sources */,
-				6ED64B491BBD89BC00C35F4D /* firehose_reply.defs in Sources */,
-				E49F2499125D48D80057C971 /* resolver.c in Sources */,
-				E44EBE3E1251659900645D88 /* init.c in Sources */,
-				9661E56B0F3E7DDF00749F3E /* object.c in Sources */,
-				E4FC3264145F46C9002FBDDB /* object.m in Sources */,
-				E43A72501AF85BBC00BAA921 /* block.cpp in Sources */,
-				6EF2CAAC1C8899D5001ABE83 /* lock.c in Sources */,
-				721F5CCF0F15553500FF03A6 /* semaphore.c in Sources */,
-				96DF70BE0F38FE3C0074BD99 /* once.c in Sources */,
-				FC7BED990E8361E600161930 /* queue.c in Sources */,
-				9676A0E10F3E755D00713ADB /* apply.c in Sources */,
-				96A8AA870F41E7A400CD570B /* source.c in Sources */,
-				6E4BACBD1D48A41500B562AE /* mach.c in Sources */,
-				6EA962971D48622600759D53 /* event.c in Sources */,
-				6EA9629F1D48625000759D53 /* event_kevent.c in Sources */,
-				6E4BACF51D49A04600B562AE /* event_epoll.c in Sources */,
-				E44A8E6B1805C3E0009FFDB6 /* voucher.c in Sources */,
-				6ED64B441BBD898700C35F4D /* firehose_buffer.c in Sources */,
-				5A27262610F26F1900751FBC /* io.c in Sources */,
-				5AAB45C010D30B79004407EA /* data.c in Sources */,
-				E420867016027AE500EEE210 /* data.m in Sources */,
-				C9C5F80E143C1771006DC718 /* transform.c in Sources */,
-				96032E4B0F5CC8C700241C5F /* time.c in Sources */,
-				2BBF5A63154B64F5002B20F9 /* allocator.c in Sources */,
-				965CD6350F3E806200D4E28D /* benchmark.c in Sources */,
 				6E9955CF1C3B218E0071D40C /* venture.c in Sources */,
+				6ED64B471BBD89AF00C35F4D /* firehose.defs in Sources */,
+				6ED64B441BBD898700C35F4D /* firehose_buffer.c in Sources */,
+				6EA9629F1D48625000759D53 /* event_kevent.c in Sources */,
+				E49F2499125D48D80057C971 /* resolver.c in Sources */,
+				6E4BACBD1D48A41500B562AE /* mach.c in Sources */,
+				E44EBE3E1251659900645D88 /* init.c in Sources */,
+				FC7BED990E8361E600161930 /* queue.c in Sources */,
+				721F5CCF0F15553500FF03A6 /* semaphore.c in Sources */,
+				6EF2CAAC1C8899D5001ABE83 /* lock.c in Sources */,
+				6ED64B491BBD89BC00C35F4D /* firehose_reply.defs in Sources */,
+				96DF70BE0F38FE3C0074BD99 /* once.c in Sources */,
+				9676A0E10F3E755D00713ADB /* apply.c in Sources */,
+				9661E56B0F3E7DDF00749F3E /* object.c in Sources */,
+				965CD6350F3E806200D4E28D /* benchmark.c in Sources */,
+				6E4BACF51D49A04600B562AE /* event_epoll.c in Sources */,
+				96A8AA870F41E7A400CD570B /* source.c in Sources */,
+				96032E4B0F5CC8C700241C5F /* time.c in Sources */,
+				5AAB45C010D30B79004407EA /* data.c in Sources */,
+				5A27262610F26F1900751FBC /* io.c in Sources */,
+				E43A72501AF85BBC00BAA921 /* block.cpp in Sources */,
+				6EA962971D48622600759D53 /* event.c in Sources */,
+				C9C5F80E143C1771006DC718 /* transform.c in Sources */,
+				E4FC3264145F46C9002FBDDB /* object.m in Sources */,
+				2BBF5A63154B64F5002B20F9 /* allocator.c in Sources */,
+				E420867016027AE500EEE210 /* data.m in Sources */,
+				E44A8E6B1805C3E0009FFDB6 /* voucher.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2315,68 +2207,32 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				E46DBC4014EE10C80001F9F6 /* protocol.defs in Sources */,
-				6EBEC7E71BBDD30F009B1596 /* firehose.defs in Sources */,
-				6EBEC7EA1BBDD326009B1596 /* firehose_reply.defs in Sources */,
-				E46DBC4114EE10C80001F9F6 /* resolver.c in Sources */,
-				E46DBC4214EE10C80001F9F6 /* init.c in Sources */,
-				E46DBC4714EE10C80001F9F6 /* object.c in Sources */,
-				E43A72881AF85BE900BAA921 /* block.cpp in Sources */,
-				6EF2CAB11C8899EC001ABE83 /* lock.c in Sources */,
-				E46DBC4414EE10C80001F9F6 /* semaphore.c in Sources */,
-				E46DBC4514EE10C80001F9F6 /* once.c in Sources */,
-				E46DBC4314EE10C80001F9F6 /* queue.c in Sources */,
-				E46DBC4614EE10C80001F9F6 /* apply.c in Sources */,
-				E46DBC4914EE10C80001F9F6 /* source.c in Sources */,
 				6E4BACC61D48A42300B562AE /* mach.c in Sources */,
-				6EA9629C1D48622A00759D53 /* event.c in Sources */,
+				E46DBC4014EE10C80001F9F6 /* protocol.defs in Sources */,
+				E46DBC4114EE10C80001F9F6 /* resolver.c in Sources */,
+				6EF2CAB11C8899EC001ABE83 /* lock.c in Sources */,
+				E46DBC4214EE10C80001F9F6 /* init.c in Sources */,
+				E46DBC4314EE10C80001F9F6 /* queue.c in Sources */,
 				6EA962A41D48625300759D53 /* event_kevent.c in Sources */,
-				6E4BACFA1D49A04900B562AE /* event_epoll.c in Sources */,
-				E44A8E701805C3E0009FFDB6 /* voucher.c in Sources */,
 				6EE664271BE2FD5C00ED7B1C /* firehose_buffer.c in Sources */,
-				E46DBC4C14EE10C80001F9F6 /* io.c in Sources */,
-				E46DBC4B14EE10C80001F9F6 /* data.c in Sources */,
-				E46DBC4D14EE10C80001F9F6 /* transform.c in Sources */,
-				E46DBC4A14EE10C80001F9F6 /* time.c in Sources */,
-				2BBF5A67154B64F5002B20F9 /* allocator.c in Sources */,
-				E46DBC4814EE10C80001F9F6 /* benchmark.c in Sources */,
+				6EA9629C1D48622A00759D53 /* event.c in Sources */,
+				6EBEC7E71BBDD30F009B1596 /* firehose.defs in Sources */,
+				E43A72881AF85BE900BAA921 /* block.cpp in Sources */,
+				E46DBC4414EE10C80001F9F6 /* semaphore.c in Sources */,
 				6E9956011C3B21980071D40C /* venture.c in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-		E49BB6D01E70748100868613 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				E49BB6D11E70748100868613 /* provider.d in Sources */,
-				E49BB6D21E70748100868613 /* protocol.defs in Sources */,
-				E49BB6D41E70748100868613 /* firehose.defs in Sources */,
-				E49BB6DD1E70748100868613 /* firehose_reply.defs in Sources */,
-				E49BB6D71E70748100868613 /* resolver.c in Sources */,
-				E49BB6D91E70748100868613 /* init.c in Sources */,
-				E49BB6E01E70748100868613 /* object.c in Sources */,
-				E49BB6EA1E70748100868613 /* object.m in Sources */,
-				E49BB6E71E70748100868613 /* block.cpp in Sources */,
-				E49BB6DC1E70748100868613 /* lock.c in Sources */,
-				E49BB6DB1E70748100868613 /* semaphore.c in Sources */,
-				E49BB6DE1E70748100868613 /* once.c in Sources */,
-				E49BB6D81E70748100868613 /* mach.c in Sources */,
-				E49BB6DA1E70748100868613 /* queue.c in Sources */,
-				E49BB6DF1E70748100868613 /* apply.c in Sources */,
-				E49BB6E31E70748100868613 /* source.c in Sources */,
-				E49BB6E81E70748100868613 /* event.c in Sources */,
-				E49BB6D61E70748100868613 /* event_kevent.c in Sources */,
-				E49BB6E21E70748100868613 /* event_epoll.c in Sources */,
-				E49BB6ED1E70748100868613 /* voucher.c in Sources */,
-				E49BB6D51E70748100868613 /* firehose_buffer.c in Sources */,
-				E49BB6E61E70748100868613 /* io.c in Sources */,
-				E49BB6E51E70748100868613 /* data.c in Sources */,
-				E49BB6EC1E70748100868613 /* data.m in Sources */,
-				E49BB6E91E70748100868613 /* transform.c in Sources */,
-				E49BB6E41E70748100868613 /* time.c in Sources */,
-				E49BB6EB1E70748100868613 /* allocator.c in Sources */,
-				E49BB6E11E70748100868613 /* benchmark.c in Sources */,
-				E49BB6D31E70748100868613 /* venture.c in Sources */,
+				6EBEC7EA1BBDD326009B1596 /* firehose_reply.defs in Sources */,
+				E46DBC4514EE10C80001F9F6 /* once.c in Sources */,
+				E44A8E701805C3E0009FFDB6 /* voucher.c in Sources */,
+				E46DBC4614EE10C80001F9F6 /* apply.c in Sources */,
+				E46DBC4714EE10C80001F9F6 /* object.c in Sources */,
+				E46DBC4814EE10C80001F9F6 /* benchmark.c in Sources */,
+				E46DBC4914EE10C80001F9F6 /* source.c in Sources */,
+				E46DBC4A14EE10C80001F9F6 /* time.c in Sources */,
+				E46DBC4B14EE10C80001F9F6 /* data.c in Sources */,
+				E46DBC4C14EE10C80001F9F6 /* io.c in Sources */,
+				E46DBC4D14EE10C80001F9F6 /* transform.c in Sources */,
+				2BBF5A67154B64F5002B20F9 /* allocator.c in Sources */,
+				6E4BACFA1D49A04900B562AE /* event_epoll.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2386,33 +2242,33 @@
 			files = (
 				E43570BA126E93380097AB9F /* provider.d in Sources */,
 				E49F24C8125D57FA0057C971 /* protocol.defs in Sources */,
-				6ED64B461BBD89AF00C35F4D /* firehose.defs in Sources */,
-				6ED64B4A1BBD89BD00C35F4D /* firehose_reply.defs in Sources */,
-				E49F24C9125D57FA0057C971 /* resolver.c in Sources */,
-				E49F24CA125D57FA0057C971 /* init.c in Sources */,
-				E49F24CF125D57FA0057C971 /* object.c in Sources */,
-				E4FC3265145F46C9002FBDDB /* object.m in Sources */,
-				E43A72841AF85BCB00BAA921 /* block.cpp in Sources */,
-				6EF2CAAD1C8899E9001ABE83 /* lock.c in Sources */,
-				E49F24CC125D57FA0057C971 /* semaphore.c in Sources */,
-				E49F24CD125D57FA0057C971 /* once.c in Sources */,
-				E49F24CB125D57FA0057C971 /* queue.c in Sources */,
-				E49F24CE125D57FA0057C971 /* apply.c in Sources */,
-				E49F24D1125D57FA0057C971 /* source.c in Sources */,
-				6E4BACC21D48A42000B562AE /* mach.c in Sources */,
-				6EA962981D48622700759D53 /* event.c in Sources */,
-				6EA962A01D48625100759D53 /* event_kevent.c in Sources */,
-				6E4BACF61D49A04700B562AE /* event_epoll.c in Sources */,
-				E44A8E6C1805C3E0009FFDB6 /* voucher.c in Sources */,
-				6ED64B401BBD898300C35F4D /* firehose_buffer.c in Sources */,
-				E49F24D4125D57FA0057C971 /* io.c in Sources */,
-				E49F24D3125D57FA0057C971 /* data.c in Sources */,
-				E420867116027AE500EEE210 /* data.m in Sources */,
-				C93D6165143E190E00EB9023 /* transform.c in Sources */,
-				E49F24D2125D57FA0057C971 /* time.c in Sources */,
-				2BBF5A64154B64F5002B20F9 /* allocator.c in Sources */,
-				E49F24D0125D57FA0057C971 /* benchmark.c in Sources */,
 				6E9956051C3B219B0071D40C /* venture.c in Sources */,
+				6ED64B461BBD89AF00C35F4D /* firehose.defs in Sources */,
+				6ED64B401BBD898300C35F4D /* firehose_buffer.c in Sources */,
+				6EA962A01D48625100759D53 /* event_kevent.c in Sources */,
+				E49F24C9125D57FA0057C971 /* resolver.c in Sources */,
+				6E4BACC21D48A42000B562AE /* mach.c in Sources */,
+				E49F24CA125D57FA0057C971 /* init.c in Sources */,
+				E49F24CB125D57FA0057C971 /* queue.c in Sources */,
+				E49F24CC125D57FA0057C971 /* semaphore.c in Sources */,
+				6EF2CAAD1C8899E9001ABE83 /* lock.c in Sources */,
+				6ED64B4A1BBD89BD00C35F4D /* firehose_reply.defs in Sources */,
+				E49F24CD125D57FA0057C971 /* once.c in Sources */,
+				E49F24CE125D57FA0057C971 /* apply.c in Sources */,
+				E49F24CF125D57FA0057C971 /* object.c in Sources */,
+				E49F24D0125D57FA0057C971 /* benchmark.c in Sources */,
+				6E4BACF61D49A04700B562AE /* event_epoll.c in Sources */,
+				E49F24D1125D57FA0057C971 /* source.c in Sources */,
+				E49F24D2125D57FA0057C971 /* time.c in Sources */,
+				E49F24D3125D57FA0057C971 /* data.c in Sources */,
+				E49F24D4125D57FA0057C971 /* io.c in Sources */,
+				E43A72841AF85BCB00BAA921 /* block.cpp in Sources */,
+				6EA962981D48622700759D53 /* event.c in Sources */,
+				C93D6165143E190E00EB9023 /* transform.c in Sources */,
+				E4FC3265145F46C9002FBDDB /* object.m in Sources */,
+				2BBF5A64154B64F5002B20F9 /* allocator.c in Sources */,
+				E420867116027AE500EEE210 /* data.m in Sources */,
+				E44A8E6C1805C3E0009FFDB6 /* voucher.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2421,34 +2277,34 @@
 			buildActionMask = 2147483647;
 			files = (
 				E4B515BD164B2DA300E003AF /* provider.d in Sources */,
+				6EA962A31D48625300759D53 /* event_kevent.c in Sources */,
 				E4B515BE164B2DA300E003AF /* protocol.defs in Sources */,
-				6ED64B481BBD89B100C35F4D /* firehose.defs in Sources */,
-				6ED64B4B1BBD89BE00C35F4D /* firehose_reply.defs in Sources */,
 				E4B515BF164B2DA300E003AF /* resolver.c in Sources */,
+				6ED64B4B1BBD89BE00C35F4D /* firehose_reply.defs in Sources */,
+				6ED64B481BBD89B100C35F4D /* firehose.defs in Sources */,
 				E4B515C0164B2DA300E003AF /* init.c in Sources */,
-				E4B515C5164B2DA300E003AF /* object.c in Sources */,
-				E4B515CC164B2DA300E003AF /* object.m in Sources */,
-				E43A72871AF85BCD00BAA921 /* block.cpp in Sources */,
-				6EF2CAB01C8899EB001ABE83 /* lock.c in Sources */,
+				6EA9629B1D48622900759D53 /* event.c in Sources */,
+				E4B515C1164B2DA300E003AF /* queue.c in Sources */,
+				6E9956021C3B21990071D40C /* venture.c in Sources */,
 				E4B515C2164B2DA300E003AF /* semaphore.c in Sources */,
 				E4B515C3164B2DA300E003AF /* once.c in Sources */,
-				E4B515C1164B2DA300E003AF /* queue.c in Sources */,
+				E43A72871AF85BCD00BAA921 /* block.cpp in Sources */,
 				E4B515C4164B2DA300E003AF /* apply.c in Sources */,
-				E4B515C7164B2DA300E003AF /* source.c in Sources */,
-				6E4BACC51D48A42200B562AE /* mach.c in Sources */,
-				6EA9629B1D48622900759D53 /* event.c in Sources */,
-				6EA962A31D48625300759D53 /* event_kevent.c in Sources */,
-				6E4BACF91D49A04800B562AE /* event_epoll.c in Sources */,
-				E44A8E6F1805C3E0009FFDB6 /* voucher.c in Sources */,
+				E4B515C5164B2DA300E003AF /* object.c in Sources */,
 				6ED64B431BBD898600C35F4D /* firehose_buffer.c in Sources */,
-				E4B515CA164B2DA300E003AF /* io.c in Sources */,
-				E4B515C9164B2DA300E003AF /* data.c in Sources */,
-				E4B515CE164B2DA300E003AF /* data.m in Sources */,
-				E4B515CB164B2DA300E003AF /* transform.c in Sources */,
-				E4B515C8164B2DA300E003AF /* time.c in Sources */,
-				E4B515CD164B2DA300E003AF /* allocator.c in Sources */,
 				E4B515C6164B2DA300E003AF /* benchmark.c in Sources */,
-				6E9956021C3B21990071D40C /* venture.c in Sources */,
+				E4B515C7164B2DA300E003AF /* source.c in Sources */,
+				E4B515C8164B2DA300E003AF /* time.c in Sources */,
+				6E4BACC51D48A42200B562AE /* mach.c in Sources */,
+				E4B515C9164B2DA300E003AF /* data.c in Sources */,
+				E4B515CA164B2DA300E003AF /* io.c in Sources */,
+				E44A8E6F1805C3E0009FFDB6 /* voucher.c in Sources */,
+				E4B515CB164B2DA300E003AF /* transform.c in Sources */,
+				6EF2CAB01C8899EB001ABE83 /* lock.c in Sources */,
+				E4B515CC164B2DA300E003AF /* object.m in Sources */,
+				E4B515CD164B2DA300E003AF /* allocator.c in Sources */,
+				6E4BACF91D49A04800B562AE /* event_epoll.c in Sources */,
+				E4B515CE164B2DA300E003AF /* data.m in Sources */,
 				E4B515DD164B32E000E003AF /* introspection.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -2459,33 +2315,33 @@
 			files = (
 				E417A38412A472C4004D659D /* provider.d in Sources */,
 				E44EBE5412517EBE00645D88 /* protocol.defs in Sources */,
-				6EBEC7E61BBDD30D009B1596 /* firehose.defs in Sources */,
-				6EBEC7E91BBDD325009B1596 /* firehose_reply.defs in Sources */,
-				E49F2424125D3C970057C971 /* resolver.c in Sources */,
-				E44EBE5512517EBE00645D88 /* init.c in Sources */,
-				E4EC11B212514302000DDBD1 /* object.c in Sources */,
-				E4FC3266145F46C9002FBDDB /* object.m in Sources */,
-				E43A72861AF85BCC00BAA921 /* block.cpp in Sources */,
-				6EF2CAAF1C8899EB001ABE83 /* lock.c in Sources */,
-				E4EC11AF12514302000DDBD1 /* semaphore.c in Sources */,
-				E4EC11B012514302000DDBD1 /* once.c in Sources */,
-				E4EC11AE12514302000DDBD1 /* queue.c in Sources */,
-				E4EC11B112514302000DDBD1 /* apply.c in Sources */,
-				E4EC11B412514302000DDBD1 /* source.c in Sources */,
-				6E4BACC41D48A42200B562AE /* mach.c in Sources */,
-				6EA9629A1D48622900759D53 /* event.c in Sources */,
-				6EA962A21D48625200759D53 /* event_kevent.c in Sources */,
-				6E4BACF81D49A04800B562AE /* event_epoll.c in Sources */,
-				E44A8E6E1805C3E0009FFDB6 /* voucher.c in Sources */,
-				6ED64B421BBD898500C35F4D /* firehose_buffer.c in Sources */,
-				E4EC11B812514302000DDBD1 /* io.c in Sources */,
-				E4EC11B712514302000DDBD1 /* data.c in Sources */,
-				E420867316027AE500EEE210 /* data.m in Sources */,
-				C93D6166143E190F00EB9023 /* transform.c in Sources */,
-				E4EC11B512514302000DDBD1 /* time.c in Sources */,
-				2BBF5A65154B64F5002B20F9 /* allocator.c in Sources */,
-				E4EC11B312514302000DDBD1 /* benchmark.c in Sources */,
 				6E9956031C3B219A0071D40C /* venture.c in Sources */,
+				6EBEC7E61BBDD30D009B1596 /* firehose.defs in Sources */,
+				6ED64B421BBD898500C35F4D /* firehose_buffer.c in Sources */,
+				6EA962A21D48625200759D53 /* event_kevent.c in Sources */,
+				E49F2424125D3C970057C971 /* resolver.c in Sources */,
+				6E4BACC41D48A42200B562AE /* mach.c in Sources */,
+				E44EBE5512517EBE00645D88 /* init.c in Sources */,
+				E4EC11AE12514302000DDBD1 /* queue.c in Sources */,
+				E4EC11AF12514302000DDBD1 /* semaphore.c in Sources */,
+				6EF2CAAF1C8899EB001ABE83 /* lock.c in Sources */,
+				6EBEC7E91BBDD325009B1596 /* firehose_reply.defs in Sources */,
+				E4EC11B012514302000DDBD1 /* once.c in Sources */,
+				E4EC11B112514302000DDBD1 /* apply.c in Sources */,
+				E4EC11B212514302000DDBD1 /* object.c in Sources */,
+				E4EC11B312514302000DDBD1 /* benchmark.c in Sources */,
+				6E4BACF81D49A04800B562AE /* event_epoll.c in Sources */,
+				E4EC11B412514302000DDBD1 /* source.c in Sources */,
+				E4EC11B512514302000DDBD1 /* time.c in Sources */,
+				E4EC11B712514302000DDBD1 /* data.c in Sources */,
+				E4EC11B812514302000DDBD1 /* io.c in Sources */,
+				E43A72861AF85BCC00BAA921 /* block.cpp in Sources */,
+				6EA9629A1D48622900759D53 /* event.c in Sources */,
+				C93D6166143E190F00EB9023 /* transform.c in Sources */,
+				E4FC3266145F46C9002FBDDB /* object.m in Sources */,
+				2BBF5A65154B64F5002B20F9 /* allocator.c in Sources */,
+				E420867316027AE500EEE210 /* data.m in Sources */,
+				E44A8E6E1805C3E0009FFDB6 /* voucher.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2495,33 +2351,33 @@
 			files = (
 				E417A38512A472C5004D659D /* provider.d in Sources */,
 				E44EBE5612517EBE00645D88 /* protocol.defs in Sources */,
-				6EBEC7E51BBDD30C009B1596 /* firehose.defs in Sources */,
-				6EBEC7E81BBDD324009B1596 /* firehose_reply.defs in Sources */,
-				E49F2423125D3C960057C971 /* resolver.c in Sources */,
-				E44EBE5712517EBE00645D88 /* init.c in Sources */,
-				E4EC121E12514715000DDBD1 /* object.c in Sources */,
-				E4FC3267145F46C9002FBDDB /* object.m in Sources */,
-				E43A72851AF85BCC00BAA921 /* block.cpp in Sources */,
-				6EF2CAAE1C8899EA001ABE83 /* lock.c in Sources */,
-				E4EC121B12514715000DDBD1 /* semaphore.c in Sources */,
-				E4EC121C12514715000DDBD1 /* once.c in Sources */,
-				E4EC121A12514715000DDBD1 /* queue.c in Sources */,
-				E4EC121D12514715000DDBD1 /* apply.c in Sources */,
-				E4EC122012514715000DDBD1 /* source.c in Sources */,
-				6E4BACC31D48A42100B562AE /* mach.c in Sources */,
-				6EA962991D48622800759D53 /* event.c in Sources */,
-				6EA962A11D48625100759D53 /* event_kevent.c in Sources */,
-				6E4BACF71D49A04700B562AE /* event_epoll.c in Sources */,
-				E44A8E6D1805C3E0009FFDB6 /* voucher.c in Sources */,
-				6ED64B411BBD898400C35F4D /* firehose_buffer.c in Sources */,
-				E4EC122412514715000DDBD1 /* io.c in Sources */,
-				E4EC122312514715000DDBD1 /* data.c in Sources */,
-				E420867216027AE500EEE210 /* data.m in Sources */,
-				C93D6167143E190F00EB9023 /* transform.c in Sources */,
-				E4EC122112514715000DDBD1 /* time.c in Sources */,
-				2BBF5A66154B64F5002B20F9 /* allocator.c in Sources */,
-				E4EC121F12514715000DDBD1 /* benchmark.c in Sources */,
 				6E9956041C3B219B0071D40C /* venture.c in Sources */,
+				6EBEC7E51BBDD30C009B1596 /* firehose.defs in Sources */,
+				6ED64B411BBD898400C35F4D /* firehose_buffer.c in Sources */,
+				6EA962A11D48625100759D53 /* event_kevent.c in Sources */,
+				E49F2423125D3C960057C971 /* resolver.c in Sources */,
+				6E4BACC31D48A42100B562AE /* mach.c in Sources */,
+				E44EBE5712517EBE00645D88 /* init.c in Sources */,
+				E4EC121A12514715000DDBD1 /* queue.c in Sources */,
+				E4EC121B12514715000DDBD1 /* semaphore.c in Sources */,
+				6EF2CAAE1C8899EA001ABE83 /* lock.c in Sources */,
+				6EBEC7E81BBDD324009B1596 /* firehose_reply.defs in Sources */,
+				E4EC121C12514715000DDBD1 /* once.c in Sources */,
+				E4EC121D12514715000DDBD1 /* apply.c in Sources */,
+				E4EC121E12514715000DDBD1 /* object.c in Sources */,
+				E4EC121F12514715000DDBD1 /* benchmark.c in Sources */,
+				6E4BACF71D49A04700B562AE /* event_epoll.c in Sources */,
+				E4EC122012514715000DDBD1 /* source.c in Sources */,
+				E4EC122112514715000DDBD1 /* time.c in Sources */,
+				E4EC122312514715000DDBD1 /* data.c in Sources */,
+				E4EC122412514715000DDBD1 /* io.c in Sources */,
+				E43A72851AF85BCC00BAA921 /* block.cpp in Sources */,
+				6EA962991D48622800759D53 /* event.c in Sources */,
+				C93D6167143E190F00EB9023 /* transform.c in Sources */,
+				E4FC3267145F46C9002FBDDB /* object.m in Sources */,
+				2BBF5A66154B64F5002B20F9 /* allocator.c in Sources */,
+				E420867216027AE500EEE210 /* data.m in Sources */,
+				E44A8E6D1805C3E0009FFDB6 /* voucher.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2583,11 +2439,6 @@
 			target = E4EC121612514715000DDBD1 /* libdispatch mp resolved */;
 			targetProxy = E47D6ECC125FEBA10070D91C /* PBXContainerItemProxy */;
 		};
-		E49BB6F81E7074C100868613 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = E49BB6CE1E70748100868613 /* libdispatch alt resolved */;
-			targetProxy = E49BB6F71E7074C100868613 /* PBXContainerItemProxy */;
-		};
 		E4B515DB164B317700E003AF /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = E4B51595164B2DA300E003AF /* libdispatch introspection */;
@@ -2708,6 +2559,7 @@
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = C00B0E121C5AEBF7000330B3 /* libdispatch-dyld-stub.xcconfig */;
 			buildSettings = {
+				PRODUCT_NAME = "$(PRODUCT_NAME)";
 			};
 			name = Release;
 		};
@@ -2715,6 +2567,7 @@
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = C00B0E121C5AEBF7000330B3 /* libdispatch-dyld-stub.xcconfig */;
 			buildSettings = {
+				PRODUCT_NAME = "$(PRODUCT_NAME)";
 			};
 			name = Debug;
 		};
@@ -2722,6 +2575,7 @@
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = C01866BE1C59735B0040FC07 /* libdispatch-mp-static.xcconfig */;
 			buildSettings = {
+				PRODUCT_NAME = "$(PRODUCT_NAME)";
 			};
 			name = Release;
 		};
@@ -2729,6 +2583,7 @@
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = C01866BE1C59735B0040FC07 /* libdispatch-mp-static.xcconfig */;
 			buildSettings = {
+				PRODUCT_NAME = "$(PRODUCT_NAME)";
 			};
 			name = Debug;
 		};
@@ -2758,22 +2613,6 @@
 			};
 			name = Debug;
 		};
-		E49BB6F01E70748100868613 /* Release */ = {
-			isa = XCBuildConfiguration;
-			baseConfigurationReference = E40041A9125D70590022B135 /* libdispatch-resolved.xcconfig */;
-			buildSettings = {
-				DISPATCH_RESOLVED_VARIANT = alt;
-			};
-			name = Release;
-		};
-		E49BB6F11E70748100868613 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			baseConfigurationReference = E40041A9125D70590022B135 /* libdispatch-resolved.xcconfig */;
-			buildSettings = {
-				DISPATCH_RESOLVED_VARIANT = alt;
-			};
-			name = Debug;
-		};
 		E49F24D9125D57FA0057C971 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
@@ -2787,7 +2626,6 @@
 		E49F24DA125D57FA0057C971 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ONLY_ACTIVE_ARCH = YES;
 				WARNING_CFLAGS = (
 					"-Weverything",
 					"$(inherited)",
@@ -2975,15 +2813,6 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
-		E49BB6EF1E70748100868613 /* Build configuration list for PBXNativeTarget "libdispatch alt resolved" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				E49BB6F01E70748100868613 /* Release */,
-				E49BB6F11E70748100868613 /* Debug */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
 		E49F24D8125D57FA0057C971 /* Build configuration list for PBXNativeTarget "libdispatch no resolver" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
diff --git a/man/dispatch_queue_create.3 b/man/dispatch_queue_create.3
index 833e564..f3c3051 100644
--- a/man/dispatch_queue_create.3
+++ b/man/dispatch_queue_create.3
@@ -72,8 +72,7 @@
 By convention, clients should pass a reverse DNS style label. For example:
 .Pp
 .Bd -literal -offset indent
-my_queue = dispatch_queue_create("com.example.subsystem.taskXYZ",
-				 DISPATCH_QUEUE_SERIAL);
+my_queue = dispatch_queue_create("com.example.subsystem.taskXYZ", NULL);
 .Ed
 .Pp
 The
diff --git a/os/firehose_buffer_private.h b/os/firehose_buffer_private.h
index d131d6d..29b80c3 100644
--- a/os/firehose_buffer_private.h
+++ b/os/firehose_buffer_private.h
@@ -31,7 +31,7 @@
 #include <dispatch/dispatch.h>
 #endif
 
-#define OS_FIREHOSE_SPI_VERSION 20170222
+#define OS_FIREHOSE_SPI_VERSION 20160318
 
 /*!
  * @group Firehose SPI
diff --git a/os/firehose_server_private.h b/os/firehose_server_private.h
index fc352da..441bb52 100644
--- a/os/firehose_server_private.h
+++ b/os/firehose_server_private.h
@@ -228,23 +228,6 @@
 firehose_client_set_context(firehose_client_t client, void *ctxt);
 
 /*!
- * @function firehose_client_initiate_quarantine
- *
- * @abstract
- * Starts the procedure to move the given client to the high volume quarantine
- *
- * @discussion
- * When the client is in the high volume quarantine, their firehose chunks
- * have the fcp_quarantined bit set to 1.
- *
- * @param client
- * The specified client.
- */
-OS_NOTHROW OS_NONNULL1
-void
-firehose_client_initiate_quarantine(firehose_client_t client);
-
-/*!
  * @function firehose_client_metadata_stream_peek
  *
  * @abstract
@@ -378,36 +361,6 @@
 dispatch_queue_t
 firehose_server_copy_queue(firehose_server_queue_t which);
 
-/*!
- * @function firehose_server_quarantined_suspend
- *
- * @abstract
- * Suspends processing of quarantined clients until
- * firehose_server_quarantined_resume() is called for the same queue.
- *
- * @discussion
- * Suspending processing of quarantined clients causes firehose_snapshot()
- * to block until the processing is enabled again.
- *
- * However if this is used to pace the processing, it is a good idea to disable
- * this pacing until the snapshot has completed.
- *
- * Similarly, quarantine suspension must be off during shutdown.
- */
-OS_NOTHROW
-void
-firehose_server_quarantined_suspend(firehose_server_queue_t q);
-
-/*!
- * @function firehose_server_quarantined_resume
- *
- * @abstract
- * Resumes processing of quarantined clients.
- */
-OS_NOTHROW
-void
-firehose_server_quarantined_resume(firehose_server_queue_t q);
-
 #pragma mark - Firehose Snapshot
 
 /*!
diff --git a/os/object_private.h b/os/object_private.h
index 215c3d1..2f8cdf4 100644
--- a/os/object_private.h
+++ b/os/object_private.h
@@ -36,9 +36,7 @@
 #define OS_OBJECT_NONNULL __attribute__((__nonnull__))
 #define OS_OBJECT_WARN_RESULT __attribute__((__warn_unused_result__))
 #define OS_OBJECT_MALLOC __attribute__((__malloc__))
-#ifndef OS_OBJECT_EXPORT
 #define OS_OBJECT_EXPORT extern __attribute__((visibility("default")))
-#endif
 #else
 /*! @parseOnly */
 #define OS_OBJECT_NOTHROW
@@ -48,11 +46,8 @@
 #define OS_OBJECT_WARN_RESULT
 /*! @parseOnly */
 #define OS_OBJECT_MALLOC
-#ifndef OS_OBJECT_EXPORT
-/*! @parseOnly */
 #define OS_OBJECT_EXPORT extern
 #endif
-#endif
 
 #if OS_OBJECT_USE_OBJC && __has_feature(objc_arc)
 #define _OS_OBJECT_OBJC_ARC 1
@@ -184,18 +179,6 @@
 void
 _os_object_release_internal(_os_object_t object);
 
-API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
-OS_OBJECT_EXPORT OS_OBJECT_NONNULL OS_OBJECT_NOTHROW
-OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
-_os_object_t
-_os_object_retain_internal_n(_os_object_t object, uint16_t n);
-
-API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
-OS_OBJECT_EXPORT OS_OBJECT_NONNULL OS_OBJECT_NOTHROW
-OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
-void
-_os_object_release_internal_n(_os_object_t object, uint16_t n);
-
 #endif // !_OS_OBJECT_OBJC_ARC
 
 __END_DECLS
diff --git a/os/voucher_activity_private.h b/os/voucher_activity_private.h
index 8ce0ef5..28effc9 100644
--- a/os/voucher_activity_private.h
+++ b/os/voucher_activity_private.h
@@ -282,13 +282,12 @@
 		const void *privdata, size_t privlen);
 
 typedef const struct voucher_activity_hooks_s {
-#define VOUCHER_ACTIVITY_HOOKS_VERSION     5
+#define VOUCHER_ACTIVITY_HOOKS_VERSION     4
 	long vah_version;
 	mach_port_t (*vah_get_logd_port)(void);
 	dispatch_mach_handler_function_t vah_debug_channel_handler;
 	kern_return_t (*vah_get_reconnect_info)(mach_vm_address_t *, mach_vm_size_t *);
 	void (*vah_metadata_init)(void *metadata_buffer, size_t size);
-	void (*vah_quarantine_starts)(void);
 } *voucher_activity_hooks_t;
 
 /*!
diff --git a/private/mach_private.h b/private/mach_private.h
index bc53223..6ca891d 100644
--- a/private/mach_private.h
+++ b/private/mach_private.h
@@ -114,9 +114,7 @@
  * A SIGTERM signal has been received. This notification is delivered at most
  * once during the lifetime of the channel. This event is sent only for XPC
  * channels (i.e. channels that were created by calling
- * dispatch_mach_create_4libxpc()) and only if the
- * dmxh_enable_sigterm_notification function in the XPC hooks structure is not
- * set or it returned true when it was called at channel activation time.
+ * dispatch_mach_create_4libxpc()).
  *
  * @const DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED
  * The channel has been disconnected by a call to dispatch_mach_reconnect() or
@@ -813,7 +811,7 @@
 
 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
 typedef const struct dispatch_mach_xpc_hooks_s {
-#define DISPATCH_MACH_XPC_HOOKS_VERSION     3
+#define DISPATCH_MACH_XPC_HOOKS_VERSION     2
 	unsigned long version;
 
 	/* Fields available in version 1. */
@@ -829,8 +827,8 @@
 	 * throw an exception.
 	 */
 	bool (* _Nonnull dmxh_direct_message_handler)(void *_Nullable context,
-			dispatch_mach_reason_t reason, dispatch_mach_msg_t message,
-			mach_error_t error);
+		dispatch_mach_reason_t reason, dispatch_mach_msg_t message,
+		mach_error_t error);
 
 	/* Fields available in version 2. */
 
@@ -846,7 +844,7 @@
 	 * other code.
 	 */
 	dispatch_queue_t _Nullable (*_Nonnull dmxh_msg_context_reply_queue)(
-			void *_Nonnull msg_context);
+		void *_Nonnull msg_context);
 
 	/*
 	 * Called when a reply to a message sent by
@@ -863,15 +861,6 @@
 	 * details.
 	 */
 	dispatch_mach_async_reply_callback_t dmxh_async_reply_handler;
-
-	/* Fields available in version 3. */
-	/**
-	 * Called once when the Mach channel has been activated. If this function
-	 * returns true, a DISPATCH_MACH_SIGTERM_RECEIVED notification will be
-	 * delivered to the channel's event handler when a SIGTERM is received.
-	 */
-	bool (* _Nullable dmxh_enable_sigterm_notification)(
-			void *_Nullable context);
 } *dispatch_mach_xpc_hooks_t;
 
 #define DISPATCH_MACH_XPC_SUPPORTS_ASYNC_REPLIES(hooks) ((hooks)->version >= 2)
diff --git a/private/private.h b/private/private.h
index cc9d578..82da15e 100644
--- a/private/private.h
+++ b/private/private.h
@@ -66,7 +66,7 @@
 #endif /* !__DISPATCH_BUILDING_DISPATCH__ */
 
 // <rdar://problem/9627726> Check that public and private dispatch headers match
-#if DISPATCH_API_VERSION != 20170124 // Keep in sync with <dispatch/dispatch.h>
+#if DISPATCH_API_VERSION != 20160831 // Keep in sync with <dispatch/dispatch.h>
 #error "Dispatch header mismatch between /usr/include and /usr/local/include"
 #endif
 
@@ -214,16 +214,6 @@
 DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NOTHROW
 mach_port_t
 _dispatch_runloop_root_queue_get_port_4CF(dispatch_queue_t queue);
-
-#ifdef __BLOCKS__
-API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
-DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
-DISPATCH_NOTHROW
-dispatch_queue_t
-_dispatch_network_root_queue_create_4NW(const char *_Nullable label,
-		const pthread_attr_t *_Nullable attrs,
-		dispatch_block_t _Nullable configure);
-#endif
 #endif
 
 API_AVAILABLE(macos(10.9), ios(7.0))
@@ -252,11 +242,6 @@
 
 #endif /* DISPATCH_COCOA_COMPAT */
 
-API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
-DISPATCH_EXPORT DISPATCH_NOTHROW
-void
-_dispatch_poll_for_events_4launchd(void);
-
 __END_DECLS
 
 DISPATCH_ASSUME_NONNULL_END
diff --git a/private/queue_private.h b/private/queue_private.h
index 98c7f5e..14d6477 100644
--- a/private/queue_private.h
+++ b/private/queue_private.h
@@ -278,12 +278,11 @@
 
 /*!
  * @constant DISPATCH_APPLY_CURRENT_ROOT_QUEUE
- *
- * @discussion
- * This constant is deprecated, please use DISPATCH_APPLY_AUTO.
- *
- * DISPATCH_APPLY_AUTO also selects the current pthread root queue if
- * applicable.
+ * @discussion Constant to pass to the dispatch_apply() and dispatch_apply_f()
+ * functions to indicate that the root queue for the current thread should be
+ * used (i.e. one of the global concurrent queues or a queue created with
+ * dispatch_pthread_root_queue_create()). If there is no such queue, the
+ * default priority global concurrent queue will be used.
  */
 #define DISPATCH_APPLY_CURRENT_ROOT_QUEUE ((dispatch_queue_t _Nonnull)0)
 
diff --git a/private/source_private.h b/private/source_private.h
index 019f648..f01287b 100644
--- a/private/source_private.h
+++ b/private/source_private.h
@@ -165,6 +165,15 @@
 	DISPATCH_SOCK_NOTIFY_ACK = 0x00004000,
 };
 
+/*!
+ * @enum dispatch_source_nw_channel_flags_t
+ *
+ * @constant DISPATCH_NW_CHANNEL_FLOW_ADV_UPDATE
+ * Received network channel flow advisory.
+ */
+enum {
+	DISPATCH_NW_CHANNEL_FLOW_ADV_UPDATE = 0x00000001,
+};
 
 /*!
  * @enum dispatch_source_vfs_flags_t
@@ -332,16 +341,11 @@
  *
  * @constant DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL
  * The memory of the process has reached 100% of its high watermark limit.
- *
- * @constant DISPATCH_MEMORYPRESSURE_MSL_STATUS
- * Mask for enabling/disabling malloc stack logging.
  */
 enum {
-	DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) = 0x10,
+	DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.10), tvos(10.10), watchos(3.0)) = 0x10,
 
-	DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) = 0x20,
-	
-	DISPATCH_MEMORYPRESSURE_MSL_STATUS DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) = 0xf0000000,
+	DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.10), tvos(10.10), watchos(3.0)) = 0x20,
 };
 
 /*!
diff --git a/src/apply.c b/src/apply.c
index 9d64522..40e6f32 100644
--- a/src/apply.c
+++ b/src/apply.c
@@ -35,7 +35,7 @@
 	size_t idx, done = 0;
 
 	idx = os_atomic_inc_orig2o(da, da_index, acquire);
-	if (unlikely(idx >= iter)) goto out;
+	if (!fastpath(idx < iter)) goto out;
 
 	// da_dc is only safe to access once the 'index lock' has been acquired
 	dispatch_apply_function_t const func = (void *)da->da_dc->dc_func;
@@ -67,7 +67,7 @@
 			done++;
 			idx = os_atomic_inc_orig2o(da, da_index, relaxed);
 		});
-	} while (likely(idx < iter));
+	} while (fastpath(idx < iter));
 
 	if (invoke_flags & DISPATCH_APPLY_INVOKE_REDIRECT) {
 		_dispatch_reset_basepri(old_dbp);
@@ -124,7 +124,7 @@
 
 	while (dq && !qaf) {
 		qaf = _dispatch_queue_autorelease_frequency(dq);
-		dq = dq->do_targetq;
+		dq = slowpath(dq->do_targetq);
 	}
 	return qaf;
 }
@@ -198,13 +198,13 @@
 	do {
 		int32_t width = _dispatch_queue_try_reserve_apply_width(rq, da_width);
 
-		if (unlikely(da_width > width)) {
+		if (slowpath(da_width > width)) {
 			int32_t excess = da_width - width;
 			for (tq = dq; tq != rq; tq = tq->do_targetq) {
 				_dispatch_queue_relinquish_width(tq, excess);
 			}
 			da_width -= excess;
-			if (unlikely(!da_width)) {
+			if (slowpath(!da_width)) {
 				return _dispatch_apply_serial(da);
 			}
 			da->da_thr_cnt -= excess;
@@ -216,41 +216,22 @@
 			da->da_flags = _dispatch_queue_autorelease_frequency(dq);
 		}
 		rq = rq->do_targetq;
-	} while (unlikely(rq->do_targetq));
+	} while (slowpath(rq->do_targetq));
 	_dispatch_apply_f2(rq, da, _dispatch_apply_redirect_invoke);
 	do {
 		_dispatch_queue_relinquish_width(dq, da_width);
 		dq = dq->do_targetq;
-	} while (unlikely(dq->do_targetq));
+	} while (slowpath(dq->do_targetq));
 }
 
 #define DISPATCH_APPLY_MAX UINT16_MAX // must be < sqrt(SIZE_MAX)
 
-DISPATCH_ALWAYS_INLINE
-static inline dispatch_queue_t
-_dispatch_apply_root_queue(dispatch_queue_t dq)
-{
-	if (dq) {
-		while (unlikely(dq->do_targetq)) {
-			dq = dq->do_targetq;
-		}
-		// if the current root queue is a pthread root queue, select it
-		if (!_dispatch_priority_qos(dq->dq_priority)) {
-			return dq;
-		}
-	}
-
-	pthread_priority_t pp = _dispatch_get_priority();
-	dispatch_qos_t qos = _dispatch_qos_from_pp(pp);
-	return _dispatch_get_root_queue(qos ? qos : DISPATCH_QOS_DEFAULT, false);
-}
-
 DISPATCH_NOINLINE
 void
 dispatch_apply_f(size_t iterations, dispatch_queue_t dq, void *ctxt,
 		void (*func)(void *, size_t))
 {
-	if (unlikely(iterations == 0)) {
+	if (slowpath(iterations == 0)) {
 		return;
 	}
 	int32_t thr_cnt = (int32_t)dispatch_hw_config(active_cpus);
@@ -259,7 +240,7 @@
 	size_t nested = dtctxt ? dtctxt->dtc_apply_nesting : 0;
 	dispatch_queue_t old_dq = _dispatch_queue_get_current();
 
-	if (likely(!nested)) {
+	if (!slowpath(nested)) {
 		nested = iterations;
 	} else {
 		thr_cnt = nested < (size_t)thr_cnt ? thr_cnt / (int32_t)nested : 1;
@@ -269,8 +250,12 @@
 	if (iterations < (size_t)thr_cnt) {
 		thr_cnt = (int32_t)iterations;
 	}
-	if (likely(dq == DISPATCH_APPLY_AUTO)) {
-		dq = _dispatch_apply_root_queue(old_dq);
+	if (slowpath(dq == DISPATCH_APPLY_CURRENT_ROOT_QUEUE)) {
+		dq = old_dq ? old_dq : _dispatch_get_root_queue(
+				DISPATCH_QOS_DEFAULT, false);
+		while (slowpath(dq->do_targetq)) {
+			dq = dq->do_targetq;
+		}
 	}
 	struct dispatch_continuation_s dc = {
 		.dc_func = (void*)func,
@@ -291,11 +276,11 @@
 #endif
 	da->da_flags = 0;
 
-	if (unlikely(dq->dq_width == 1 || thr_cnt <= 1)) {
+	if (slowpath(dq->dq_width == 1) || slowpath(thr_cnt <= 1)) {
 		return dispatch_sync_f(dq, da, _dispatch_apply_serial);
 	}
-	if (unlikely(dq->do_targetq)) {
-		if (unlikely(dq == old_dq)) {
+	if (slowpath(dq->do_targetq)) {
+		if (slowpath(dq == old_dq)) {
 			return dispatch_sync_f(dq, da, _dispatch_apply_serial);
 		} else {
 			return dispatch_sync_f(dq, da, _dispatch_apply_redirect);
diff --git a/src/block.cpp b/src/block.cpp
index 2a6f007..3060a2a 100644
--- a/src/block.cpp
+++ b/src/block.cpp
@@ -32,8 +32,6 @@
 #include "internal.h"
 }
 
-// NOTE: this file must not contain any atomic operations
-
 #if DISPATCH_DEBUG && DISPATCH_BLOCK_PRIVATE_DATA_DEBUG
 #define _dispatch_block_private_data_debug(msg, ...) \
 		_dispatch_debug("block_private[%p]: " msg, (this), ##__VA_ARGS__)
@@ -85,8 +83,7 @@
 			((void (*)(dispatch_group_t))dispatch_release)(dbpd_group);
 		}
 		if (dbpd_queue) {
-			((void (*)(os_mpsc_queue_t, uint16_t))
-					_os_object_release_internal_n)(dbpd_queue, 2);
+			((void (*)(os_mpsc_queue_t))_os_object_release_internal)(dbpd_queue);
 		}
 		if (dbpd_block) Block_release(dbpd_block);
 		if (dbpd_voucher) voucher_release(dbpd_voucher);
diff --git a/src/data.c b/src/data.c
index 240309f..adcfbb2 100644
--- a/src/data.c
+++ b/src/data.c
@@ -100,22 +100,51 @@
 #define _dispatch_data_release(x) dispatch_release(x)
 #endif
 
+const dispatch_block_t _dispatch_data_destructor_free = ^{
+	DISPATCH_INTERNAL_CRASH(0, "free destructor called");
+};
+
+const dispatch_block_t _dispatch_data_destructor_none = ^{
+	DISPATCH_INTERNAL_CRASH(0, "none destructor called");
+};
+
+#if !HAVE_MACH
+const dispatch_block_t _dispatch_data_destructor_munmap = ^{
+	DISPATCH_INTERNAL_CRASH(0, "munmap destructor called");
+};
+#else
+// _dispatch_data_destructor_munmap is a linker alias to the following
+const dispatch_block_t _dispatch_data_destructor_vm_deallocate = ^{
+	DISPATCH_INTERNAL_CRASH(0, "vmdeallocate destructor called");
+};
+#endif
+
+const dispatch_block_t _dispatch_data_destructor_inline = ^{
+	DISPATCH_INTERNAL_CRASH(0, "inline destructor called");
+};
+
+struct dispatch_data_s _dispatch_data_empty = {
+#if DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
+	.do_vtable = DISPATCH_DATA_EMPTY_CLASS,
+#else
+	DISPATCH_GLOBAL_OBJECT_HEADER(data),
+	.do_next = DISPATCH_OBJECT_LISTLESS,
+#endif
+};
+
 DISPATCH_ALWAYS_INLINE
 static inline dispatch_data_t
 _dispatch_data_alloc(size_t n, size_t extra)
 {
 	dispatch_data_t data;
 	size_t size;
-	size_t base_size;
 
-	if (os_add_overflow(sizeof(struct dispatch_data_s), extra, &base_size)) {
-		return DISPATCH_OUT_OF_MEMORY;
-	}
-	if (os_mul_and_add_overflow(n, sizeof(range_record), base_size, &size)) {
+	if (os_mul_and_add_overflow(n, sizeof(range_record),
+			sizeof(struct dispatch_data_s) + extra, &size)) {
 		return DISPATCH_OUT_OF_MEMORY;
 	}
 
-	data = _dispatch_object_alloc(DISPATCH_DATA_CLASS, size);
+	data = _dispatch_alloc(DISPATCH_DATA_CLASS, size);
 	data->num_records = n;
 #if !DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
 	data->do_targetq = dispatch_get_global_queue(
@@ -163,8 +192,8 @@
 }
 
 void
-_dispatch_data_init_with_bytes(dispatch_data_t data, const void *buffer,
-		size_t size, dispatch_block_t destructor)
+dispatch_data_init(dispatch_data_t data, const void *buffer, size_t size,
+		dispatch_block_t destructor)
 {
 	if (!buffer || !size) {
 		if (destructor) {
@@ -255,7 +284,7 @@
 }
 
 void
-_dispatch_data_dispose(dispatch_data_t dd, DISPATCH_UNUSED bool *allow_free)
+_dispatch_data_dispose(dispatch_data_t dd)
 {
 	if (_dispatch_data_leaf(dd)) {
 		_dispatch_data_destroy_buffer(dd->buf, dd->size, dd->do_targetq,
@@ -269,18 +298,6 @@
 	}
 }
 
-void
-_dispatch_data_set_target_queue(dispatch_data_t dd, dispatch_queue_t tq)
-{
-#if DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
-	_dispatch_retain(tq);
-	tq = os_atomic_xchg2o(dd, do_targetq, tq, release);
-	if (tq) _dispatch_release(tq);
-#else
-	_dispatch_object_set_target_queue_inline(dd, tq);
-#endif
-}
-
 size_t
 _dispatch_data_debug(dispatch_data_t dd, char* buf, size_t bufsiz)
 {
diff --git a/src/data.m b/src/data.m
index 1d024ff..9971f18 100644
--- a/src/data.m
+++ b/src/data.m
@@ -28,8 +28,6 @@
 
 #include <Foundation/NSString.h>
 
-// NOTE: this file must not contain any atomic operations
-
 @interface DISPATCH_CLASS(data) () <DISPATCH_CLASS(data)>
 @property (readonly,nonatomic) NSUInteger length;
 @property (readonly,nonatomic) const void *bytes NS_RETURNS_INNER_POINTER;
@@ -68,26 +66,29 @@
 	} else {
 		destructor = DISPATCH_DATA_DESTRUCTOR_NONE;
 	}
-	_dispatch_data_init_with_bytes(self, bytes, length, destructor);
+	dispatch_data_init(self, bytes, length, destructor);
 	return self;
 }
 
+#define _dispatch_data_objc_dispose(selector) \
+	struct dispatch_data_s *dd = (void*)self; \
+	_dispatch_data_dispose(self); \
+	dispatch_queue_t tq = dd->do_targetq; \
+	dispatch_function_t func = dd->finalizer; \
+	void *ctxt = dd->ctxt; \
+	[super selector]; \
+	if (func && ctxt) { \
+		if (!tq) { \
+			 tq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);\
+		} \
+		dispatch_async_f(tq, ctxt, func); \
+	} \
+	if (tq) { \
+		_os_object_release_internal((_os_object_t)tq); \
+	}
+
 - (void)dealloc {
-	struct dispatch_data_s *dd = (void*)self;
-	_dispatch_data_dispose(self, NULL);
-	dispatch_queue_t tq = dd->do_targetq;
-	dispatch_function_t func = dd->finalizer;
-	void *ctxt = dd->ctxt;
-	[super dealloc];
-	if (func && ctxt) {
-		if (!tq) {
-			 tq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
-		}
-		dispatch_async_f(tq, ctxt, func);
-	}
-	if (tq) {
-		_os_object_release_internal((_os_object_t)tq);
-	}
+	_dispatch_data_objc_dispose(dealloc);
 }
 
 - (BOOL)_bytesAreVM {
@@ -112,7 +113,10 @@
 
 - (void)_setTargetQueue:(dispatch_queue_t)queue {
 	struct dispatch_data_s *dd = (void*)self;
-	return _dispatch_data_set_target_queue(dd, queue);
+	_os_object_retain_internal((_os_object_t)queue);
+	dispatch_queue_t prev;
+	prev = os_atomic_xchg2o(dd, do_targetq, queue, release);
+	if (prev) _os_object_release_internal((_os_object_t)prev);
 }
 
 - (NSString *)debugDescription {
diff --git a/src/data_internal.h b/src/data_internal.h
index 19fc3d9..bbef21e 100644
--- a/src/data_internal.h
+++ b/src/data_internal.h
@@ -100,13 +100,12 @@
 	dispatch_transform_t encode;
 };
 
-void _dispatch_data_init_with_bytes(dispatch_data_t data, const void *buffer,
-		size_t size, dispatch_block_t destructor);
-void _dispatch_data_dispose(dispatch_data_t data, bool *allow_free);
-void _dispatch_data_set_target_queue(struct dispatch_data_s *dd,
-		dispatch_queue_t tq);
+void dispatch_data_init(dispatch_data_t data, const void *buffer, size_t size,
+		dispatch_block_t destructor);
+void _dispatch_data_dispose(dispatch_data_t data);
 size_t _dispatch_data_debug(dispatch_data_t data, char* buf, size_t bufsiz);
-const void* _dispatch_data_get_flattened_bytes(struct dispatch_data_s *dd);
+const void*
+_dispatch_data_get_flattened_bytes(struct dispatch_data_s *dd);
 
 #if !defined(__cplusplus)
 extern const dispatch_block_t _dispatch_data_destructor_inline;
diff --git a/src/event/event.c b/src/event/event.c
index 34abbf0..2a8a8c3 100644
--- a/src/event/event.c
+++ b/src/event/event.c
@@ -46,7 +46,6 @@
 		du = _dispatch_unote_linkage_get_unote(dul)._du;
 	}
 	du->du_type = dst;
-	du->du_can_be_wlh = dst->dst_per_trigger_qos;
 	du->du_ident = (uint32_t)handle;
 	du->du_filter = dst->dst_filter;
 	du->du_fflags = (typeof(du->du_fflags))mask;
@@ -109,13 +108,8 @@
 	}
 #endif
 	if (du._du->du_is_timer) {
-		if (unlikely(du._dt->dt_heap_entry[DTH_TARGET_ID] != DTH_INVALID_ID ||
-				du._dt->dt_heap_entry[DTH_DEADLINE_ID] != DTH_INVALID_ID)) {
-			DISPATCH_INTERNAL_CRASH(0, "Disposing of timer still in its heap");
-		}
-		if (unlikely(du._dt->dt_pending_config)) {
+		if (du._dt->dt_pending_config) {
 			free(du._dt->dt_pending_config);
-			du._dt->dt_pending_config = NULL;
 		}
 	} else if (!du._du->du_is_direct) {
 		ptr = _dispatch_unote_get_linkage(du);
@@ -286,8 +280,6 @@
 		du._dt->dt_timer.target = UINT64_MAX;
 		du._dt->dt_timer.deadline = UINT64_MAX;
 		du._dt->dt_timer.interval = UINT64_MAX;
-		du._dt->dt_heap_entry[DTH_TARGET_ID] = DTH_INVALID_ID;
-		du._dt->dt_heap_entry[DTH_DEADLINE_ID] = DTH_INVALID_ID;
 	}
 	return du;
 }
diff --git a/src/event/event_config.h b/src/event/event_config.h
index 2ac3c42..7f7761c 100644
--- a/src/event/event_config.h
+++ b/src/event/event_config.h
@@ -35,17 +35,12 @@
 
 #if DISPATCH_DEBUG
 #define DISPATCH_MGR_QUEUE_DEBUG 1
-#define DISPATCH_WLH_DEBUG 1
 #endif
 
 #ifndef DISPATCH_MGR_QUEUE_DEBUG
 #define DISPATCH_MGR_QUEUE_DEBUG 0
 #endif
 
-#ifndef DISPATCH_WLH_DEBUG
-#define DISPATCH_WLH_DEBUG 0
-#endif
-
 #ifndef DISPATCH_MACHPORT_DEBUG
 #define DISPATCH_MACHPORT_DEBUG 0
 #endif
@@ -105,6 +100,31 @@
 #	ifndef VQ_DESIRED_DISK
 #	undef HAVE_DECL_VQ_DESIRED_DISK
 #	endif // VQ_DESIRED_DISK
+
+#	ifndef NOTE_MEMORYSTATUS_LOW_SWAP
+#	define NOTE_MEMORYSTATUS_LOW_SWAP 0x8
+#	endif
+
+#	if !defined(NOTE_MEMORYSTATUS_PROC_LIMIT_WARN) || \
+		!DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
+#	undef NOTE_MEMORYSTATUS_PROC_LIMIT_WARN
+#	define NOTE_MEMORYSTATUS_PROC_LIMIT_WARN 0
+#	endif // NOTE_MEMORYSTATUS_PROC_LIMIT_WARN
+
+#	if !defined(NOTE_MEMORYSTATUS_PROC_LIMIT_CRITICAL) || \
+		!DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
+#	undef NOTE_MEMORYSTATUS_PROC_LIMIT_CRITICAL
+#	define NOTE_MEMORYSTATUS_PROC_LIMIT_CRITICAL 0
+#	endif // NOTE_MEMORYSTATUS_PROC_LIMIT_CRITICAL
+
+#	ifndef DISPATCH_KEVENT_TREAT_ENOENT_AS_EINPROGRESS
+#	if TARGET_OS_MAC && !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
+	// deferred delete can return bogus ENOENTs on older kernels
+#	define DISPATCH_KEVENT_TREAT_ENOENT_AS_EINPROGRESS 1
+#	else
+#	define DISPATCH_KEVENT_TREAT_ENOENT_AS_EINPROGRESS 0
+#	endif
+#	endif
 #else // DISPATCH_EVENT_BACKEND_KEVENT
 #	define EV_ADD					0x0001
 #	define EV_DELETE				0x0002
@@ -175,14 +195,6 @@
 #	define MACH_MSG_PRIORITY_UNSPECIFIED ((mach_msg_priority_t)0)
 #	endif // MACH_SEND_OVERRIDE
 
-#	ifndef MACH_SEND_SYNC_OVERRIDE
-#	define MACH_SEND_SYNC_OVERRIDE 0x00100000
-#	endif // MACH_SEND_SYNC_OVERRIDE
-
-#	ifndef MACH_RCV_SYNC_WAIT
-#	define MACH_RCV_SYNC_WAIT 0x00004000
-#	endif // MACH_RCV_SYNC_WAIT
-
 #	define DISPATCH_MACH_TRAILER_SIZE sizeof(dispatch_mach_trailer_t)
 #	define DISPATCH_MACH_RCV_TRAILER MACH_RCV_TRAILER_CTX
 #	define DISPATCH_MACH_RCV_OPTIONS ( \
diff --git a/src/event/event_epoll.c b/src/event/event_epoll.c
index 68140d5..647552f 100644
--- a/src/event/event_epoll.c
+++ b/src/event/event_epoll.c
@@ -211,8 +211,8 @@
 }
 
 bool
-_dispatch_unote_register(dispatch_unote_t du,
-		DISPATCH_UNUSED dispatch_wlh_t wlh, dispatch_priority_t pri)
+_dispatch_unote_register(dispatch_unote_t du, dispatch_wlh_t wlh,
+		dispatch_priority_t pri)
 {
 	struct dispatch_muxnote_bucket_s *dmb;
 	dispatch_muxnote_t dmn;
@@ -225,7 +225,7 @@
 	case DISPATCH_EVFILT_CUSTOM_ADD:
 	case DISPATCH_EVFILT_CUSTOM_OR:
 	case DISPATCH_EVFILT_CUSTOM_REPLACE:
-		du._du->du_wlh = DISPATCH_WLH_ANON;
+		du._du->du_wlh = wlh;
 		return true;
 	case EVFILT_WRITE:
 		events |= EPOLLOUT;
@@ -268,8 +268,7 @@
 			TAILQ_INSERT_TAIL(&dmn->dmn_readers_head, dul, du_link);
 		}
 		dul->du_muxnote = dmn;
-		dispatch_assert(du._du->du_wlh == NULL);
-		du._du->du_wlh = DISPATCH_WLH_ANON;
+		du._du->du_wlh = DISPATCH_WLH_GLOBAL;
 	}
 	return dmn != NULL;
 }
@@ -322,7 +321,6 @@
 			TAILQ_REMOVE(_dispatch_unote_muxnote_bucket(du), dmn, dmn_list);
 			_dispatch_muxnote_dispose(dmn);
 		}
-		dispatch_assert(du._du->du_wlh == DISPATCH_WLH_ANON);
 		du._du->du_wlh = NULL;
 	}
 	return true;
@@ -420,6 +418,11 @@
 {
 }
 
+void
+_dispatch_event_loop_init(void)
+{
+}
+
 static void
 _dispatch_epoll_init(void *context DISPATCH_UNUSED)
 {
@@ -456,7 +459,7 @@
 
 void
 _dispatch_event_loop_poke(dispatch_wlh_t wlh DISPATCH_UNUSED,
-		uint64_t dq_state DISPATCH_UNUSED, uint32_t flags DISPATCH_UNUSED)
+		dispatch_priority_t pri DISPATCH_UNUSED, uint32_t flags DISPATCH_UNUSED)
 {
 	dispatch_once_f(&epoll_init_pred, NULL, _dispatch_epoll_init);
 	dispatch_assume_zero(eventfd_write(_dispatch_eventfd, 1));
@@ -578,40 +581,4 @@
 	}
 }
 
-void
-_dispatch_event_loop_wake_owner(dispatch_sync_context_t dsc,
-		dispatch_wlh_t wlh, uint64_t old_state, uint64_t new_state)
-{
-	(void)dsc; (void)wlh; (void)old_state; (void)new_state;
-}
-
-void
-_dispatch_event_loop_wait_for_ownership(dispatch_sync_context_t dsc)
-{
-	if (dsc->dsc_release_storage) {
-		_dispatch_queue_release_storage(dsc->dc_data);
-	}
-}
-
-void
-_dispatch_event_loop_end_ownership(dispatch_wlh_t wlh, uint64_t old_state,
-		uint64_t new_state, uint32_t flags)
-{
-	(void)wlh; (void)old_state; (void)new_state; (void)flags;
-}
-
-#if DISPATCH_WLH_DEBUG
-void
-_dispatch_event_loop_assert_not_owned(dispatch_wlh_t wlh)
-{
-	(void)wlh;
-}
-#endif
-
-void
-_dispatch_event_loop_leave_immediate(dispatch_wlh_t wlh, uint64_t dq_state)
-{
-	(void)wlh; (void)dq_state;
-}
-
 #endif // DISPATCH_EVENT_BACKEND_EPOLL
diff --git a/src/event/event_internal.h b/src/event/event_internal.h
index 842c4ee..c84b353 100644
--- a/src/event/event_internal.h
+++ b/src/event/event_internal.h
@@ -29,10 +29,9 @@
 
 #include "event_config.h"
 
-struct dispatch_sync_context_s;
 typedef struct dispatch_wlh_s *dispatch_wlh_t; // opaque handle
-#define DISPATCH_WLH_ANON       ((dispatch_wlh_t)(void*)(~0ul))
-#define DISPATCH_WLH_MANAGER    ((dispatch_wlh_t)(void*)(~2ul))
+#define DISPATCH_WLH_GLOBAL ((dispatch_wlh_t)(void*)(~0ul))
+#define DISPATCH_WLH_MANAGER ((dispatch_wlh_t)(void*)(~2ul))
 
 #define DISPATCH_UNOTE_DATA_ACTION_SIZE 2
 
@@ -41,17 +40,15 @@
 	uintptr_t du_owner_wref; /* "weak" back reference to the owner object */ \
 	dispatch_wlh_t du_wlh; \
 	uint32_t  du_ident; \
-	int8_t    du_filter; \
+	int16_t   du_filter; \
+	uint8_t   du_data_action : DISPATCH_UNOTE_DATA_ACTION_SIZE; \
+	uint8_t   du_is_direct : 1; \
+	uint8_t   du_is_timer : 1; \
+	uint8_t   du_memorypressure_override : 1; \
+	uint8_t   du_vmpressure_override : 1; \
+	uint8_t   dmr_async_reply : 1; \
+	uint8_t   dmrr_handler_is_block : 1; \
 	os_atomic(bool) dmsr_notification_armed; \
-	uint16_t  du_data_action : DISPATCH_UNOTE_DATA_ACTION_SIZE; \
-	uint16_t  du_is_direct : 1; \
-	uint16_t  du_is_timer : 1; \
-	uint16_t  du_memorypressure_override : 1; \
-	uint16_t  du_vmpressure_override : 1; \
-	uint16_t  du_can_be_wlh : 1; \
-	uint16_t  dmr_async_reply : 1; \
-	uint16_t  dmrr_handler_is_block : 1; \
-	uint16_t  du_unused : 7; \
 	uint32_t  du_fflags; \
 	dispatch_priority_t du_priority
 
@@ -96,7 +93,6 @@
 	uint64_t delay, leeway;
 } dispatch_timer_delay_s;
 
-#define DTH_INVALID_ID  (~0u)
 #define DTH_TARGET_ID   0u
 #define DTH_DEADLINE_ID 1u
 #define DTH_ID_COUNT    2u
@@ -227,11 +223,11 @@
 #define DU_UNREGISTER_ALREADY_DELETED  0x02
 #define DU_UNREGISTER_DISCONNECTED     0x04
 #define DU_UNREGISTER_REPLY_REMOVE     0x08
+#define DU_UNREGISTER_WAKEUP           0x10
 
 typedef struct dispatch_source_type_s {
 	const char *dst_kind;
-	int8_t     dst_filter;
-	uint8_t    dst_per_trigger_qos : 1;
+	int16_t    dst_filter;
 	uint16_t   dst_flags;
 	uint32_t   dst_fflags;
 	uint32_t   dst_mask;
@@ -260,10 +256,14 @@
 extern const dispatch_source_type_s _dispatch_source_type_after;
 
 #if HAVE_MACH
+extern const dispatch_source_type_s _dispatch_source_type_mach_recv_pset;
 extern const dispatch_source_type_s _dispatch_source_type_mach_recv_direct;
+extern const dispatch_source_type_s _dispatch_source_type_mach_recv_direct_pset;
 extern const dispatch_source_type_s _dispatch_mach_type_send;
 extern const dispatch_source_type_s _dispatch_mach_type_recv;
+extern const dispatch_source_type_s _dispatch_mach_type_recv_pset;
 extern const dispatch_source_type_s _dispatch_mach_type_reply;
+extern const dispatch_source_type_s _dispatch_mach_type_reply_pset;
 extern const dispatch_source_type_s _dispatch_xpc_type_sigterm;
 #endif
 
@@ -282,17 +282,13 @@
 #define DISPATCH_DEFERRED_ITEMS_EVENT_COUNT 16
 
 typedef struct dispatch_deferred_items_s {
+#define DISPATCH_PRIORITY_NOSTASH ((dispatch_priority_t)~0u)
+	dispatch_priority_t ddi_stashed_pri;
 	dispatch_queue_t ddi_stashed_rq;
-	dispatch_object_t ddi_stashed_dou;
-	dispatch_qos_t ddi_stashed_qos;
+	dispatch_queue_t ddi_stashed_dq;
 #if DISPATCH_EVENT_BACKEND_KEVENT
-	dispatch_kevent_t ddi_eventlist;
-	uint16_t ddi_nevents;
-	uint16_t ddi_maxevents;
-	bool     ddi_can_stash;
-	uint16_t ddi_wlh_needs_delete : 1;
-	uint16_t ddi_wlh_needs_update : 1;
-	uint16_t ddi_wlh_servicing : 1;
+	int ddi_nevents;
+	dispatch_kevent_s ddi_eventlist[DISPATCH_DEFERRED_ITEMS_EVENT_COUNT];
 #endif
 } dispatch_deferred_items_s, *dispatch_deferred_items_t;
 
@@ -337,6 +333,32 @@
 	_dispatch_thread_setspecific(dispatch_r2k_key, (void *)0);
 }
 
+DISPATCH_ALWAYS_INLINE DISPATCH_PURE
+static inline dispatch_wlh_t
+_dispatch_get_wlh(void)
+{
+	return _dispatch_thread_getspecific(dispatch_wlh_key);
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline void
+_dispatch_set_wlh(dispatch_wlh_t wlh)
+{
+	dispatch_assert(_dispatch_get_wlh() == NULL);
+	dispatch_assert(wlh);
+	_dispatch_debug("wlh[%p]: set current ", wlh);
+	_dispatch_thread_setspecific(dispatch_wlh_key, (void *)wlh);
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline void
+_dispatch_reset_wlh(void)
+{
+	_dispatch_debug("wlh[%p]: clear current ", _dispatch_get_wlh());
+	_dispatch_thread_setspecific(dispatch_wlh_key, NULL);
+	_dispatch_clear_return_to_kernel();
+}
+
 DISPATCH_ALWAYS_INLINE
 static inline bool
 _dispatch_unote_registered(dispatch_unote_t du)
@@ -345,14 +367,6 @@
 }
 
 DISPATCH_ALWAYS_INLINE
-static inline bool
-_dispatch_unote_wlh_changed(dispatch_unote_t du, dispatch_wlh_t expected_wlh)
-{
-	dispatch_wlh_t wlh = du._du->du_wlh;
-	return wlh && wlh != DISPATCH_WLH_ANON && wlh != expected_wlh;
-}
-
-DISPATCH_ALWAYS_INLINE
 static inline dispatch_unote_linkage_t
 _dispatch_unote_get_linkage(dispatch_unote_t du)
 {
@@ -419,29 +433,14 @@
 void _dispatch_unote_dispose(dispatch_unote_t du);
 
 void _dispatch_event_loop_atfork_child(void);
-#define DISPATCH_EVENT_LOOP_CONSUME_2 DISPATCH_WAKEUP_CONSUME_2
-#define DISPATCH_EVENT_LOOP_OVERRIDE  0x80000000
-void _dispatch_event_loop_poke(dispatch_wlh_t wlh, uint64_t dq_state,
+void _dispatch_event_loop_init(void);
+void _dispatch_event_loop_poke(dispatch_wlh_t wlh, dispatch_priority_t pri,
 		uint32_t flags);
-void _dispatch_event_loop_wake_owner(struct dispatch_sync_context_s *dsc,
-		dispatch_wlh_t wlh, uint64_t old_state, uint64_t new_state);
-void _dispatch_event_loop_wait_for_ownership(
-		struct dispatch_sync_context_s *dsc);
-void _dispatch_event_loop_end_ownership(dispatch_wlh_t wlh,
-		uint64_t old_state, uint64_t new_state, uint32_t flags);
-#if DISPATCH_WLH_DEBUG
-void _dispatch_event_loop_assert_not_owned(dispatch_wlh_t wlh);
-#else
-#undef _dispatch_event_loop_assert_not_owned
-#define _dispatch_event_loop_assert_not_owned(wlh) ((void)wlh)
-#endif
-void _dispatch_event_loop_leave_immediate(dispatch_wlh_t wlh, uint64_t dq_state);
+void _dispatch_event_loop_drain(uint32_t flags);
 #if DISPATCH_EVENT_BACKEND_KEVENT
-void _dispatch_event_loop_leave_deferred(dispatch_wlh_t wlh,
-		uint64_t dq_state);
+void _dispatch_event_loop_update(void);
 void _dispatch_event_loop_merge(dispatch_kevent_t events, int nevents);
 #endif
-void _dispatch_event_loop_drain(uint32_t flags);
 void _dispatch_event_loop_timer_arm(unsigned int tidx,
 		dispatch_timer_delay_s range, dispatch_clock_now_cache_t nows);
 void _dispatch_event_loop_timer_delete(unsigned int tidx);
diff --git a/src/event/event_kevent.c b/src/event/event_kevent.c
index c15a397..3275888 100644
--- a/src/event/event_kevent.c
+++ b/src/event/event_kevent.c
@@ -30,7 +30,6 @@
 #endif
 
 #define DISPATCH_KEVENT_MUXED_MARKER  1ul
-#define DISPATCH_MACH_AUDIT_TOKEN_PID (5)
 
 typedef struct dispatch_muxnote_s {
 	TAILQ_ENTRY(dispatch_muxnote_s) dmn_list;
@@ -39,7 +38,6 @@
 	dispatch_kevent_s dmn_kev;
 } *dispatch_muxnote_t;
 
-static bool _dispatch_timers_force_max_leeway;
 static int _dispatch_kq = -1;
 static struct {
 	dispatch_once_t pred;
@@ -79,6 +77,7 @@
 };
 
 static void _dispatch_kevent_timer_drain(dispatch_kevent_t ke);
+static void _dispatch_kevent_poke_drain(dispatch_kevent_t ke);
 
 #pragma mark -
 #pragma mark kevent debug
@@ -221,12 +220,7 @@
 #define _dispatch_kevent_mgr_debug(verb, kev) _dispatch_kevent_debug(verb, kev)
 #else
 #define _dispatch_kevent_mgr_debug(verb, kev) ((void)verb, (void)kev)
-#endif // DISPATCH_MGR_QUEUE_DEBUG
-#if DISPATCH_WLH_DEBUG
-#define _dispatch_kevent_wlh_debug(verb, kev) _dispatch_kevent_debug(verb, kev)
-#else
-#define _dispatch_kevent_wlh_debug(verb, kev)  ((void)verb, (void)kev)
-#endif // DISPATCH_WLH_DEBUG
+#endif
 
 #if DISPATCH_MACHPORT_DEBUG
 #ifndef MACH_PORT_TYPE_SPREQUEST
@@ -311,6 +305,9 @@
 	return (mach_msg_size_t)ke->ext[1];
 }
 
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+static void _dispatch_mach_kevent_portset_drain(dispatch_kevent_t ke);
+#endif
 static void _dispatch_kevent_mach_msg_drain(dispatch_kevent_t ke);
 static inline void _dispatch_mach_host_calendar_change_register(void);
 
@@ -345,14 +342,20 @@
 static void
 _dispatch_kevent_print_error(dispatch_kevent_t ke)
 {
-	_dispatch_debug("kevent[0x%llx]: handling error",
-			(unsigned long long)ke->udata);
+	dispatch_kevent_t kev = NULL;
+
 	if (ke->flags & EV_DELETE) {
 		if (ke->flags & EV_UDATA_SPECIFIC) {
 			if (ke->data == EINPROGRESS) {
 				// deferred EV_DELETE
 				return;
 			}
+#if DISPATCH_KEVENT_TREAT_ENOENT_AS_EINPROGRESS
+			if (ke->data == ENOENT) {
+				// deferred EV_DELETE
+				return;
+			}
+#endif
 		}
 		// for EV_DELETE if the update was deferred we may have reclaimed
 		// the udata already, and it is unsafe to dereference it now.
@@ -366,7 +369,8 @@
 
 #if HAVE_MACH
 	if (ke->filter == EVFILT_MACHPORT && ke->data == ENOTSUP &&
-			(ke->flags & EV_ADD) && (ke->fflags & MACH_RCV_MSG)) {
+			(ke->flags & EV_ADD) && _dispatch_evfilt_machport_direct_enabled &&
+			kev && (kev->fflags & MACH_RCV_MSG)) {
 		DISPATCH_INTERNAL_CRASH(ke->ident,
 				"Missing EVFILT_MACHPORT support for ports");
 	}
@@ -434,7 +438,7 @@
 {
 	if (ke->filter == EVFILT_USER) {
 		_dispatch_kevent_mgr_debug("received", ke);
-		return;
+		return _dispatch_kevent_poke_drain(ke);
 	}
 	_dispatch_kevent_debug("received", ke);
 	if (unlikely(ke->flags & EV_ERROR)) {
@@ -448,6 +452,8 @@
 			ke->data = 0;
 			_dispatch_kevent_debug("synthetic NOTE_EXIT", ke);
 		} else {
+			_dispatch_debug("kevent[0x%llx]: handling error",
+					(unsigned long long)ke->udata);
 			return _dispatch_kevent_print_error(ke);
 		}
 	}
@@ -457,6 +463,11 @@
 
 #if HAVE_MACH
 	if (ke->filter == EVFILT_MACHPORT) {
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+		if (ke->udata == 0) {
+			return _dispatch_mach_kevent_portset_drain(ke);
+		}
+#endif
 		if (_dispatch_kevent_mach_msg_size(ke)) {
 			return _dispatch_kevent_mach_msg_drain(ke);
 		}
@@ -522,30 +533,31 @@
 #endif
 
 static void
-_dispatch_kq_init(void *context)
+_dispatch_kq_init(void *context DISPATCH_UNUSED)
 {
-	bool *kq_initialized = context;
-
 	_dispatch_fork_becomes_unsafe();
-	if (unlikely(getenv("LIBDISPATCH_TIMERS_FORCE_MAX_LEEWAY"))) {
-		_dispatch_timers_force_max_leeway = true;
-	}
-	*kq_initialized = true;
-
 #if DISPATCH_USE_KEVENT_WORKQUEUE
 	_dispatch_kevent_workqueue_init();
 	if (_dispatch_kevent_workqueue_enabled) {
 		int r;
 		int kqfd = _dispatch_kq;
-		const dispatch_kevent_s ke = {
-			.ident = 1,
-			.filter = EVFILT_USER,
-			.flags = EV_ADD|EV_CLEAR,
-			.qos = _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG,
-			.udata = (uintptr_t)DISPATCH_WLH_MANAGER,
+		const dispatch_kevent_s kev[] = {
+			[0] = {
+				.ident = 1,
+				.filter = EVFILT_USER,
+				.flags = EV_ADD|EV_CLEAR,
+				.qos = _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG,
+				.udata = (uintptr_t)DISPATCH_WLH_MANAGER,
+			},
+			[1] = {
+				.ident = 1,
+				.filter = EVFILT_USER,
+				.fflags = NOTE_TRIGGER,
+				.udata = (uintptr_t)DISPATCH_WLH_MANAGER,
+			},
 		};
 retry:
-		r = kevent_qos(kqfd, &ke, 1, NULL, 0, NULL, NULL,
+		r = kevent_qos(kqfd, kev, 2, NULL, 0, NULL, NULL,
 				KEVENT_FLAG_WORKQ|KEVENT_FLAG_IMMEDIATE);
 		if (unlikely(r == -1)) {
 			int err = errno;
@@ -567,116 +579,88 @@
 #endif // DISPATCH_USE_MGR_THREAD
 }
 
-#if DISPATCH_USE_MEMORYPRESSURE_SOURCE
-static void _dispatch_memorypressure_init(void);
-#else
-#define _dispatch_memorypressure_init() ((void)0)
-#endif
-
 DISPATCH_NOINLINE
 static int
-_dispatch_kq_poll(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n,
-		dispatch_kevent_t ke_out, int n_out, void *buf, size_t *avail,
+_dispatch_kq_update(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n,
 		uint32_t flags)
 {
 	static dispatch_once_t pred;
-	bool kq_initialized = false;
-	int r = 0;
+	dispatch_once_f(&pred, NULL, _dispatch_kq_init);
 
-	dispatch_once_f(&pred, &kq_initialized, _dispatch_kq_init);
-	if (unlikely(kq_initialized)) {
-		// The calling thread was the one doing the initialization
-		//
-		// The event loop needs the memory pressure source and debug channel,
-		// however creating these will recursively call _dispatch_kq_poll(),
-		// so we can't quite initialize them under the dispatch once.
-		_dispatch_memorypressure_init();
-		_voucher_activity_debug_channel_init();
-	}
+	dispatch_kevent_s ke_out[DISPATCH_DEFERRED_ITEMS_EVENT_COUNT];
+	int i, out_n = countof(ke_out), r = 0;
+#if DISPATCH_USE_KEVENT_QOS
+	size_t size, *avail = NULL;
+	void *buf = NULL;
+#endif
 
-
-#if !DISPATCH_USE_KEVENT_QOS
-	if (flags & KEVENT_FLAG_ERROR_EVENTS) {
-		// emulate KEVENT_FLAG_ERROR_EVENTS
-		for (r = 0; r < n; r++) {
-			ke[r].flags |= EV_RECEIPT;
+#if DISPATCH_DEBUG
+	dispatch_assert(wlh);
+	dispatch_assert((size_t)n <= countof(ke_out));
+	for (i = 0; i < n; i++) {
+		if (ke[i].filter != EVFILT_USER || DISPATCH_MGR_QUEUE_DEBUG) {
+			_dispatch_kevent_debug_n(NULL, ke + i, i, n);
 		}
-		out_n = n;
 	}
 #endif
 
+	wlh = DISPATCH_WLH_GLOBAL;
+
+	if (flags & KEVENT_FLAG_ERROR_EVENTS) {
+#if !DISPATCH_USE_KEVENT_QOS
+		// emulate KEVENT_FLAG_ERROR_EVENTS
+		for (i = 0; i < n; i++) {
+			ke[i].flags |= EV_RECEIPT;
+		}
+		out_n = n;
+#endif
+	} else {
+#if DISPATCH_USE_KEVENT_QOS
+		size = DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE +
+				DISPATCH_MACH_TRAILER_SIZE;
+		buf = alloca(size);
+		avail = &size;
+#endif
+	}
+
 retry:
-	if (wlh == DISPATCH_WLH_ANON) {
+	_dispatch_clear_return_to_kernel();
+	if (wlh == DISPATCH_WLH_GLOBAL) {
 		int kqfd = _dispatch_kq;
 #if DISPATCH_USE_KEVENT_QOS
 		if (_dispatch_kevent_workqueue_enabled) {
 			flags |= KEVENT_FLAG_WORKQ;
 		}
-		r = kevent_qos(kqfd, ke, n, ke_out, n_out, buf, avail, flags);
+		r = kevent_qos(kqfd, ke, n, ke_out, out_n, buf, avail, flags);
 #else
 		const struct timespec timeout_immediately = {}, *timeout = NULL;
 		if (flags & KEVENT_FLAG_IMMEDIATE) timeout = &timeout_immediately;
-		r = kevent(kqfd, ke, n, ke_out, n_out, timeout);
+		r = kevent(kqfd, ke, n, ke_out, out_n, timeout);
 #endif
 	}
 	if (unlikely(r == -1)) {
 		int err = errno;
 		switch (err) {
-		case ENOMEM:
-			_dispatch_temporary_resource_shortage();
-			/* FALLTHROUGH */
 		case EINTR:
 			goto retry;
 		case EBADF:
 			DISPATCH_CLIENT_CRASH(err, "Do not close random Unix descriptors");
+			break;
 		default:
-			DISPATCH_CLIENT_CRASH(err, "Unexpected error from kevent");
+			(void)dispatch_assume_zero(err);
+			break;
 		}
+		return err;
 	}
-	return r;
-}
 
-DISPATCH_NOINLINE
-static int
-_dispatch_kq_drain(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n,
-		uint32_t flags)
-{
-	dispatch_kevent_s ke_out[DISPATCH_DEFERRED_ITEMS_EVENT_COUNT];
-	bool poll_for_events = !(flags & KEVENT_FLAG_ERROR_EVENTS);
-	int i, n_out = countof(ke_out), r = 0;
-	size_t *avail = NULL;
-	void *buf = NULL;
-
-#if DISPATCH_USE_KEVENT_QOS
-	size_t size;
-	if (poll_for_events) {
-		size = DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE +
-				DISPATCH_MACH_TRAILER_SIZE;
-		buf = alloca(size);
-		avail = &size;
-	}
-#endif
-
-#if DISPATCH_DEBUG
-	for (r = 0; r < n; r++) {
-		if (ke[r].filter != EVFILT_USER || DISPATCH_MGR_QUEUE_DEBUG) {
-			_dispatch_kevent_debug_n(NULL, ke + r, r, n);
-		}
-	}
-#endif
-
-	if (poll_for_events) _dispatch_clear_return_to_kernel();
-	n = _dispatch_kq_poll(wlh, ke, n, ke_out, n_out, buf, avail, flags);
-	if (n == 0) {
-		r = 0;
-	} else if (flags & KEVENT_FLAG_ERROR_EVENTS) {
-		for (i = 0, r = 0; i < n; i++) {
+	if (flags & KEVENT_FLAG_ERROR_EVENTS) {
+		for (i = 0, n = r, r = 0; i < n; i++) {
 			if ((ke_out[i].flags & EV_ERROR) && (r = (int)ke_out[i].data)) {
 				_dispatch_kevent_drain(&ke_out[i]);
 			}
 		}
 	} else {
-		for (i = 0, r = 0; i < n; i++) {
+		for (i = 0, n = r, r = 0; i < n; i++) {
 			_dispatch_kevent_drain(&ke_out[i]);
 		}
 	}
@@ -687,7 +671,7 @@
 static inline int
 _dispatch_kq_update_one(dispatch_wlh_t wlh, dispatch_kevent_t ke)
 {
-	return _dispatch_kq_drain(wlh, ke, 1,
+	return _dispatch_kq_update(wlh, ke, 1,
 			KEVENT_FLAG_IMMEDIATE | KEVENT_FLAG_ERROR_EVENTS);
 }
 
@@ -695,7 +679,7 @@
 static inline void
 _dispatch_kq_update_all(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n)
 {
-	(void)_dispatch_kq_drain(wlh, ke, n,
+	(void)_dispatch_kq_update(wlh, ke, n,
 			KEVENT_FLAG_IMMEDIATE | KEVENT_FLAG_ERROR_EVENTS);
 }
 
@@ -747,8 +731,8 @@
 _dispatch_kq_deferred_reuse_slot(dispatch_wlh_t wlh,
 		dispatch_deferred_items_t ddi, int slot)
 {
-	if (wlh != DISPATCH_WLH_ANON) _dispatch_set_return_to_kernel();
-	if (unlikely(slot == ddi->ddi_maxevents)) {
+	if (wlh != DISPATCH_WLH_GLOBAL) _dispatch_set_return_to_kernel();
+	if (unlikely(slot == countof(ddi->ddi_eventlist))) {
 		int nevents = ddi->ddi_nevents;
 		ddi->ddi_nevents = 1;
 		_dispatch_kq_update_all(wlh, ddi->ddi_eventlist, nevents);
@@ -778,13 +762,13 @@
 {
 	dispatch_deferred_items_t ddi = _dispatch_deferred_items_get();
 
-	if (ddi && ddi->ddi_maxevents && wlh == _dispatch_get_wlh()) {
+	if (ddi && wlh == _dispatch_get_wlh()) {
 		int slot = _dispatch_kq_deferred_find_slot(ddi, ke->filter, ke->ident,
 				ke->udata);
 		dispatch_kevent_t dk = _dispatch_kq_deferred_reuse_slot(wlh, ddi, slot);
 		*dk = *ke;
-		if (ke->filter != EVFILT_USER) {
-			_dispatch_kevent_mgr_debug("deferred", ke);
+		if (ke->filter != EVFILT_USER || DISPATCH_MGR_QUEUE_DEBUG) {
+			_dispatch_kevent_debug("deferred", ke);
 		}
 	} else {
 		_dispatch_kq_update_one(wlh, ke);
@@ -816,9 +800,7 @@
 
 	if (action_flags & EV_ADD) {
 		// as soon as we register we may get an event delivery and it has to
-		// see du_wlh already set, else it will not unregister the kevent
-		dispatch_assert(du->du_wlh == NULL);
-		_dispatch_wlh_retain(wlh);
+		// see this bit already set, else it will not unregister the kevent
 		du->du_wlh = wlh;
 	}
 
@@ -852,7 +834,6 @@
 done:
 	if (action_flags & EV_ADD) {
 		if (unlikely(r)) {
-			_dispatch_wlh_release(du->du_wlh);
 			du->du_wlh = NULL;
 		}
 		return r == 0;
@@ -861,8 +842,11 @@
 	if (action_flags & EV_DELETE) {
 		if (r == EINPROGRESS) {
 			return false;
+#if DISPATCH_KEVENT_TREAT_ENOENT_AS_EINPROGRESS
+		} else if (r == ENOENT) {
+			return false;
+#endif
 		}
-		_dispatch_wlh_release(du->du_wlh);
 		du->du_wlh = NULL;
 	}
 
@@ -929,7 +913,7 @@
 {
 	struct dispatch_muxnote_bucket_s *dmb;
 	dmb = _dispatch_muxnote_bucket(name, filter);
-	return _dispatch_muxnote_find(dmb, DISPATCH_WLH_ANON, name, filter);
+	return _dispatch_muxnote_find(dmb, DISPATCH_WLH_GLOBAL, name, filter);
 }
 
 DISPATCH_NOINLINE
@@ -987,7 +971,7 @@
 			bool armed = DISPATCH_MACH_NOTIFICATION_ARMED(&dmn->dmn_kev);
 			os_atomic_store2o(du._dmsr, dmsr_notification_armed, armed,relaxed);
 		}
-		du._du->du_wlh = DISPATCH_WLH_ANON;
+		du._du->du_wlh = DISPATCH_WLH_GLOBAL;
 	}
 	return installed;
 }
@@ -1002,11 +986,11 @@
 	case DISPATCH_EVFILT_CUSTOM_ADD:
 	case DISPATCH_EVFILT_CUSTOM_OR:
 	case DISPATCH_EVFILT_CUSTOM_REPLACE:
-		du._du->du_wlh = DISPATCH_WLH_ANON;
+		du._du->du_wlh = wlh;
 		return true;
 	}
 	if (!du._du->du_is_direct) {
-		return _dispatch_unote_register_muxed(du, DISPATCH_WLH_ANON);
+		return _dispatch_unote_register_muxed(du, DISPATCH_WLH_GLOBAL);
 	}
 	return _dispatch_kq_unote_update(wlh, du, EV_ADD | EV_ENABLE);
 }
@@ -1040,7 +1024,6 @@
 	if (dmn->dmn_kev.filter == DISPATCH_EVFILT_MACH_NOTIFICATION) {
 		os_atomic_store2o(du._dmsr, dmsr_notification_armed, false, relaxed);
 	}
-	dispatch_assert(du._du->du_wlh == DISPATCH_WLH_ANON);
 	du._du->du_wlh = NULL;
 	TAILQ_REMOVE(&dmn->dmn_unotes_head, dul, du_link);
 	_TAILQ_TRASH_ENTRY(dul, du_link);
@@ -1107,7 +1090,14 @@
 }
 
 #pragma mark -
-#pragma mark dispatch_event_loop
+#pragma mark dispatch_loop
+
+#if DISPATCH_USE_MEMORYPRESSURE_SOURCE
+static void _dispatch_memorypressure_init(void);
+#else
+#define _dispatch_memorypressure_init()
+#endif
+static bool _dispatch_timers_force_max_leeway;
 
 void
 _dispatch_event_loop_atfork_child(void)
@@ -1118,118 +1108,77 @@
 #endif
 }
 
+DISPATCH_NOINLINE
+void
+_dispatch_event_loop_init(void)
+{
+	if (unlikely(getenv("LIBDISPATCH_TIMERS_FORCE_MAX_LEEWAY"))) {
+		_dispatch_timers_force_max_leeway = true;
+	}
+	_dispatch_memorypressure_init();
+	_voucher_activity_debug_channel_init();
+}
 
 DISPATCH_NOINLINE
 void
-_dispatch_event_loop_poke(dispatch_wlh_t wlh, uint64_t dq_state, uint32_t flags)
+_dispatch_event_loop_poke(dispatch_wlh_t wlh, dispatch_priority_t pri,
+		uint32_t flags)
 {
 	if (wlh == DISPATCH_WLH_MANAGER) {
-		dispatch_kevent_s ke = (dispatch_kevent_s){
+		dispatch_assert(!flags);
+		dispatch_kevent_s ke = {
 			.ident  = 1,
 			.filter = EVFILT_USER,
 			.fflags = NOTE_TRIGGER,
 			.udata = (uintptr_t)DISPATCH_WLH_MANAGER,
 		};
-		return _dispatch_kq_deferred_update(DISPATCH_WLH_ANON, &ke);
-	} else if (wlh && wlh != DISPATCH_WLH_ANON) {
-		(void)dq_state; (void)flags;
+		return _dispatch_kq_deferred_update(DISPATCH_WLH_GLOBAL, &ke);
+	} else if (wlh && wlh != DISPATCH_WLH_GLOBAL) {
+		dispatch_assert(flags);
+		dispatch_assert(pri);
 	}
 	DISPATCH_INTERNAL_CRASH(wlh, "Unsupported wlh configuration");
 }
 
 DISPATCH_NOINLINE
+static void
+_dispatch_kevent_poke_drain(dispatch_kevent_t ke)
+{
+	dispatch_assert(ke->filter == EVFILT_USER);
+	dispatch_wlh_t wlh = (dispatch_wlh_t)ke->udata;
+	dispatch_assert(wlh);
+}
+
+DISPATCH_NOINLINE
 void
 _dispatch_event_loop_drain(uint32_t flags)
 {
 	dispatch_wlh_t wlh = _dispatch_get_wlh();
 	dispatch_deferred_items_t ddi = _dispatch_deferred_items_get();
-	int n;
-
-again:
-	n = ddi->ddi_nevents;
+	int n = ddi->ddi_nevents;
 	ddi->ddi_nevents = 0;
-	_dispatch_kq_drain(wlh, ddi->ddi_eventlist, n, flags);
-
-	if ((flags & KEVENT_FLAG_IMMEDIATE) &&
-			!(flags & KEVENT_FLAG_ERROR_EVENTS) &&
-			_dispatch_needs_to_return_to_kernel()) {
-		goto again;
-	}
+	_dispatch_kq_update(wlh, ddi->ddi_eventlist, n, flags);
 }
 
 void
-_dispatch_event_loop_merge(dispatch_kevent_t events, int nevents)
+_dispatch_event_loop_update(void)
 {
-	dispatch_deferred_items_t ddi = _dispatch_deferred_items_get();
-	dispatch_kevent_s kev[nevents];
-
-	// now we can re-use the whole event list, but we need to save one slot
-	// for the event loop poke
-	memcpy(kev, events, sizeof(kev));
-	ddi->ddi_maxevents = DISPATCH_DEFERRED_ITEMS_EVENT_COUNT - 1;
-
-	for (int i = 0; i < nevents; i++) {
-		_dispatch_kevent_drain(&kev[i]);
-	}
-
 	dispatch_wlh_t wlh = _dispatch_get_wlh();
-	if (wlh == DISPATCH_WLH_ANON && ddi->ddi_stashed_dou._do) {
-		if (ddi->ddi_nevents) {
-			// We will drain the stashed item and not return to the kernel
-			// right away. As a consequence, do not delay these updates.
-			_dispatch_event_loop_drain(KEVENT_FLAG_IMMEDIATE |
-					KEVENT_FLAG_ERROR_EVENTS);
-		}
-		_dispatch_trace_continuation_push(ddi->ddi_stashed_rq,
-				ddi->ddi_stashed_dou);
+	dispatch_deferred_items_t ddi = _dispatch_deferred_items_get();
+	int n = ddi->ddi_nevents;
+	ddi->ddi_nevents = 0;
+	_dispatch_kq_update_all(wlh, ddi->ddi_eventlist, n);
+	dispatch_assert(ddi->ddi_nevents == 0);
+}
+
+void
+_dispatch_event_loop_merge(dispatch_kevent_t ke, int n)
+{
+	while (n-- > 0) {
+		_dispatch_kevent_drain(ke++);
 	}
 }
 
-void
-_dispatch_event_loop_leave_immediate(dispatch_wlh_t wlh, uint64_t dq_state)
-{
-	(void)wlh; (void)dq_state;
-}
-
-void
-_dispatch_event_loop_leave_deferred(dispatch_wlh_t wlh, uint64_t dq_state)
-{
-	(void)wlh; (void)dq_state;
-}
-
-void
-_dispatch_event_loop_wake_owner(dispatch_sync_context_t dsc,
-		dispatch_wlh_t wlh, uint64_t old_state, uint64_t new_state)
-{
-	(void)dsc; (void)wlh; (void)old_state; (void)new_state;
-}
-
-void
-_dispatch_event_loop_wait_for_ownership(dispatch_sync_context_t dsc)
-{
-	if (dsc->dsc_release_storage) {
-		_dispatch_queue_release_storage(dsc->dc_data);
-	}
-}
-
-void
-_dispatch_event_loop_end_ownership(dispatch_wlh_t wlh, uint64_t old_state,
-		uint64_t new_state, uint32_t flags)
-{
-	(void)wlh; (void)old_state; (void)new_state; (void)flags;
-}
-
-#if DISPATCH_WLH_DEBUG
-void
-_dispatch_event_loop_assert_not_owned(dispatch_wlh_t wlh)
-{
-	(void)wlh;
-}
-#endif // DISPATCH_WLH_DEBUG
-
-#pragma mark -
-#pragma mark dispatch_event_loop timers
-
 #define DISPATCH_KEVENT_TIMEOUT_IDENT_MASK (~0ull << 8)
 
 DISPATCH_NOINLINE
@@ -1270,7 +1219,7 @@
 #endif
 	};
 
-	_dispatch_kq_deferred_update(DISPATCH_WLH_ANON, &ke);
+	_dispatch_kq_deferred_update(DISPATCH_WLH_GLOBAL, &ke);
 }
 
 void
@@ -1302,7 +1251,6 @@
 	_dispatch_event_loop_timer_program(tidx, 0, 0, EV_DELETE);
 }
 
-#pragma mark -
 #pragma mark kevent specific sources
 
 static dispatch_unote_t
@@ -1416,16 +1364,12 @@
 		DISPATCH_MEMORYPRESSURE_WARN | \
 		DISPATCH_MEMORYPRESSURE_CRITICAL | \
 		DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN | \
-		DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL | \
-		DISPATCH_MEMORYPRESSURE_MSL_STATUS)
-
+		DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL)
 #define DISPATCH_MEMORYPRESSURE_MALLOC_MASK ( \
 		DISPATCH_MEMORYPRESSURE_WARN | \
 		DISPATCH_MEMORYPRESSURE_CRITICAL | \
 		DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN | \
-		DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL | \
-		DISPATCH_MEMORYPRESSURE_MSL_STATUS)
-
+		DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL)
 
 static void
 _dispatch_memorypressure_handler(void *context)
@@ -1465,7 +1409,8 @@
 {
 	dispatch_source_t ds = dispatch_source_create(
 			DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0,
-			DISPATCH_MEMORYPRESSURE_SOURCE_MASK, &_dispatch_mgr_q);
+			DISPATCH_MEMORYPRESSURE_SOURCE_MASK,
+			_dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, true));
 	dispatch_set_context(ds, ds);
 	dispatch_source_set_event_handler_f(ds, _dispatch_memorypressure_handler);
 	dispatch_activate(ds);
@@ -1515,8 +1460,7 @@
 	.dst_mask       = NOTE_MEMORYSTATUS_PRESSURE_NORMAL
 			|NOTE_MEMORYSTATUS_PRESSURE_WARN|NOTE_MEMORYSTATUS_PRESSURE_CRITICAL
 			|NOTE_MEMORYSTATUS_LOW_SWAP|NOTE_MEMORYSTATUS_PROC_LIMIT_WARN
-			|NOTE_MEMORYSTATUS_PROC_LIMIT_CRITICAL
-			|NOTE_MEMORYSTATUS_MSL_STATUS,
+			|NOTE_MEMORYSTATUS_PROC_LIMIT_CRITICAL,
 	.dst_size       = sizeof(struct dispatch_source_refs_s),
 
 #if TARGET_OS_SIMULATOR
@@ -1579,42 +1523,15 @@
 	}
 }
 
-static mach_msg_audit_trailer_t *
-_dispatch_mach_msg_get_audit_trailer(mach_msg_header_t *hdr)
-{
-	mach_msg_trailer_t *tlr = NULL;
-	mach_msg_audit_trailer_t *audit_tlr = NULL;
-	tlr = (mach_msg_trailer_t *)((unsigned char *)hdr +
-			round_msg(hdr->msgh_size));
-	// The trailer should always be of format zero.
-	if (tlr->msgh_trailer_type == MACH_MSG_TRAILER_FORMAT_0) {
-		if (tlr->msgh_trailer_size >= sizeof(mach_msg_audit_trailer_t)) {
-			audit_tlr = (mach_msg_audit_trailer_t *)tlr;
-		}
-	}
-	return audit_tlr;
-}
-
 DISPATCH_NOINLINE
 static void
 _dispatch_mach_notify_source_invoke(mach_msg_header_t *hdr)
 {
 	mig_reply_error_t reply;
-	mach_msg_audit_trailer_t *tlr = NULL;
 	dispatch_assert(sizeof(mig_reply_error_t) == sizeof(union
 		__ReplyUnion___dispatch_libdispatch_internal_protocol_subsystem));
 	dispatch_assert(sizeof(mig_reply_error_t) <
 			DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE);
-	tlr = _dispatch_mach_msg_get_audit_trailer(hdr);
-	if (!tlr) {
-		DISPATCH_INTERNAL_CRASH(0, "message received without expected trailer");
-	}
-	if (tlr->msgh_audit.val[DISPATCH_MACH_AUDIT_TOKEN_PID] != 0) {
-		(void)dispatch_assume_zero(
-				tlr->msgh_audit.val[DISPATCH_MACH_AUDIT_TOKEN_PID]);
-		mach_msg_destroy(hdr);
-		return;
-	}
 	boolean_t success = libdispatch_internal_protocol_server(hdr, &reply.Head);
 	if (!success && reply.RetCode == MIG_BAD_ID &&
 			(hdr->msgh_id == HOST_CALENDAR_SET_REPLYID ||
@@ -1839,7 +1756,7 @@
 
 	_dispatch_debug_machport(name);
 	dmn = _dispatch_mach_muxnote_find(name, DISPATCH_EVFILT_MACH_NOTIFICATION);
-	if (!dmn) {
+	if (!dispatch_assume(dmn)) {
 		return;
 	}
 
@@ -1988,6 +1905,204 @@
 #pragma mark mach recv / reply
 #if HAVE_MACH
 
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+static mach_port_t _dispatch_mach_portset,  _dispatch_mach_recv_portset;
+static dispatch_kevent_s _dispatch_mach_recv_kevent;
+
+static void
+_dispatch_mach_portset_init(void *context DISPATCH_UNUSED)
+{
+	kern_return_t kr = mach_port_allocate(mach_task_self(),
+			MACH_PORT_RIGHT_PORT_SET, &_dispatch_mach_portset);
+	DISPATCH_VERIFY_MIG(kr);
+	if (unlikely(kr)) {
+		DISPATCH_CLIENT_CRASH(kr,
+				"mach_port_allocate() failed: cannot create port set");
+	}
+
+	dispatch_kevent_s kev = {
+		.filter = EVFILT_MACHPORT,
+		.flags  = EV_ADD|EV_ENABLE,
+		.ident  = _dispatch_mach_portset,
+		.qos    = _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG,
+	};
+	_dispatch_kq_deferred_update(DISPATCH_WLH_GLOBAL, &kev);
+}
+
+static bool
+_dispatch_mach_portset_update(mach_port_t mp, mach_port_t mps)
+{
+	kern_return_t kr;
+
+	_dispatch_debug_machport(mp);
+	kr = mach_port_move_member(mach_task_self(), mp, mps);
+	if (unlikely(kr)) {
+		DISPATCH_VERIFY_MIG(kr);
+		switch (kr) {
+		case KERN_INVALID_RIGHT:
+			if (mps) {
+				_dispatch_bug_mach_client("_dispatch_kevent_machport_enable: "
+						"mach_port_move_member() failed ", kr);
+				break;
+			}
+			//fall through
+		case KERN_INVALID_NAME:
+#if DISPATCH_DEBUG
+			_dispatch_log("Corruption: Mach receive right 0x%x destroyed "
+					"prematurely", mp);
+#endif
+			break;
+		default:
+			(void)dispatch_assume_zero(kr);
+			break;
+		}
+	}
+	if (mps) {
+		return kr == KERN_SUCCESS;
+	}
+	return true;
+}
+
+static mach_port_t
+_dispatch_mach_get_portset(void)
+{
+	static dispatch_once_t pred;
+	dispatch_once_f(&pred, NULL, _dispatch_mach_portset_init);
+	return _dispatch_mach_portset;
+}
+
+static bool
+_dispatch_mach_recv_update_portset_mux(dispatch_muxnote_t dmn)
+{
+	mach_port_t mp = (mach_port_t)dmn->dmn_kev.ident;
+	mach_port_t mps = MACH_PORT_NULL;
+	if (!(dmn->dmn_kev.flags & EV_DELETE)) {
+		mps = _dispatch_mach_get_portset();
+	}
+	return _dispatch_mach_portset_update(mp, mps);
+}
+
+static void
+_dispatch_mach_recv_msg_buf_init(dispatch_kevent_t ke)
+{
+	mach_vm_size_t vm_size = mach_vm_round_page(
+			DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE +
+			DISPATCH_MACH_TRAILER_SIZE);
+	mach_vm_address_t vm_addr = vm_page_size;
+	kern_return_t kr;
+
+	while (unlikely(kr = mach_vm_allocate(mach_task_self(), &vm_addr, vm_size,
+			VM_FLAGS_ANYWHERE))) {
+		if (kr != KERN_NO_SPACE) {
+			DISPATCH_CLIENT_CRASH(kr,
+					"Could not allocate mach msg receive buffer");
+		}
+		_dispatch_temporary_resource_shortage();
+		vm_addr = vm_page_size;
+	}
+	ke->ext[0] = (uintptr_t)vm_addr;
+	ke->ext[1] = vm_size;
+}
+
+static void
+_dispatch_mach_recv_portset_init(void *context DISPATCH_UNUSED)
+{
+	kern_return_t kr = mach_port_allocate(mach_task_self(),
+			MACH_PORT_RIGHT_PORT_SET, &_dispatch_mach_recv_portset);
+	DISPATCH_VERIFY_MIG(kr);
+	if (unlikely(kr)) {
+		DISPATCH_CLIENT_CRASH(kr,
+				"mach_port_allocate() failed: cannot create port set");
+	}
+
+	dispatch_assert(DISPATCH_MACH_TRAILER_SIZE ==
+			REQUESTED_TRAILER_SIZE_NATIVE(MACH_RCV_TRAILER_ELEMENTS(
+			DISPATCH_MACH_RCV_TRAILER)));
+
+	_dispatch_mach_recv_kevent = (dispatch_kevent_s){
+		.filter = EVFILT_MACHPORT,
+		.ident  = _dispatch_mach_recv_portset,
+		.flags  = EV_ADD|EV_ENABLE|EV_DISPATCH,
+		.fflags = DISPATCH_MACH_RCV_OPTIONS,
+		.qos    = _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG,
+	};
+	if (!_dispatch_kevent_workqueue_enabled) {
+		_dispatch_mach_recv_msg_buf_init(&_dispatch_mach_recv_kevent);
+	}
+	_dispatch_kq_deferred_update(DISPATCH_WLH_GLOBAL,
+			&_dispatch_mach_recv_kevent);
+}
+
+static mach_port_t
+_dispatch_mach_get_recv_portset(void)
+{
+	static dispatch_once_t pred;
+	dispatch_once_f(&pred, NULL, _dispatch_mach_recv_portset_init);
+	return _dispatch_mach_recv_portset;
+}
+
+static bool
+_dispatch_mach_recv_direct_update_portset_mux(dispatch_muxnote_t dmn)
+{
+	mach_port_t mp = (mach_port_t)dmn->dmn_kev.ident;
+	mach_port_t mps = MACH_PORT_NULL;
+	if (!(dmn->dmn_kev.flags & EV_DELETE)) {
+		mps = _dispatch_mach_get_recv_portset();
+	}
+	return _dispatch_mach_portset_update(mp, mps);
+}
+
+static dispatch_unote_t
+_dispatch_mach_kevent_mach_recv_direct_find(mach_port_t name)
+{
+	dispatch_muxnote_t dmn;
+	dispatch_unote_linkage_t dul;
+
+	dmn = _dispatch_mach_muxnote_find(name, EVFILT_MACHPORT);
+	TAILQ_FOREACH(dul, &dmn->dmn_unotes_head, du_link) {
+		dispatch_unote_t du = _dispatch_unote_linkage_get_unote(dul);
+		if (du._du->du_type->dst_fflags & MACH_RCV_MSG) {
+			return du;
+		}
+	}
+	return DISPATCH_UNOTE_NULL;
+}
+
+DISPATCH_NOINLINE
+static void
+_dispatch_mach_kevent_portset_merge(dispatch_kevent_t ke)
+{
+	mach_port_t name = (mach_port_name_t)ke->data;
+	dispatch_unote_linkage_t dul, dul_next;
+	dispatch_muxnote_t dmn;
+
+	_dispatch_debug_machport(name);
+	dmn = _dispatch_mach_muxnote_find(name, EVFILT_MACHPORT);
+	if (!dispatch_assume(dmn)) {
+		return;
+	}
+	_dispatch_mach_portset_update(name, MACH_PORT_NULL); // emulate EV_DISPATCH
+
+	TAILQ_FOREACH_SAFE(dul, &dmn->dmn_unotes_head, du_link, dul_next) {
+		dispatch_unote_t du = _dispatch_unote_linkage_get_unote(dul);
+		dux_merge_evt(du._du, EV_ENABLE | EV_DISPATCH,
+				DISPATCH_MACH_RECV_MESSAGE, 0, 0);
+	}
+}
+
+DISPATCH_NOINLINE
+static void
+_dispatch_mach_kevent_portset_drain(dispatch_kevent_t ke)
+{
+	if (ke->ident == _dispatch_mach_recv_portset) {
+		return _dispatch_kevent_mach_msg_drain(ke);
+	} else {
+		dispatch_assert(ke->ident == _dispatch_mach_portset);
+		return _dispatch_mach_kevent_portset_merge(ke);
+	}
+}
+#endif // DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+
 static void
 _dispatch_kevent_mach_msg_recv(dispatch_unote_t du, uint32_t flags,
 		mach_msg_header_t *hdr)
@@ -2004,6 +2119,11 @@
 				"received message with MACH_PORT_NULL port");
 	} else {
 		_dispatch_debug_machport(name);
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+		if (du._du == NULL) {
+			du = _dispatch_mach_kevent_mach_recv_direct_find(name);
+		}
+#endif
 		if (likely(du._du)) {
 			return dux_merge_msg(du._du, flags, hdr, siz);
 		}
@@ -2074,6 +2194,25 @@
 		_dispatch_bug_mach_client("_dispatch_kevent_mach_msg_drain: "
 				"message reception failed", kr);
 	}
+
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+	if (!(flags & EV_UDATA_SPECIFIC)) {
+		_dispatch_kq_deferred_update(DISPATCH_WLH_GLOBAL,
+				&_dispatch_mach_recv_kevent);
+	}
+#endif
+}
+
+static dispatch_unote_t
+_dispatch_source_mach_recv_create(dispatch_source_type_t dst,
+		uintptr_t handle, unsigned long mask)
+{
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+	if (!_dispatch_evfilt_machport_direct_enabled) {
+		dst = &_dispatch_source_type_mach_recv_pset;
+	}
+#endif
+	return _dispatch_unote_create_with_handle(dst, handle, mask);
 }
 
 const dispatch_source_type_s _dispatch_source_type_mach_recv = {
@@ -2083,13 +2222,26 @@
 	.dst_fflags     = 0,
 	.dst_size       = sizeof(struct dispatch_source_refs_s),
 
-	.dst_create     = _dispatch_unote_create_with_handle,
+	.dst_create     = _dispatch_source_mach_recv_create,
 	.dst_merge_evt  = _dispatch_source_merge_evt,
 	.dst_merge_msg  = NULL, // never receives messages directly
-
-	.dst_per_trigger_qos = true,
 };
 
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+const dispatch_source_type_s _dispatch_source_type_mach_recv_pset = {
+	.dst_kind       = "mach_recv (portset)",
+	.dst_filter     = EVFILT_MACHPORT,
+	.dst_flags      = EV_DISPATCH,
+	.dst_fflags     = 0,
+	.dst_size       = sizeof(struct dispatch_source_refs_s),
+
+	.dst_create     = NULL, // never created directly
+	.dst_update_mux = _dispatch_mach_recv_update_portset_mux,
+	.dst_merge_evt  = _dispatch_source_merge_evt,
+	.dst_merge_msg  = NULL, // never receives messages directly
+};
+#endif
+
 static void
 _dispatch_source_mach_recv_direct_merge_msg(dispatch_unote_t du, uint32_t flags,
 		mach_msg_header_t *msg, mach_msg_size_t msgsz DISPATCH_UNUSED)
@@ -2114,6 +2266,18 @@
 	}
 }
 
+static dispatch_unote_t
+_dispatch_source_mach_recv_direct_create(dispatch_source_type_t dst,
+	uintptr_t handle, unsigned long mask)
+{
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+	if (!_dispatch_evfilt_machport_direct_enabled) {
+		dst = &_dispatch_source_type_mach_recv_direct_pset;
+	}
+#endif
+	return _dispatch_unote_create_with_handle(dst, handle, mask);
+}
+
 static void
 _dispatch_mach_recv_direct_merge(dispatch_unote_t du,
 		uint32_t flags, uintptr_t data,
@@ -2134,13 +2298,40 @@
 	.dst_fflags     = DISPATCH_MACH_RCV_OPTIONS,
 	.dst_size       = sizeof(struct dispatch_source_refs_s),
 
-	.dst_create     = _dispatch_unote_create_with_handle,
+	.dst_create     = _dispatch_source_mach_recv_direct_create,
 	.dst_merge_evt  = _dispatch_mach_recv_direct_merge,
 	.dst_merge_msg  = _dispatch_source_mach_recv_direct_merge_msg,
-
-	.dst_per_trigger_qos = true,
 };
 
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+const dispatch_source_type_s _dispatch_source_type_mach_recv_direct_pset = {
+	.dst_kind       = "direct mach_recv (portset)",
+	.dst_filter     = EVFILT_MACHPORT,
+	.dst_flags      = 0,
+	.dst_fflags     = DISPATCH_MACH_RCV_OPTIONS,
+	.dst_size       = sizeof(struct dispatch_source_refs_s),
+
+	.dst_create     = NULL, // never created directly
+	.dst_update_mux = _dispatch_mach_recv_direct_update_portset_mux,
+	.dst_merge_evt  = _dispatch_mach_recv_direct_merge,
+	.dst_merge_msg  = _dispatch_source_mach_recv_direct_merge_msg,
+};
+#endif
+
+static dispatch_unote_t
+_dispatch_mach_recv_create(dispatch_source_type_t dst,
+	uintptr_t handle, unsigned long mask)
+{
+	// mach channels pass MACH_PORT_NULL until connect
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+	if (!_dispatch_evfilt_machport_direct_enabled) {
+		dst = &_dispatch_mach_type_recv_pset;
+	}
+#endif
+	// without handle because the mach code will set the ident later
+	return _dispatch_unote_create_without_handle(dst, handle, mask);
+}
+
 const dispatch_source_type_s _dispatch_mach_type_recv = {
 	.dst_kind       = "mach_recv (channel)",
 	.dst_filter     = EVFILT_MACHPORT,
@@ -2148,14 +2339,38 @@
 	.dst_fflags     = DISPATCH_MACH_RCV_OPTIONS,
 	.dst_size       = sizeof(struct dispatch_mach_recv_refs_s),
 
-	 // without handle because the mach code will set the ident after connect
-	.dst_create     = _dispatch_unote_create_without_handle,
+	.dst_create     = _dispatch_mach_recv_create,
 	.dst_merge_evt  = _dispatch_mach_recv_direct_merge,
 	.dst_merge_msg  = _dispatch_mach_merge_msg,
-
-	.dst_per_trigger_qos = true,
 };
 
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+const dispatch_source_type_s _dispatch_mach_type_recv_pset = {
+	.dst_kind       = "mach_recv (channel, portset)",
+	.dst_filter     = EVFILT_MACHPORT,
+	.dst_flags      = 0,
+	.dst_fflags     = DISPATCH_MACH_RCV_OPTIONS,
+	.dst_size       = sizeof(struct dispatch_mach_recv_refs_s),
+
+	.dst_create     = NULL, // never created directly
+	.dst_update_mux = _dispatch_mach_recv_direct_update_portset_mux,
+	.dst_merge_evt  = _dispatch_mach_recv_direct_merge,
+	.dst_merge_msg  = _dispatch_mach_merge_msg,
+};
+#endif
+
+static dispatch_unote_t
+_dispatch_mach_reply_create(dispatch_source_type_t dst,
+	uintptr_t handle, unsigned long mask)
+{
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+	if (!_dispatch_evfilt_machport_direct_enabled) {
+		dst = &_dispatch_mach_type_reply_pset;
+	}
+#endif
+	return _dispatch_unote_create_with_handle(dst, handle, mask);
+}
+
 DISPATCH_NORETURN
 static void
 _dispatch_mach_reply_merge_evt(dispatch_unote_t du,
@@ -2173,11 +2388,26 @@
 	.dst_fflags     = DISPATCH_MACH_RCV_OPTIONS,
 	.dst_size       = sizeof(struct dispatch_mach_reply_refs_s),
 
-	.dst_create     = _dispatch_unote_create_with_handle,
+	.dst_create     = _dispatch_mach_reply_create,
 	.dst_merge_evt  = _dispatch_mach_reply_merge_evt,
 	.dst_merge_msg  = _dispatch_mach_reply_merge_msg,
 };
 
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+const dispatch_source_type_s _dispatch_mach_type_reply_pset = {
+	.dst_kind       = "mach reply (portset)",
+	.dst_filter     = EVFILT_MACHPORT,
+	.dst_flags      = EV_ONESHOT,
+	.dst_fflags     = DISPATCH_MACH_RCV_OPTIONS,
+	.dst_size       = sizeof(struct dispatch_mach_reply_refs_s),
+
+	.dst_create     = NULL, // never created directly
+	.dst_update_mux = _dispatch_mach_recv_direct_update_portset_mux,
+	.dst_merge_evt  = _dispatch_mach_reply_merge_evt,
+	.dst_merge_msg  = _dispatch_mach_reply_merge_msg,
+};
+#endif
+
 #pragma mark Mach channel SIGTERM notification (for XPC channels only)
 
 const dispatch_source_type_s _dispatch_xpc_type_sigterm = {
diff --git a/src/event/workqueue_internal.h b/src/event/workqueue_internal.h
index 9f8fc3a..012e554 100644
--- a/src/event/workqueue_internal.h
+++ b/src/event/workqueue_internal.h
@@ -37,8 +37,6 @@
 
 #define WORKQ_NUM_PRIORITIES 6
 
-#define WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 0x1
-
 #define DISPATCH_WORKQ_MAX_PTHREAD_COUNT 255
 
 void _dispatch_workq_worker_register(dispatch_queue_t root_q, int priority);
diff --git a/src/firehose/firehose.defs b/src/firehose/firehose.defs
index e4fdf33..7ed7958 100644
--- a/src/firehose/firehose.defs
+++ b/src/firehose/firehose.defs
@@ -40,13 +40,12 @@
 );
 
 routine
-push_and_wait(
+push(
 RequestPort	comm_port		: mach_port_t;
 SReplyPort	reply_port		: mach_port_make_send_once_t;
 			qos_class		: qos_class_t;
 			for_io			: boolean_t;
-out			push_reply		: firehose_push_reply_t;
-out			quarantinedOut	: boolean_t
+out			push_reply		: firehose_push_reply_t
 );
 
 simpleroutine
diff --git a/src/firehose/firehose_buffer.c b/src/firehose/firehose_buffer.c
index 3bb790c..21692b9 100644
--- a/src/firehose/firehose_buffer.c
+++ b/src/firehose/firehose_buffer.c
@@ -69,8 +69,6 @@
 #define DLOCK_LOCK_DATA_CONTENTION 0
 static void _dispatch_gate_wait(dispatch_gate_t l, uint32_t flags);
 
-#define fcp_quarntined fcp_quarantined
-
 #include <kern/debug.h>
 #include <machine/cpu_number.h>
 #include <kern/thread.h>
@@ -452,58 +450,23 @@
 		}
 	}
 }
-
-OS_NOINLINE
-static void
-firehose_client_start_quarantine(firehose_buffer_t fb)
-{
-	if (_voucher_libtrace_hooks->vah_version < 5) return;
-	if (!_voucher_libtrace_hooks->vah_quarantine_starts) return;
-
-	_voucher_libtrace_hooks->vah_quarantine_starts();
-
-	fb->fb_header.fbh_quarantined = true;
-	firehose_buffer_stream_flush(fb, firehose_stream_special);
-	firehose_buffer_stream_flush(fb, firehose_stream_persist);
-	firehose_buffer_stream_flush(fb, firehose_stream_memory);
-}
 #endif // !KERNEL
 
 static void
 firehose_client_merge_updates(firehose_buffer_t fb, bool async_notif,
-		firehose_push_reply_t reply, bool quarantined,
-		firehose_bank_state_u *state_out)
+		firehose_push_reply_t reply, firehose_bank_state_u *state_out)
 {
-	firehose_buffer_header_t fbh = &fb->fb_header;
 	firehose_bank_state_u state;
 	firehose_ring_tail_u otail, ntail;
 	uint64_t old_flushed_pos, bank_updates;
 	uint16_t io_delta = 0;
 	uint16_t mem_delta = 0;
 
-	if (quarantined) {
-#ifndef KERNEL
-		// this isn't a dispatch_once so that the upcall to libtrace
-		// can actually log itself without blocking on the gate.
-		if (async_notif) {
-			if (os_atomic_xchg(&fbh->fbh_quarantined_state,
-					FBH_QUARANTINE_STARTED, relaxed) !=
-					FBH_QUARANTINE_STARTED) {
-				firehose_client_start_quarantine(fb);
-			}
-		} else if (os_atomic_load(&fbh->fbh_quarantined_state, relaxed) ==
-				FBH_QUARANTINE_NONE) {
-			os_atomic_cmpxchg(&fbh->fbh_quarantined_state, FBH_QUARANTINE_NONE,
-					FBH_QUARANTINE_PENDING, relaxed);
-		}
-#endif
-	}
-
-	if (firehose_atomic_maxv2o(fbh, fbh_bank.fbb_mem_flushed,
+	if (firehose_atomic_maxv2o(&fb->fb_header, fbh_bank.fbb_mem_flushed,
 			reply.fpr_mem_flushed_pos, &old_flushed_pos, relaxed)) {
 		mem_delta = (uint16_t)(reply.fpr_mem_flushed_pos - old_flushed_pos);
 	}
-	if (firehose_atomic_maxv2o(fbh, fbh_bank.fbb_io_flushed,
+	if (firehose_atomic_maxv2o(&fb->fb_header, fbh_bank.fbb_io_flushed,
 			reply.fpr_io_flushed_pos, &old_flushed_pos, relaxed)) {
 		io_delta = (uint16_t)(reply.fpr_io_flushed_pos - old_flushed_pos);
 	}
@@ -515,14 +478,14 @@
 
 	if (!mem_delta && !io_delta) {
 		if (state_out) {
-			state_out->fbs_atomic_state = os_atomic_load2o(fbh,
+			state_out->fbs_atomic_state = os_atomic_load2o(&fb->fb_header,
 					fbh_bank.fbb_state.fbs_atomic_state, relaxed);
 		}
 		return;
 	}
 
 	__firehose_critical_region_enter();
-	os_atomic_rmw_loop2o(fbh, fbh_ring_tail.frp_atomic_tail,
+	os_atomic_rmw_loop2o(&fb->fb_header, fbh_ring_tail.frp_atomic_tail,
 			otail.frp_atomic_tail, ntail.frp_atomic_tail, relaxed, {
 		ntail = otail;
 		// overflow handles the generation wraps
@@ -532,7 +495,7 @@
 
 	bank_updates = ((uint64_t)mem_delta << FIREHOSE_BANK_SHIFT(0)) |
 			((uint64_t)io_delta << FIREHOSE_BANK_SHIFT(1));
-	state.fbs_atomic_state = os_atomic_sub2o(fbh,
+	state.fbs_atomic_state = os_atomic_sub2o(&fb->fb_header,
 			fbh_bank.fbb_state.fbs_atomic_state, bank_updates, release);
 	__firehose_critical_region_leave();
 
@@ -540,32 +503,29 @@
 
 	if (async_notif) {
 		if (io_delta) {
-			os_atomic_inc2o(fbh, fbh_bank.fbb_io_notifs, relaxed);
+			os_atomic_inc2o(&fb->fb_header, fbh_bank.fbb_io_notifs, relaxed);
 		}
 		if (mem_delta) {
-			os_atomic_inc2o(fbh, fbh_bank.fbb_mem_notifs, relaxed);
+			os_atomic_inc2o(&fb->fb_header, fbh_bank.fbb_mem_notifs, relaxed);
 		}
 	}
 }
 
 #ifndef KERNEL
-OS_NOT_TAIL_CALLED OS_NOINLINE
 static void
-firehose_client_send_push_and_wait(firehose_buffer_t fb, bool for_io,
+firehose_client_send_push(firehose_buffer_t fb, bool for_io,
 		firehose_bank_state_u *state_out)
 {
 	mach_port_t sendp = fb->fb_header.fbh_sendp;
 	firehose_push_reply_t push_reply = { };
 	qos_class_t qos = qos_class_self();
-	boolean_t quarantined = false;
 	kern_return_t kr;
 
 	if (slowpath(sendp == MACH_PORT_DEAD)) {
 		return;
 	}
 	if (fastpath(sendp)) {
-		kr = firehose_send_push_and_wait(sendp, qos, for_io,
-				&push_reply, &quarantined);
+		kr = firehose_send_push(sendp, qos, for_io, &push_reply);
 		if (likely(kr == KERN_SUCCESS)) {
 			goto success;
 		}
@@ -577,8 +537,7 @@
 
 	sendp = firehose_client_reconnect(fb, sendp);
 	if (fastpath(MACH_PORT_VALID(sendp))) {
-		kr = firehose_send_push_and_wait(sendp, qos, for_io,
-				&push_reply, &quarantined);
+		kr = firehose_send_push(sendp, qos, for_io, &push_reply);
 		if (likely(kr == KERN_SUCCESS)) {
 			goto success;
 		}
@@ -614,22 +573,12 @@
 	// There only is a point for multithreaded clients if:
 	// - enough samples (total_flushes above some limits)
 	// - the ratio is really bad (a push per cycle is definitely a problem)
-	return firehose_client_merge_updates(fb, false, push_reply, quarantined,
-			state_out);
-}
-
-OS_NOT_TAIL_CALLED OS_NOINLINE
-static void
-__FIREHOSE_CLIENT_THROTTLED_DUE_TO_HEAVY_LOGGING__(firehose_buffer_t fb,
-		bool for_io, firehose_bank_state_u *state_out)
-{
-	firehose_client_send_push_and_wait(fb, for_io, state_out);
+	return firehose_client_merge_updates(fb, false, push_reply, state_out);
 }
 
 kern_return_t
 firehose_client_push_reply(mach_port_t req_port OS_UNUSED,
-	kern_return_t rtc, firehose_push_reply_t push_reply OS_UNUSED,
-	boolean_t quarantined OS_UNUSED)
+	kern_return_t rtc, firehose_push_reply_t push_reply OS_UNUSED)
 {
 	DISPATCH_INTERNAL_CRASH(rtc, "firehose_push_reply should never be sent "
 			"to the buffer receive port");
@@ -637,12 +586,12 @@
 
 kern_return_t
 firehose_client_push_notify_async(mach_port_t server_port OS_UNUSED,
-	firehose_push_reply_t push_reply, boolean_t quarantined)
+	firehose_push_reply_t push_reply)
 {
 	// see _dispatch_source_merge_mach_msg_direct
 	dispatch_queue_t dq = _dispatch_queue_get_current();
 	firehose_buffer_t fb = dispatch_get_context(dq);
-	firehose_client_merge_updates(fb, true, push_reply, quarantined, NULL);
+	firehose_client_merge_updates(fb, true, push_reply, NULL);
 	return KERN_SUCCESS;
 }
 
@@ -704,7 +653,6 @@
 		.fcp_qos = firehose_buffer_qos_bits_propagate(),
 		.fcp_stream = ask->stream,
 		.fcp_flag_io = ask->for_io,
-		.fcp_quarantined = ask->quarantined,
 	};
 
 	if (privptr) {
@@ -720,8 +668,7 @@
 {
 	firehose_stream_state_u state, new_state;
 	firehose_tracepoint_t ft;
-	firehose_buffer_header_t fbh = &fb->fb_header;
-	firehose_buffer_stream_t fbs = &fbh->fbh_stream[ask->stream];
+	firehose_buffer_stream_t fbs = &fb->fb_header.fbh_stream[ask->stream];
 	uint64_t stamp_and_len;
 
 	if (fastpath(ref)) {
@@ -738,7 +685,7 @@
 		ft->ft_thread = _pthread_threadid_self_np_direct();
 #endif
 		if (ask->stream == firehose_stream_metadata) {
-			os_atomic_or2o(fbh, fbh_bank.fbb_metadata_bitmap,
+			os_atomic_or2o(fb, fb_header.fbh_bank.fbb_metadata_bitmap,
 					1ULL << ref, relaxed);
 		}
 		// release barrier to make the chunk init visible
@@ -769,11 +716,8 @@
 		ft = NULL;
 	}
 
-	// pairs with the one in firehose_buffer_tracepoint_reserve()
-	__firehose_critical_region_leave();
-
 #ifndef KERNEL
-	if (unlikely(_dispatch_lock_is_locked_by_self(state.fss_gate.dgl_lock))) {
+	if (unlikely(state.fss_gate.dgl_lock != _dispatch_tid_self())) {
 		_dispatch_gate_broadcast_slow(&fbs->fbs_state.fss_gate,
 				state.fss_gate.dgl_lock);
 	}
@@ -781,16 +725,10 @@
 	if (unlikely(state.fss_current == FIREHOSE_STREAM_STATE_PRISTINE)) {
 		firehose_buffer_update_limits(fb);
 	}
-
-	if (unlikely(os_atomic_load2o(fbh, fbh_quarantined_state, relaxed) ==
-			FBH_QUARANTINE_PENDING)) {
-		if (os_atomic_cmpxchg2o(fbh, fbh_quarantined_state,
-				FBH_QUARANTINE_PENDING, FBH_QUARANTINE_STARTED, relaxed)) {
-			firehose_client_start_quarantine(fb);
-		}
-	}
 #endif // KERNEL
 
+	// pairs with the one in firehose_buffer_tracepoint_reserve()
+	__firehose_critical_region_leave();
 	return ft;
 }
 
@@ -1029,12 +967,7 @@
 		state.fbs_atomic_state =
 				os_atomic_load2o(fbb, fbb_state.fbs_atomic_state, relaxed);
 		while ((state.fbs_atomic_state - bank_inc) & bank_unavail_mask) {
-			if (ask->quarantined) {
-				__FIREHOSE_CLIENT_THROTTLED_DUE_TO_HEAVY_LOGGING__(fb,
-						ask->for_io, &state);
-			} else {
-				firehose_client_send_push_and_wait(fb, ask->for_io, &state);
-			}
+			firehose_client_send_push(fb, ask->for_io, &state);
 			if (slowpath(fb->fb_header.fbh_sendp == MACH_PORT_DEAD)) {
 				// logd was unloaded, give up
 				return NULL;
@@ -1066,12 +999,7 @@
 		if (fastpath(ref = firehose_buffer_ring_try_grow(fbb, fbs_max_ref))) {
 			break;
 		}
-		if (ask->quarantined) {
-			__FIREHOSE_CLIENT_THROTTLED_DUE_TO_HEAVY_LOGGING__(fb,
-					ask->for_io, &state);
-		} else {
-			firehose_client_send_push_and_wait(fb, ask->for_io, NULL);
-		}
+		firehose_client_send_push(fb, ask->for_io, NULL);
 		if (slowpath(fb->fb_header.fbh_sendp == MACH_PORT_DEAD)) {
 			// logd was unloaded, give up
 			break;
@@ -1180,7 +1108,7 @@
 {
 	firehose_buffer_t fb = kernel_firehose_buffer;
 	if (fastpath(fb)) {
-		firehose_client_merge_updates(fb, true, update, false, NULL);
+		firehose_client_merge_updates(fb, true, update, NULL);
 	}
 }
 #endif // KERNEL
diff --git a/src/firehose/firehose_buffer_internal.h b/src/firehose/firehose_buffer_internal.h
index e41d9cb..7679c8c 100644
--- a/src/firehose/firehose_buffer_internal.h
+++ b/src/firehose/firehose_buffer_internal.h
@@ -171,11 +171,6 @@
 	dispatch_once_t					fbh_notifs_pred OS_ALIGNED(64);
 	dispatch_source_t				fbh_notifs_source;
 	dispatch_unfair_lock_s			fbh_logd_lock;
-#define FBH_QUARANTINE_NONE		0
-#define FBH_QUARANTINE_PENDING	1
-#define FBH_QUARANTINE_STARTED	2
-	uint8_t volatile				fbh_quarantined_state;
-	bool							fbh_quarantined;
 #endif
 	uint64_t						fbh_unused[0];
 } OS_ALIGNED(FIREHOSE_CHUNK_SIZE) *firehose_buffer_header_t;
@@ -192,7 +187,6 @@
 	firehose_stream_t stream;
 	bool	 is_bank_ok;
 	bool     for_io;
-	bool     quarantined;
 	uint64_t stamp;
 } *firehose_tracepoint_query_t;
 
diff --git a/src/firehose/firehose_inline_internal.h b/src/firehose/firehose_inline_internal.h
index 3939ee2..abc5f9e 100644
--- a/src/firehose/firehose_inline_internal.h
+++ b/src/firehose/firehose_inline_internal.h
@@ -319,7 +319,7 @@
 #if KERNEL
 		new_state.fss_allocator = (uint32_t)cpu_number();
 #else
-		new_state.fss_allocator = _dispatch_lock_value_for_self();
+		new_state.fss_allocator = _dispatch_tid_self();
 #endif
 		success = os_atomic_cmpxchgv2o(fbs, fbs_state.fss_atomic_state,
 				old_state.fss_atomic_state, new_state.fss_atomic_state,
@@ -335,9 +335,6 @@
 		.privsize = privsize,
 		.stream = stream,
 		.for_io = (firehose_stream_uses_io_bank & (1UL << stream)) != 0,
-#ifndef KERNEL
-		.quarantined = fb->fb_header.fbh_quarantined,
-#endif
 		.stamp = stamp,
 	};
 	return firehose_buffer_tracepoint_reserve_slow(fb, &ask, privptr);
diff --git a/src/firehose/firehose_internal.h b/src/firehose/firehose_internal.h
index 7040995..29d1ad2 100644
--- a/src/firehose/firehose_internal.h
+++ b/src/firehose/firehose_internal.h
@@ -29,8 +29,6 @@
 #define __MigTypeCheck 1
 #endif
 
-#define fcp_quarntined fcp_quarantined
-
 #include <limits.h>
 #include <machine/endian.h>
 #include <mach/mach_types.h>
diff --git a/src/firehose/firehose_reply.defs b/src/firehose/firehose_reply.defs
index c080545..124defa 100644
--- a/src/firehose/firehose_reply.defs
+++ b/src/firehose/firehose_reply.defs
@@ -33,13 +33,11 @@
 simpleroutine push_reply(
 RequestPort	req_port		: mach_port_move_send_once_t;
 in			rtc				: kern_return_t;
-in			push_reply		: firehose_push_reply_t;
-in			quarantined		: boolean_t
+in			push_reply		: firehose_push_reply_t
 );
 
 simpleroutine push_notify_async(
 RequestPort	comm_port		: mach_port_t;
 in			push_reply		: firehose_push_reply_t;
-in			quarantined		: boolean_t;
 WaitTime	timeout			: natural_t
 );
diff --git a/src/firehose/firehose_server.c b/src/firehose/firehose_server.c
index ba335db..52397d6 100644
--- a/src/firehose/firehose_server.c
+++ b/src/firehose/firehose_server.c
@@ -31,11 +31,6 @@
 		% 8 == 0, "Make sure atomic fields are properly aligned");
 #endif
 
-typedef struct fs_client_queue_s {
-	struct firehose_client_s *volatile fs_client_head;
-	struct firehose_client_s *volatile fs_client_tail;
-} fs_client_queue_s, *fs_client_queue_t;
-
 static struct firehose_server_s {
 	mach_port_t			fs_bootstrap_port;
 	dispatch_mach_t		fs_mach_channel;
@@ -46,161 +41,26 @@
 	firehose_handler_t	fs_handler;
 
 	firehose_snapshot_t fs_snapshot;
+	bool                fs_io_snapshot_started;
+	bool                fs_mem_snapshot_started;
+
 	int					fs_kernel_fd;
 	firehose_client_t	fs_kernel_client;
 
 	TAILQ_HEAD(, firehose_client_s) fs_clients;
-	os_unfair_lock      fs_clients_lock;
-	fs_client_queue_s	fs_queues[4];
-	dispatch_source_t	fs_sources[4];
 } server_config = {
 	.fs_clients = TAILQ_HEAD_INITIALIZER(server_config.fs_clients),
-	.fs_clients_lock = OS_UNFAIR_LOCK_INIT,
 	.fs_kernel_fd = -1,
 };
 
-OS_ALWAYS_INLINE
-static inline void
-fs_clients_lock(void)
-{
-	os_unfair_lock_lock_with_options(&server_config.fs_clients_lock,
-			OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION);
-}
-
-OS_ALWAYS_INLINE
-static inline void
-fs_clients_unlock(void)
-{
-	os_unfair_lock_unlock(&server_config.fs_clients_lock);
-}
+#pragma mark -
+#pragma mark firehose client state machine
 
 static void firehose_server_demux(firehose_client_t fc,
 		mach_msg_header_t *msg_hdr);
 static void firehose_client_cancel(firehose_client_t fc);
 static void firehose_client_snapshot_finish(firehose_client_t fc,
 		firehose_snapshot_t snapshot, bool for_io);
-static void firehose_client_handle_death(void *ctxt);
-
-#pragma mark -
-#pragma mark firehose client enqueueing
-
-OS_ALWAYS_INLINE
-static inline bool
-fs_idx_is_for_io(size_t idx)
-{
-	return idx & 1;
-}
-
-OS_ALWAYS_INLINE
-static inline bool
-fs_queue_is_for_io(fs_client_queue_t q)
-{
-	return (q - server_config.fs_queues) & 1;
-}
-
-OS_ALWAYS_INLINE
-static inline bool
-fs_queue_is_for_quarantined(fs_client_queue_t q)
-{
-	return (q - server_config.fs_queues) & 2;
-}
-
-OS_ALWAYS_INLINE
-static inline fs_client_queue_t
-fs_queue(bool quarantined, bool for_io)
-{
-	return &server_config.fs_queues[quarantined * 2 + for_io];
-}
-
-OS_ALWAYS_INLINE
-static inline dispatch_source_t
-fs_source(bool quarantined, bool for_io)
-{
-	return server_config.fs_sources[quarantined * 2 + for_io];
-}
-
-OS_ALWAYS_INLINE
-static inline void
-firehose_client_push(firehose_client_t fc, pthread_priority_t pp,
-		bool quarantined, bool for_io)
-{
-	fs_client_queue_t queue = fs_queue(quarantined, for_io);
-	if (fc && os_mpsc_push_update_tail(queue, fs_client, fc, fc_next[for_io])) {
-		os_mpsc_push_update_head(queue, fs_client, fc);
-		_dispatch_source_merge_data(fs_source(quarantined, for_io), pp, 1);
-	} else if (pp) {
-		_dispatch_source_merge_data(fs_source(quarantined, for_io), pp, 1);
-	}
-}
-
-OS_ALWAYS_INLINE
-static inline bool
-firehose_client_wakeup(firehose_client_t fc, pthread_priority_t pp,
-		bool for_io)
-{
-	uintptr_t canceled_bit = FC_STATE_CANCELED(for_io);
-	uintptr_t enqueued_bit = FC_STATE_ENQUEUED(for_io);
-	uintptr_t old_state, new_state;
-
-	os_atomic_rmw_loop(&fc->fc_state, old_state, new_state, relaxed, {
-		if (old_state & canceled_bit) {
-			os_atomic_rmw_loop_give_up(return false);
-		}
-		if (old_state & enqueued_bit) {
-			os_atomic_rmw_loop_give_up(break);
-		}
-		new_state = old_state | enqueued_bit;
-	});
-	firehose_client_push(old_state & enqueued_bit ? NULL : fc, pp,
-			fc->fc_quarantined, for_io);
-	return true;
-}
-
-OS_ALWAYS_INLINE
-static inline void
-firehose_client_start_cancel(firehose_client_t fc, bool for_io)
-{
-	uintptr_t canceling_bit = FC_STATE_CANCELING(for_io);
-	uintptr_t canceled_bit = FC_STATE_CANCELED(for_io);
-	uintptr_t enqueued_bit = FC_STATE_ENQUEUED(for_io);
-	uintptr_t old_state, new_state;
-
-	os_atomic_rmw_loop(&fc->fc_state, old_state, new_state, relaxed, {
-		if (old_state & (canceled_bit | canceling_bit)) {
-			os_atomic_rmw_loop_give_up(return);
-		}
-		new_state = old_state | enqueued_bit | canceling_bit;
-	});
-	firehose_client_push(old_state & enqueued_bit ? NULL : fc, 0,
-			fc->fc_quarantined, for_io);
-}
-
-OS_ALWAYS_INLINE
-static inline bool
-firehose_client_dequeue(firehose_client_t fc, bool for_io)
-{
-	uintptr_t canceling_bit = FC_STATE_CANCELING(for_io);
-	uintptr_t canceled_bit = FC_STATE_CANCELED(for_io);
-	uintptr_t enqueued_bit = FC_STATE_ENQUEUED(for_io);
-	uintptr_t old_state, new_state;
-
-	os_atomic_rmw_loop(&fc->fc_state, old_state, new_state, relaxed, {
-		new_state = old_state & ~(canceling_bit | enqueued_bit);
-		if (old_state & canceling_bit) {
-			new_state |= canceled_bit;
-		}
-	});
-
-	if (((old_state ^ new_state) & FC_STATE_CANCELED_MASK) &&
-			(new_state & FC_STATE_CANCELED_MASK) == FC_STATE_CANCELED_MASK) {
-		dispatch_async_f(server_config.fs_io_drain_queue, fc,
-				firehose_client_handle_death);
-	}
-	return !(new_state & canceled_bit);
-}
-
-#pragma mark -
-#pragma mark firehose client state machine
 
 static void
 firehose_client_notify(firehose_client_t fc, mach_port_t reply_port)
@@ -222,11 +82,9 @@
 		}
 	} else {
 		if (reply_port == fc->fc_sendp) {
-			kr = firehose_send_push_notify_async(reply_port, push_reply,
-					fc->fc_quarantined, 0);
+			kr = firehose_send_push_notify_async(reply_port, push_reply, 0);
 		} else {
-			kr = firehose_send_push_reply(reply_port, KERN_SUCCESS, push_reply,
-					fc->fc_quarantined);
+			kr = firehose_send_push_reply(reply_port, KERN_SUCCESS, push_reply);
 		}
 		if (kr != MACH_SEND_INVALID_DEST) {
 			DISPATCH_VERIFY_MIG(kr);
@@ -248,6 +106,18 @@
 	return head;
 }
 
+OS_ALWAYS_INLINE
+static inline void
+firehose_client_push_async_merge(firehose_client_t fc, pthread_priority_t pp,
+		bool for_io)
+{
+	if (for_io) {
+		_dispatch_source_merge_data(fc->fc_io_source, pp, 1);
+	} else {
+		_dispatch_source_merge_data(fc->fc_mem_source, pp, 1);
+	}
+}
+
 OS_NOINLINE OS_COLD
 static void
 firehose_client_mark_corrupted(firehose_client_t fc, mach_port_t reply_port)
@@ -261,7 +131,7 @@
 
 	if (reply_port) {
 		kern_return_t kr = firehose_send_push_reply(reply_port, 0,
-				FIREHOSE_PUSH_REPLY_CORRUPTED, false);
+				FIREHOSE_PUSH_REPLY_CORRUPTED);
 		DISPATCH_VERIFY_MIG(kr);
 		dispatch_assume_zero(kr);
 	}
@@ -286,7 +156,7 @@
 
 OS_NOINLINE
 static void
-firehose_client_drain_one(firehose_client_t fc, mach_port_t port, uint32_t flags)
+firehose_client_drain(firehose_client_t fc, mach_port_t port, uint32_t flags)
 {
 	firehose_buffer_t fb = fc->fc_buffer;
 	firehose_chunk_t fbc;
@@ -304,7 +174,9 @@
 		fbh_ring = fb->fb_header.fbh_io_ring;
 		sent_flushed = (uint16_t)fc->fc_io_sent_flushed_pos;
 		flushed = (uint16_t)fc->fc_io_flushed_pos;
-		if (fc->fc_needs_io_snapshot) snapshot = server_config.fs_snapshot;
+		if (fc->fc_needs_io_snapshot && server_config.fs_io_snapshot_started) {
+			snapshot = server_config.fs_snapshot;
+		}
 	} else {
 		evt = FIREHOSE_EVENT_MEM_BUFFER_RECEIVED;
 		_Static_assert(FIREHOSE_EVENT_MEM_BUFFER_RECEIVED ==
@@ -312,7 +184,9 @@
 		fbh_ring = fb->fb_header.fbh_mem_ring;
 		sent_flushed = (uint16_t)fc->fc_mem_sent_flushed_pos;
 		flushed = (uint16_t)fc->fc_mem_flushed_pos;
-		if (fc->fc_needs_mem_snapshot) snapshot = server_config.fs_snapshot;
+		if (fc->fc_needs_mem_snapshot && server_config.fs_mem_snapshot_started) {
+			snapshot = server_config.fs_snapshot;
+		}
 	}
 
 	if (slowpath(fc->fc_memory_corrupted)) {
@@ -399,12 +273,12 @@
 			// and there's more to drain, so optimistically schedule draining
 			// again this is cheap since the queue is hot, and is fair for other
 			// clients
-			firehose_client_wakeup(fc, 0, for_io);
+			firehose_client_push_async_merge(fc, 0, for_io);
 		}
 		if (count && server_config.fs_kernel_client) {
 			// the kernel is special because it can drop messages, so if we're
 			// draining, poll the kernel each time while we're bound to a thread
-			firehose_client_drain_one(server_config.fs_kernel_client,
+			firehose_client_drain(server_config.fs_kernel_client,
 					MACH_PORT_NULL, flags | FIREHOSE_DRAIN_POLL);
 		}
 	}
@@ -419,36 +293,20 @@
 	// (needs_<for_io>_snapshot: false, memory_corrupted: true). we can safely
 	// silence the corresponding source of drain wake-ups.
 	if (fc->fc_pid) {
-		firehose_client_start_cancel(fc, for_io);
+		dispatch_source_cancel(for_io ? fc->fc_io_source : fc->fc_mem_source);
 	}
 }
 
 static void
-firehose_client_drain(void *ctxt)
+firehose_client_drain_io_async(void *ctx)
 {
-	fs_client_queue_t queue = ctxt;
-	bool for_io = fs_queue_is_for_io(queue);
-	bool quarantined = fs_queue_is_for_quarantined(queue);
-	firehose_client_t fc, fc_next;
-	size_t clients = 0;
+	firehose_client_drain(ctx, MACH_PORT_NULL, FIREHOSE_DRAIN_FOR_IO);
+}
 
-	while (queue->fs_client_tail) {
-		fc = os_mpsc_get_head(queue, fs_client);
-		do {
-			fc_next = os_mpsc_pop_head(queue, fs_client, fc, fc_next[for_io]);
-			if (firehose_client_dequeue(fc, for_io)) {
-				firehose_client_drain_one(fc, MACH_PORT_NULL,
-						for_io ? FIREHOSE_DRAIN_FOR_IO : 0);
-			}
-			// process quarantined clients 4 times as slow as the other ones
-			// also reasyncing every 4 clients allows for discovering
-			// quarantined suspension faster
-			if (++clients == (quarantined ? 1 : 4)) {
-				dispatch_source_merge_data(fs_source(quarantined, for_io), 1);
-				return;
-			}
-		} while ((fc = fc_next));
-	}
+static void
+firehose_client_drain_mem_async(void *ctx)
+{
+	firehose_client_drain(ctx, MACH_PORT_NULL, 0);
 }
 
 OS_NOINLINE
@@ -477,10 +335,7 @@
 	}
 	server_config.fs_handler(fc, FIREHOSE_EVENT_CLIENT_DIED, NULL);
 
-	fs_clients_lock();
 	TAILQ_REMOVE(&server_config.fs_clients, fc, fc_entry);
-	fs_clients_unlock();
-
 	dispatch_release(fc->fc_mach_channel);
 	fc->fc_mach_channel = NULL;
 	fc->fc_entry.tqe_next = DISPATCH_OBJECT_LISTLESS;
@@ -558,7 +413,7 @@
 			continue;
 		}
 		server_config.fs_handler(fc, FIREHOSE_EVENT_IO_BUFFER_RECEIVED, fbc);
-		if (fc->fc_needs_io_snapshot) {
+		if (fc->fc_needs_io_snapshot && server_config.fs_io_snapshot_started) {
 			snapshot->handler(fc, FIREHOSE_SNAPSHOT_EVENT_IO_BUFFER, fbc);
 		}
 	}
@@ -576,7 +431,7 @@
 
 			mem_bitmap_copy &= ~(1ULL << ref);
 			server_config.fs_handler(fc, FIREHOSE_EVENT_MEM_BUFFER_RECEIVED, fbc);
-			if (fc->fc_needs_mem_snapshot) {
+			if (fc->fc_needs_mem_snapshot && server_config.fs_mem_snapshot_started) {
 				snapshot->handler(fc, FIREHOSE_SNAPSHOT_EVENT_MEM_BUFFER, fbc);
 			}
 		}
@@ -592,11 +447,16 @@
 {
 	mach_msg_header_t *msg_hdr = NULL;
 	firehose_client_t fc = ctx;
-	mach_port_t port;
+	mach_port_t oldsendp = 0, oldrecvp = 0;
+
+	if (dmsg) {
+		msg_hdr = dispatch_mach_msg_get_msg(dmsg, NULL);
+		oldsendp = msg_hdr->msgh_remote_port;
+		oldrecvp = msg_hdr->msgh_local_port;
+	}
 
 	switch (reason) {
 	case DISPATCH_MACH_MESSAGE_RECEIVED:
-		msg_hdr = dispatch_mach_msg_get_msg(dmsg, NULL);
 		if (msg_hdr->msgh_id == MACH_NOTIFY_NO_SENDERS) {
 			_dispatch_debug("FIREHOSE NO_SENDERS (unique_pid: 0x%llx)",
 					firehose_client_get_unique_pid(fc, NULL));
@@ -607,33 +467,25 @@
 		break;
 
 	case DISPATCH_MACH_DISCONNECTED:
-		msg_hdr = dispatch_mach_msg_get_msg(dmsg, NULL);
-		port = msg_hdr->msgh_remote_port;
-		if (MACH_PORT_VALID(port)) {
-			if (port != fc->fc_sendp) {
-				DISPATCH_INTERNAL_CRASH(port, "Unknown send-right");
+		if (oldsendp) {
+			if (slowpath(oldsendp != fc->fc_sendp)) {
+				DISPATCH_INTERNAL_CRASH(oldsendp,
+						"disconnect event about unknown send-right");
 			}
 			firehose_mach_port_send_release(fc->fc_sendp);
 			fc->fc_sendp = MACH_PORT_NULL;
 		}
-		port = msg_hdr->msgh_local_port;
-		if (MACH_PORT_VALID(port)) {
-			if (port != fc->fc_recvp) {
-				DISPATCH_INTERNAL_CRASH(port, "Unknown recv-right");
+		if (oldrecvp) {
+			if (slowpath(oldrecvp != fc->fc_recvp)) {
+				DISPATCH_INTERNAL_CRASH(oldrecvp,
+						"disconnect event about unknown receive-right");
 			}
 			firehose_mach_port_recv_dispose(fc->fc_recvp, fc);
 			fc->fc_recvp = MACH_PORT_NULL;
 		}
-		break;
-
-	case DISPATCH_MACH_CANCELED:
-		if (MACH_PORT_VALID(fc->fc_sendp)) {
-			DISPATCH_INTERNAL_CRASH(fc->fc_sendp, "send-right leak");
+		if (fc->fc_recvp == MACH_PORT_NULL && fc->fc_sendp == MACH_PORT_NULL) {
+			firehose_client_cancel(fc);
 		}
-		if (MACH_PORT_VALID(fc->fc_recvp)) {
-			DISPATCH_INTERNAL_CRASH(fc->fc_recvp, "recv-right leak");
-		}
-		firehose_client_cancel(fc);
 		break;
 	}
 }
@@ -647,8 +499,10 @@
 	// resumed in firehose_client_drain for both memory and I/O
 	dispatch_suspend(fc->fc_kernel_source);
 	dispatch_suspend(fc->fc_kernel_source);
-	firehose_client_wakeup(fc, 0, false);
-	firehose_client_wakeup(fc, 0, true);
+	dispatch_async_f(server_config.fs_mem_drain_queue,
+			fc, firehose_client_drain_mem_async);
+	dispatch_async_f(server_config.fs_io_drain_queue,
+			fc, firehose_client_drain_io_async);
 }
 #endif
 
@@ -657,37 +511,36 @@
 		const struct firehose_client_connected_info_s *fcci)
 {
 	dispatch_assert_queue(server_config.fs_io_drain_queue);
-
-	fs_clients_lock();
 	TAILQ_INSERT_TAIL(&server_config.fs_clients, fc, fc_entry);
-	fs_clients_unlock();
-
 	server_config.fs_handler(fc, FIREHOSE_EVENT_CLIENT_CONNECTED, (void *)fcci);
 	if (!fc->fc_pid) {
 		dispatch_activate(fc->fc_kernel_source);
 	} else {
 		dispatch_mach_connect(fc->fc_mach_channel,
 				fc->fc_recvp, fc->fc_sendp, NULL);
+		dispatch_activate(fc->fc_io_source);
+		dispatch_activate(fc->fc_mem_source);
 	}
 }
 
 static void
 firehose_client_cancel(firehose_client_t fc)
 {
+	dispatch_block_t block;
+
 	_dispatch_debug("client died (unique_pid: 0x%llx",
 			firehose_client_get_unique_pid(fc, NULL));
 
-	if (MACH_PORT_VALID(fc->fc_sendp)) {
-		firehose_mach_port_send_release(fc->fc_sendp);
-		fc->fc_sendp = MACH_PORT_NULL;
-	}
-	if (MACH_PORT_VALID(fc->fc_recvp)) {
-		firehose_mach_port_recv_dispose(fc->fc_recvp, fc);
-		fc->fc_recvp = MACH_PORT_NULL;
-	}
 	fc->fc_use_notifs = false;
-	firehose_client_start_cancel(fc, false);
-	firehose_client_start_cancel(fc, true);
+	dispatch_source_cancel(fc->fc_io_source);
+	dispatch_source_cancel(fc->fc_mem_source);
+
+	block = dispatch_block_create(DISPATCH_BLOCK_DETACHED, ^{
+		dispatch_async_f(server_config.fs_io_drain_queue, fc,
+				firehose_client_handle_death);
+	});
+	dispatch_async(server_config.fs_mem_drain_queue, block);
+	_Block_release(block);
 }
 
 static firehose_client_t
@@ -725,10 +578,28 @@
 	uint64_t unique_pid = fb->fb_header.fbh_uniquepid;
 	firehose_client_t fc = _firehose_client_create(fb);
 	dispatch_mach_t dm;
+	dispatch_source_t ds;
 
 	fc->fc_pid = token->pid ? token->pid : ~0;
 	fc->fc_euid = token->euid;
 	fc->fc_pidversion = token->execcnt;
+	ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_OR, 0, 0,
+			server_config.fs_mem_drain_queue);
+	_os_object_retain_internal_inline(&fc->fc_as_os_object);
+	dispatch_set_context(ds, fc);
+	dispatch_set_finalizer_f(ds,
+			(dispatch_function_t)_os_object_release_internal);
+	dispatch_source_set_event_handler_f(ds, firehose_client_drain_mem_async);
+	fc->fc_mem_source = ds;
+
+	ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_OR, 0, 0,
+			server_config.fs_io_drain_queue);
+	_os_object_retain_internal_inline(&fc->fc_as_os_object);
+	dispatch_set_context(ds, fc);
+	dispatch_set_finalizer_f(ds,
+			(dispatch_function_t)_os_object_release_internal);
+	dispatch_source_set_event_handler_f(ds, firehose_client_drain_io_async);
+	fc->fc_io_source = ds;
 
 	_dispatch_debug("FIREHOSE_REGISTER (unique_pid: 0x%llx)", unique_pid);
 	fc->fc_recvp = comm_recvp;
@@ -801,6 +672,12 @@
 {
 	_dispatch_debug("Cleaning up client info for unique_pid 0x%llx",
 			firehose_client_get_unique_pid(fc, NULL));
+
+	dispatch_release(fc->fc_io_source);
+	fc->fc_io_source = NULL;
+
+	dispatch_release(fc->fc_mem_source);
+	fc->fc_mem_source = NULL;
 }
 
 uint64_t
@@ -845,12 +722,6 @@
 	return os_atomic_xchg2o(fc, fc_ctxt, ctxt, relaxed);
 }
 
-void
-firehose_client_initiate_quarantine(firehose_client_t fc)
-{
-	fc->fc_quarantined = true;
-}
-
 #pragma mark -
 #pragma mark firehose server
 
@@ -879,24 +750,22 @@
 firehose_server_init(mach_port_t comm_port, firehose_handler_t handler)
 {
 	struct firehose_server_s *fs = &server_config;
-	dispatch_queue_attr_t attr = DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL;
-	dispatch_queue_attr_t attr_ui;
+	dispatch_queue_attr_t attr;
 	dispatch_mach_t dm;
-	dispatch_source_t ds;
 
 	// just reference the string so that it's captured
 	(void)os_atomic_load(&__libfirehose_serverVersionString[0], relaxed);
 
-	attr_ui = dispatch_queue_attr_make_with_qos_class(attr,
+	attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL,
 			QOS_CLASS_USER_INITIATED, 0);
 	fs->fs_ipc_queue = dispatch_queue_create_with_target(
-			"com.apple.firehose.ipc", attr_ui, NULL);
+			"com.apple.firehose.ipc", attr, NULL);
 	fs->fs_snapshot_gate_queue = dispatch_queue_create_with_target(
-			"com.apple.firehose.snapshot-gate", attr, NULL);
+			"com.apple.firehose.snapshot-gate", DISPATCH_QUEUE_SERIAL, NULL);
 	fs->fs_io_drain_queue = dispatch_queue_create_with_target(
-			"com.apple.firehose.drain-io", attr, NULL);
+			"com.apple.firehose.drain-io", DISPATCH_QUEUE_SERIAL, NULL);
 	fs->fs_mem_drain_queue = dispatch_queue_create_with_target(
-			"com.apple.firehose.drain-mem", attr, NULL);
+			"com.apple.firehose.drain-mem", DISPATCH_QUEUE_SERIAL, NULL);
 
 	dm = dispatch_mach_create_f("com.apple.firehose.listener",
 			fs->fs_ipc_queue, NULL, firehose_server_handle_mach_event);
@@ -904,15 +773,6 @@
 	fs->fs_mach_channel = dm;
 	fs->fs_handler = _Block_copy(handler);
 	firehose_kernel_client_create();
-
-	for (size_t i = 0; i < countof(fs->fs_sources); i++) {
-		ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_OR, 0, 0,
-				fs_idx_is_for_io(i) ? server_config.fs_io_drain_queue :
-				server_config.fs_mem_drain_queue);
-		dispatch_set_context(ds, &fs->fs_queues[i]);
-		dispatch_source_set_event_handler_f(ds, firehose_client_drain);
-		fs->fs_sources[i] = ds;
-	}
 }
 
 void
@@ -956,23 +816,24 @@
 	}
 	dispatch_mach_connect(fs->fs_mach_channel, fs->fs_bootstrap_port,
 			MACH_PORT_NULL, NULL);
-	for (size_t i = 0; i < countof(fs->fs_sources); i++) {
-		dispatch_activate(fs->fs_sources[i]);
+}
+
+OS_NOINLINE
+static void
+_firehose_server_cancel(void *ctxt OS_UNUSED)
+{
+	firehose_client_t fc;
+	TAILQ_FOREACH(fc, &server_config.fs_clients, fc_entry) {
+		dispatch_mach_cancel(fc->fc_mach_channel);
 	}
 }
 
 void
 firehose_server_cancel(void)
 {
-	firehose_client_t fc;
-
 	dispatch_mach_cancel(server_config.fs_mach_channel);
-
-	fs_clients_lock();
-	TAILQ_FOREACH(fc, &server_config.fs_clients, fc_entry) {
-		dispatch_mach_cancel(fc->fc_mach_channel);
-	}
-	fs_clients_unlock();
+	dispatch_async_f(server_config.fs_io_drain_queue, NULL,
+			_firehose_server_cancel);
 }
 
 dispatch_queue_t
@@ -993,37 +854,6 @@
 	return dq;
 }
 
-void
-firehose_server_quarantined_suspend(firehose_server_queue_t which)
-{
-	switch (which) {
-	case FIREHOSE_SERVER_QUEUE_IO:
-		dispatch_suspend(fs_source(true, true));
-		break;
-	case FIREHOSE_SERVER_QUEUE_MEMORY:
-		dispatch_suspend(fs_source(true, false));
-		break;
-	default:
-		DISPATCH_INTERNAL_CRASH(which, "Invalid firehose server queue type");
-	}
-}
-
-void
-firehose_server_quarantined_resume(firehose_server_queue_t which)
-{
-	switch (which) {
-	case FIREHOSE_SERVER_QUEUE_IO:
-		dispatch_resume(fs_source(true, true));
-		break;
-	case FIREHOSE_SERVER_QUEUE_MEMORY:
-		dispatch_resume(fs_source(true, false));
-		break;
-	default:
-		DISPATCH_INTERNAL_CRASH(which, "Invalid firehose server queue type");
-	}
-}
-
-
 #pragma mark -
 #pragma mark firehose snapshot and peeking
 
@@ -1136,35 +966,73 @@
 }
 
 static void
-firehose_snapshot_tickle_clients(firehose_snapshot_t fs, bool for_io)
+firehose_snapshot_start(void *ctxt)
 {
-	firehose_client_t fc;
+	firehose_snapshot_t snapshot = ctxt;
+	firehose_client_t fci;
 	long n = 0;
 
-	fs_clients_lock();
-	TAILQ_FOREACH(fc, &server_config.fs_clients, fc_entry) {
-		if (slowpath(fc->fc_memory_corrupted)) {
-			continue;
-		}
-		if (!fc->fc_pid) {
+	// 0. we need to be on the IO queue so that client connection and/or death
+	//    cannot happen concurrently
+	dispatch_assert_queue(server_config.fs_io_drain_queue);
+	server_config.fs_snapshot = snapshot;
+
+	// 1. mark all the clients participating in the current snapshot
+	//    and enter the group for each bit set
+	TAILQ_FOREACH(fci, &server_config.fs_clients, fc_entry) {
+		if (!fci->fc_pid) {
 #if TARGET_OS_SIMULATOR
 			continue;
 #endif
-		} else if (!firehose_client_wakeup(fc, 0, for_io)) {
+		}
+		if (slowpath(fci->fc_memory_corrupted)) {
 			continue;
 		}
-		n++;
-		if (for_io) {
-			fc->fc_needs_io_snapshot = true;
-		} else {
-			fc->fc_needs_mem_snapshot = true;
-		}
+		fci->fc_needs_io_snapshot = true;
+		fci->fc_needs_mem_snapshot = true;
+		n += 2;
 	}
-	fs_clients_unlock();
+	if (n) {
+		// cheating: equivalent to dispatch_group_enter() n times
+		// without the acquire barriers that we don't need
+		os_atomic_add2o(snapshot->fs_group, dg_value, n, relaxed);
+	}
 
-	// cheating: equivalent to dispatch_group_enter() n times
-	// without the acquire barriers that we don't need
-	if (n) os_atomic_add2o(fs->fs_group, dg_value, n, relaxed);
+	dispatch_async(server_config.fs_mem_drain_queue, ^{
+		// 2. start the fs_mem_snapshot, this is what triggers the snapshot
+		//    logic from _drain() or handle_death()
+		server_config.fs_mem_snapshot_started = true;
+		snapshot->handler(NULL, FIREHOSE_SNAPSHOT_EVENT_MEM_START, NULL);
+
+		dispatch_async(server_config.fs_io_drain_queue, ^{
+			firehose_client_t fcj;
+
+			// 3. start the fs_io_snapshot, this is what triggers the snapshot
+			//    logic from _drain() or handle_death()
+			//    29868879: must always happen after the memory snapshot started
+			server_config.fs_io_snapshot_started = true;
+			snapshot->handler(NULL, FIREHOSE_SNAPSHOT_EVENT_IO_START, NULL);
+
+			// match group_enter from firehose_snapshot() after MEM+IO_START
+			dispatch_group_leave(snapshot->fs_group);
+
+			// 3. tickle all the clients. the list of clients may have changed
+			//    since step 1, but worry not - new clients don't have
+			//    fc_needs_*_snapshot set so drain is harmless; clients that
+			//    were removed from the list have already left the group
+			//    (see firehose_client_finalize())
+			TAILQ_FOREACH(fcj, &server_config.fs_clients, fc_entry) {
+				if (!fcj->fc_pid) {
+#if !TARGET_OS_SIMULATOR
+					firehose_client_kernel_source_handle_event(fcj);
+#endif
+				} else {
+					dispatch_source_merge_data(fcj->fc_io_source, 1);
+					dispatch_source_merge_data(fcj->fc_mem_source, 1);
+				}
+			}
+		});
+	});
 }
 
 static void
@@ -1174,6 +1042,8 @@
 
 	fs->handler(NULL, FIREHOSE_SNAPSHOT_EVENT_COMPLETE, NULL);
 	server_config.fs_snapshot = NULL;
+	server_config.fs_mem_snapshot_started = false;
+	server_config.fs_io_snapshot_started = false;
 
 	dispatch_release(fs->fs_group);
 	Block_release(fs->handler);
@@ -1186,37 +1056,10 @@
 static void
 firehose_snapshot_gate(void *ctxt)
 {
-	firehose_snapshot_t fs = ctxt;
-
 	// prevent other snapshots from running until done
-
 	dispatch_suspend(server_config.fs_snapshot_gate_queue);
-
-	server_config.fs_snapshot = fs;
-	dispatch_group_async(fs->fs_group, server_config.fs_mem_drain_queue, ^{
-		// start the fs_mem_snapshot, this is what triggers the snapshot
-		// logic from _drain() or handle_death()
-		fs->handler(NULL, FIREHOSE_SNAPSHOT_EVENT_MEM_START, NULL);
-		firehose_snapshot_tickle_clients(fs, false);
-
-		dispatch_group_async(fs->fs_group, server_config.fs_io_drain_queue, ^{
-			// start the fs_io_snapshot, this is what triggers the snapshot
-			// logic from _drain() or handle_death()
-			// 29868879: must always happen after the memory snapshot started
-			fs->handler(NULL, FIREHOSE_SNAPSHOT_EVENT_IO_START, NULL);
-			firehose_snapshot_tickle_clients(fs, true);
-
-#if !TARGET_OS_SIMULATOR
-			if (server_config.fs_kernel_client) {
-				firehose_client_kernel_source_handle_event(
-						server_config.fs_kernel_client);
-			}
-#endif
-		});
-	});
-
-	dispatch_group_notify_f(fs->fs_group, server_config.fs_io_drain_queue,
-			fs, firehose_snapshot_finish);
+	dispatch_async_f(server_config.fs_io_drain_queue, ctxt,
+			firehose_snapshot_start);
 }
 
 void
@@ -1227,6 +1070,12 @@
 	snapshot->handler = Block_copy(handler);
 	snapshot->fs_group = dispatch_group_create();
 
+	// keep the group entered until IO_START and MEM_START have been sent
+	// See firehose_snapshot_start()
+	dispatch_group_enter(snapshot->fs_group);
+	dispatch_group_notify_f(snapshot->fs_group, server_config.fs_io_drain_queue,
+			snapshot, firehose_snapshot_finish);
+
 	dispatch_async_f(server_config.fs_snapshot_gate_queue, snapshot,
 			firehose_snapshot_gate);
 }
@@ -1317,16 +1166,15 @@
 		if (expects_notifs && !fc->fc_use_notifs) {
 			fc->fc_use_notifs = true;
 		}
-		firehose_client_wakeup(fc, pp, for_io);
+		firehose_client_push_async_merge(fc, pp, for_io);
 	}
 	return KERN_SUCCESS;
 }
 
 kern_return_t
-firehose_server_push_and_wait(mach_port_t server_port OS_UNUSED,
+firehose_server_push(mach_port_t server_port OS_UNUSED,
 		mach_port_t reply_port, qos_class_t qos, boolean_t for_io,
-		firehose_push_reply_t *push_reply OS_UNUSED,
-		boolean_t *quarantinedOut OS_UNUSED)
+		firehose_push_reply_t *push_reply OS_UNUSED)
 {
 	firehose_client_t fc = cur_client_info;
 	dispatch_block_flags_t flags = DISPATCH_BLOCK_ENFORCE_QOS_CLASS;
@@ -1348,7 +1196,7 @@
 	}
 
 	block = dispatch_block_create_with_qos_class(flags, qos, 0, ^{
-		firehose_client_drain_one(fc, reply_port,
+		firehose_client_drain(fc, reply_port,
 				for_io ? FIREHOSE_DRAIN_FOR_IO : 0);
 	});
 	dispatch_async(q, block);
diff --git a/src/firehose/firehose_server_internal.h b/src/firehose/firehose_server_internal.h
index 13f52b8..d805167 100644
--- a/src/firehose/firehose_server_internal.h
+++ b/src/firehose/firehose_server_internal.h
@@ -36,7 +36,6 @@
 		struct _os_object_s fc_as_os_object;
 	};
 	TAILQ_ENTRY(firehose_client_s) fc_entry;
-	struct firehose_client_s *volatile fc_next[2];
 
 	firehose_buffer_t	fc_buffer;
 	uint64_t volatile	fc_mem_sent_flushed_pos;
@@ -44,27 +43,14 @@
 	uint64_t volatile	fc_io_sent_flushed_pos;
 	uint64_t volatile	fc_io_flushed_pos;
 
-#define FC_STATE_ENQUEUED(for_io)      (0x0001u << (for_io))
-#define FC_STATE_MEM_ENQUEUED           0x0001
-#define FC_STATE_IO_ENQUEUED            0x0002
-
-#define FC_STATE_CANCELING(for_io)     (0x0010u << (for_io))
-#define FC_STATE_MEM_CANCELING          0x0010
-#define FC_STATE_IO_CANCELING           0x0020
-
-#define FC_STATE_CANCELED(for_io)      (0x0100u << (for_io))
-#define FC_STATE_MEM_CANCELED           0x0100
-#define FC_STATE_IO_CANCELED            0x0200
-#define FC_STATE_CANCELED_MASK          0x0300
-
-	uintptr_t volatile	fc_state;
-
 	void *volatile		fc_ctxt;
 
 	union {
 		dispatch_mach_t	fc_mach_channel;
 		dispatch_source_t fc_kernel_source;
 	};
+	dispatch_source_t	fc_io_source;
+	dispatch_source_t	fc_mem_source;
 	mach_port_t			fc_recvp;
 	mach_port_t			fc_sendp;
 	os_unfair_lock      fc_lock;
@@ -75,7 +61,6 @@
 	bool				fc_memory_corrupted;
 	bool				fc_needs_io_snapshot;
 	bool				fc_needs_mem_snapshot;
-	bool				fc_quarantined;
 };
 
 void
diff --git a/src/init.c b/src/init.c
index dea5e87..22a61e3 100644
--- a/src/init.c
+++ b/src/init.c
@@ -21,8 +21,6 @@
 // Contains exported global data and initialization & other routines that must
 // only exist once in the shared library even when resolvers are used.
 
-// NOTE: this file must not contain any atomic operations
-
 #include "internal.h"
 
 #if HAVE_MACH
@@ -148,6 +146,10 @@
 #if DISPATCH_USE_KEVENT_WORKQUEUE && DISPATCH_USE_MGR_THREAD
 int _dispatch_kevent_workqueue_enabled;
 #endif
+#if DISPATCH_USE_EVFILT_MACHPORT_DIRECT && \
+		DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+int _dispatch_evfilt_machport_direct_enabled;
+#endif
 
 DISPATCH_HW_CONFIG();
 uint8_t _dispatch_unsafe_fork;
@@ -171,6 +173,33 @@
 	return _dispatch_child_of_unsafe_fork;
 }
 
+DISPATCH_NOINLINE
+void
+_dispatch_fork_becomes_unsafe_slow(void)
+{
+	uint8_t value = os_atomic_or(&_dispatch_unsafe_fork,
+			_DISPATCH_UNSAFE_FORK_MULTITHREADED, relaxed);
+	if (value & _DISPATCH_UNSAFE_FORK_PROHIBIT) {
+		DISPATCH_CLIENT_CRASH(0, "Transition to multithreaded is prohibited");
+	}
+}
+
+DISPATCH_NOINLINE
+void
+_dispatch_prohibit_transition_to_multithreaded(bool prohibit)
+{
+	if (prohibit) {
+		uint8_t value = os_atomic_or(&_dispatch_unsafe_fork,
+				_DISPATCH_UNSAFE_FORK_PROHIBIT, relaxed);
+		if (value & _DISPATCH_UNSAFE_FORK_MULTITHREADED) {
+			DISPATCH_CLIENT_CRASH(0, "The executable is already multithreaded");
+		}
+	} else {
+		os_atomic_and(&_dispatch_unsafe_fork,
+				(uint8_t)~_DISPATCH_UNSAFE_FORK_PROHIBIT, relaxed);
+	}
+}
+
 const struct dispatch_queue_offsets_s dispatch_queue_offsets = {
 	.dqo_version = 6,
 	.dqo_label = offsetof(struct dispatch_queue_s, dq_label),
@@ -209,10 +238,10 @@
 	.do_targetq = &_dispatch_root_queues[
 			DISPATCH_ROOT_QUEUE_IDX_DEFAULT_QOS_OVERCOMMIT],
 #endif
-	.dq_state = DISPATCH_QUEUE_STATE_INIT_VALUE(1) |
-			DISPATCH_QUEUE_ROLE_BASE_ANON,
+	.dq_state = DISPATCH_QUEUE_STATE_INIT_VALUE(1),
 	.dq_label = "com.apple.main-thread",
 	.dq_atomic_flags = DQF_THREAD_BOUND | DQF_CANNOT_TRYSYNC | DQF_WIDTH(1),
+	.dq_wlh = DISPATCH_WLH_GLOBAL, // TODO: main thread wlh
 	.dq_serialnum = 1,
 };
 
@@ -397,7 +426,6 @@
 	.do_debug = dispatch_queue_debug,
 );
 
-
 DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_main, queue,
 	.do_type = DISPATCH_QUEUE_SERIAL_TYPE,
 	.do_kind = "main-queue",
@@ -421,7 +449,7 @@
 DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_mgr, queue,
 	.do_type = DISPATCH_QUEUE_MGR_TYPE,
 	.do_kind = "mgr-queue",
-	.do_push = _dispatch_mgr_queue_push,
+	.do_push = _dispatch_queue_push,
 	.do_invoke = _dispatch_mgr_thread,
 	.do_wakeup = _dispatch_mgr_queue_wakeup,
 	.do_debug = dispatch_queue_debug,
@@ -486,7 +514,6 @@
 	.do_kind = "data",
 	.do_dispose = _dispatch_data_dispose,
 	.do_debug = _dispatch_data_debug,
-	.do_set_targetq = (void*)_dispatch_data_set_target_queue,
 );
 #endif
 
@@ -525,41 +552,6 @@
 }
 
 #pragma mark -
-#pragma mark dispatch_data globals
-
-const dispatch_block_t _dispatch_data_destructor_free = ^{
-	DISPATCH_INTERNAL_CRASH(0, "free destructor called");
-};
-
-const dispatch_block_t _dispatch_data_destructor_none = ^{
-	DISPATCH_INTERNAL_CRASH(0, "none destructor called");
-};
-
-#if !HAVE_MACH
-const dispatch_block_t _dispatch_data_destructor_munmap = ^{
-	DISPATCH_INTERNAL_CRASH(0, "munmap destructor called");
-};
-#else
-// _dispatch_data_destructor_munmap is a linker alias to the following
-const dispatch_block_t _dispatch_data_destructor_vm_deallocate = ^{
-	DISPATCH_INTERNAL_CRASH(0, "vmdeallocate destructor called");
-};
-#endif
-
-const dispatch_block_t _dispatch_data_destructor_inline = ^{
-	DISPATCH_INTERNAL_CRASH(0, "inline destructor called");
-};
-
-struct dispatch_data_s _dispatch_data_empty = {
-#if DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
-	.do_vtable = DISPATCH_DATA_EMPTY_CLASS,
-#else
-	DISPATCH_GLOBAL_OBJECT_HEADER(data),
-	.do_next = DISPATCH_OBJECT_LISTLESS,
-#endif
-};
-
-#pragma mark -
 #pragma mark dispatch_bug
 
 static char _dispatch_build[16];
@@ -1155,17 +1147,16 @@
 	}
 }
 
-void
-_dispatch_last_resort_autorelease_pool_push(dispatch_invoke_context_t dic)
+void*
+_dispatch_last_resort_autorelease_pool_push(void)
 {
-	dic->dic_autorelease_pool = _dispatch_autorelease_pool_push();
+	return _dispatch_autorelease_pool_push();
 }
 
 void
-_dispatch_last_resort_autorelease_pool_pop(dispatch_invoke_context_t dic)
+_dispatch_last_resort_autorelease_pool_pop(void *pool)
 {
-	_dispatch_autorelease_pool_pop(dic->dic_autorelease_pool);
-	dic->dic_autorelease_pool = NULL;
+	_dispatch_autorelease_pool_pop(pool);
 }
 
 #endif // DISPATCH_COCOA_COMPAT
@@ -1208,16 +1199,22 @@
 _dispatch_mach_notify_port_destroyed(mach_port_t notify DISPATCH_UNUSED,
 		mach_port_t name)
 {
-	DISPATCH_INTERNAL_CRASH(name, "unexpected receipt of port-destroyed");
-	return KERN_FAILURE;
+	kern_return_t kr;
+	// this function should never be called
+	(void)dispatch_assume_zero(name);
+	kr = mach_port_mod_refs(mach_task_self(), name, MACH_PORT_RIGHT_RECEIVE,-1);
+	DISPATCH_VERIFY_MIG(kr);
+	(void)dispatch_assume_zero(kr);
+	return KERN_SUCCESS;
 }
 
 kern_return_t
-_dispatch_mach_notify_no_senders(mach_port_t notify DISPATCH_UNUSED,
-		mach_port_mscount_t mscnt)
+_dispatch_mach_notify_no_senders(mach_port_t notify,
+		mach_port_mscount_t mscnt DISPATCH_UNUSED)
 {
-	DISPATCH_INTERNAL_CRASH(mscnt, "unexpected receipt of no-more-senders");
-	return KERN_FAILURE;
+	// this function should never be called
+	(void)dispatch_assume_zero(notify);
+	return KERN_SUCCESS;
 }
 
 kern_return_t
diff --git a/src/inline_internal.h b/src/inline_internal.h
index 0ed9e51..53548ed 100644
--- a/src/inline_internal.h
+++ b/src/inline_internal.h
@@ -101,13 +101,6 @@
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
-_dispatch_object_is_queue(dispatch_object_t dou)
-{
-	return _dispatch_object_has_vtable(dou) && dx_vtable(dou._do)->do_push;
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline bool
 _dispatch_object_is_continuation(dispatch_object_t dou)
 {
 	if (_dispatch_object_has_vtable(dou)) {
@@ -174,9 +167,9 @@
 
 DISPATCH_ALWAYS_INLINE
 static inline _os_object_t
-_os_object_retain_internal_n_inline(_os_object_t obj, int n)
+_os_object_retain_internal_inline(_os_object_t obj)
 {
-	int ref_cnt = _os_object_refcnt_add(obj, n);
+	int ref_cnt = _os_object_refcnt_inc(obj);
 	if (unlikely(ref_cnt <= 0)) {
 		_OS_OBJECT_CLIENT_CRASH("Resurrection of an object");
 	}
@@ -185,20 +178,23 @@
 
 DISPATCH_ALWAYS_INLINE
 static inline void
-_os_object_release_internal_n_no_dispose_inline(_os_object_t obj, int n)
+_os_object_release_internal_inline_no_dispose(_os_object_t obj)
 {
-	int ref_cnt = _os_object_refcnt_sub(obj, n);
+	int ref_cnt = _os_object_refcnt_dec(obj);
 	if (likely(ref_cnt >= 0)) {
 		return;
 	}
+	if (ref_cnt == 0) {
+		_OS_OBJECT_CLIENT_CRASH("Unexpected release of an object");
+	}
 	_OS_OBJECT_CLIENT_CRASH("Over-release of an object");
 }
 
 DISPATCH_ALWAYS_INLINE
 static inline void
-_os_object_release_internal_n_inline(_os_object_t obj, int n)
+_os_object_release_internal_inline(_os_object_t obj)
 {
-	int ref_cnt = _os_object_refcnt_sub(obj, n);
+	int ref_cnt = _os_object_refcnt_dec(obj);
 	if (likely(ref_cnt >= 0)) {
 		return;
 	}
@@ -220,56 +216,14 @@
 static inline void
 _dispatch_retain(dispatch_object_t dou)
 {
-	(void)_os_object_retain_internal_n_inline(dou._os_obj, 1);
-}
-
-DISPATCH_ALWAYS_INLINE_NDEBUG
-static inline void
-_dispatch_retain_2(dispatch_object_t dou)
-{
-	(void)_os_object_retain_internal_n_inline(dou._os_obj, 2);
-}
-
-DISPATCH_ALWAYS_INLINE_NDEBUG
-static inline void
-_dispatch_retain_n(dispatch_object_t dou, int n)
-{
-	(void)_os_object_retain_internal_n_inline(dou._os_obj, n);
+	(void)_os_object_retain_internal_inline(dou._os_obj);
 }
 
 DISPATCH_ALWAYS_INLINE_NDEBUG
 static inline void
 _dispatch_release(dispatch_object_t dou)
 {
-	_os_object_release_internal_n_inline(dou._os_obj, 1);
-}
-
-DISPATCH_ALWAYS_INLINE_NDEBUG
-static inline void
-_dispatch_release_2(dispatch_object_t dou)
-{
-	_os_object_release_internal_n_inline(dou._os_obj, 2);
-}
-
-DISPATCH_ALWAYS_INLINE_NDEBUG
-static inline void
-_dispatch_release_n(dispatch_object_t dou, int n)
-{
-	_os_object_release_internal_n_inline(dou._os_obj, n);
-}
-
-DISPATCH_ALWAYS_INLINE_NDEBUG
-static inline void
-_dispatch_release_no_dispose(dispatch_object_t dou)
-{
-	_os_object_release_internal_n_no_dispose_inline(dou._os_obj, 1);
-}
-
-DISPATCH_ALWAYS_INLINE_NDEBUG
-static inline void
-_dispatch_release_2_no_dispose(dispatch_object_t dou)
-{
-	_os_object_release_internal_n_no_dispose_inline(dou._os_obj, 2);
+	_os_object_release_internal_inline(dou._os_obj);
 }
 
 DISPATCH_ALWAYS_INLINE_NDEBUG
@@ -279,42 +233,6 @@
 	_os_object_release_internal(dou._os_obj);
 }
 
-DISPATCH_ALWAYS_INLINE_NDEBUG
-static inline void
-_dispatch_release_2_tailcall(dispatch_object_t dou)
-{
-	_os_object_release_internal_n(dou._os_obj, 2);
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_queue_retain_storage(dispatch_queue_t dq)
-{
-	int ref_cnt = os_atomic_inc2o(dq, dq_sref_cnt, relaxed);
-	if (unlikely(ref_cnt <= 0)) {
-		_OS_OBJECT_CLIENT_CRASH("Resurrection of an object");
-	}
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_queue_release_storage(dispatch_queue_t dq)
-{
-	// this refcount only delays the _dispatch_object_dealloc() and there's no
-	// need for visibility wrt to the allocation, the internal refcount already
-	// gives us that, and the object becomes immutable after the last internal
-	// refcount release.
-	int ref_cnt = os_atomic_dec2o(dq, dq_sref_cnt, relaxed);
-	if (unlikely(ref_cnt >= 0)) {
-		return;
-	}
-	if (unlikely(ref_cnt < -1)) {
-		_OS_OBJECT_CLIENT_CRASH("Over-release of an object");
-	}
-	dq->dq_state = 0xdead000000000000;
-	_dispatch_object_dealloc(dq);
-}
-
 DISPATCH_ALWAYS_INLINE DISPATCH_NONNULL_ALL
 static inline void
 _dispatch_object_set_target_queue_inline(dispatch_object_t dou,
@@ -656,113 +574,6 @@
 	return _dispatch_queue_atomic_flags(dq) & DQF_LEGACY;
 }
 
-DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_wlh_retain(dispatch_wlh_t wlh)
-{
-	if (wlh && wlh != DISPATCH_WLH_ANON) {
-		_dispatch_queue_retain_storage((dispatch_queue_t)wlh);
-	}
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_wlh_release(dispatch_wlh_t wlh)
-{
-	if (wlh && wlh != DISPATCH_WLH_ANON) {
-		_dispatch_queue_release_storage((dispatch_queue_t)wlh);
-	}
-}
-
-#define DISPATCH_WLH_STORAGE_REF 1ul
-
-DISPATCH_ALWAYS_INLINE DISPATCH_PURE
-static inline dispatch_wlh_t
-_dispatch_get_wlh(void)
-{
-	return _dispatch_thread_getspecific(dispatch_wlh_key);
-}
-
-DISPATCH_ALWAYS_INLINE DISPATCH_PURE
-static inline dispatch_wlh_t
-_dispatch_get_wlh_reference(void)
-{
-	dispatch_wlh_t wlh = _dispatch_thread_getspecific(dispatch_wlh_key);
-	if (wlh != DISPATCH_WLH_ANON) {
-		wlh = (dispatch_wlh_t)((uintptr_t)wlh & ~DISPATCH_WLH_STORAGE_REF);
-	}
-	return wlh;
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline bool
-_dispatch_adopt_wlh_anon_recurse(void)
-{
-	dispatch_wlh_t cur_wlh = _dispatch_get_wlh_reference();
-	if (cur_wlh == DISPATCH_WLH_ANON) return false;
-	_dispatch_debug("wlh[anon]: set current (releasing %p)", cur_wlh);
-	_dispatch_wlh_release(cur_wlh);
-	_dispatch_thread_setspecific(dispatch_wlh_key, (void *)DISPATCH_WLH_ANON);
-	return true;
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_adopt_wlh_anon(void)
-{
-	if (unlikely(!_dispatch_adopt_wlh_anon_recurse())) {
-		DISPATCH_INTERNAL_CRASH(0, "Lingering DISPATCH_WLH_ANON");
-	}
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_adopt_wlh(dispatch_wlh_t wlh)
-{
-	dispatch_wlh_t cur_wlh = _dispatch_get_wlh_reference();
-	_dispatch_debug("wlh[%p]: adopt current (releasing %p)", wlh, cur_wlh);
-	if (cur_wlh == DISPATCH_WLH_ANON) {
-		DISPATCH_INTERNAL_CRASH(0, "Lingering DISPATCH_WLH_ANON");
-	}
-	if (cur_wlh != wlh) {
-		dispatch_assert(wlh);
-		_dispatch_wlh_release(cur_wlh);
-		_dispatch_wlh_retain(wlh);
-	}
-	_dispatch_thread_setspecific(dispatch_wlh_key, (void *)wlh);
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_preserve_wlh_storage_reference(dispatch_wlh_t wlh)
-{
-	dispatch_assert(wlh != DISPATCH_WLH_ANON);
-	dispatch_assert(wlh == _dispatch_get_wlh());
-	_dispatch_thread_setspecific(dispatch_wlh_key,
-			(void *)((uintptr_t)wlh | DISPATCH_WLH_STORAGE_REF));
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_reset_wlh(void)
-{
-	dispatch_assert(_dispatch_get_wlh() == DISPATCH_WLH_ANON);
-	_dispatch_debug("wlh[anon]: clear current");
-	_dispatch_thread_setspecific(dispatch_wlh_key, NULL);
-	_dispatch_clear_return_to_kernel();
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline bool
-_dispatch_wlh_should_poll_unote(dispatch_unote_t du)
-{
-	if (likely(_dispatch_needs_to_return_to_kernel())) {
-		dispatch_wlh_t wlh = _dispatch_get_wlh();
-		return wlh != DISPATCH_WLH_ANON && du._du->du_wlh == wlh;
-	}
-	return false;
-}
-
 #endif // DISPATCH_PURE_C
 #ifndef __cplusplus
 
@@ -867,67 +678,16 @@
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
-_dq_state_is_base_wlh(uint64_t dq_state)
-{
-	return dq_state & DISPATCH_QUEUE_ROLE_BASE_WLH;
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline bool
-_dq_state_is_base_anon(uint64_t dq_state)
-{
-	return dq_state & DISPATCH_QUEUE_ROLE_BASE_ANON;
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline bool
-_dq_state_is_inner_queue(uint64_t dq_state)
-{
-	return (dq_state & DISPATCH_QUEUE_ROLE_MASK) == DISPATCH_QUEUE_ROLE_INNER;
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline bool
 _dq_state_is_enqueued(uint64_t dq_state)
 {
-	return dq_state & (DISPATCH_QUEUE_ENQUEUED|DISPATCH_QUEUE_ENQUEUED_ON_MGR);
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline bool
-_dq_state_is_enqueued_on_target(uint64_t dq_state)
-{
 	return dq_state & DISPATCH_QUEUE_ENQUEUED;
 }
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
-_dq_state_is_enqueued_on_manager(uint64_t dq_state)
-{
-	return dq_state & DISPATCH_QUEUE_ENQUEUED_ON_MGR;
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline bool
-_dq_state_in_sync_transfer(uint64_t dq_state)
-{
-	return dq_state & DISPATCH_QUEUE_SYNC_TRANSFER;
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline bool
 _dq_state_received_override(uint64_t dq_state)
 {
-	return _dq_state_is_base_anon(dq_state) &&
-			(dq_state & DISPATCH_QUEUE_RECEIVED_OVERRIDE);
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline bool
-_dq_state_received_sync_wait(uint64_t dq_state)
-{
-	return _dq_state_is_base_wlh(dq_state) &&
-			(dq_state & DISPATCH_QUEUE_RECEIVED_SYNC_WAIT);
+	return dq_state & DISPATCH_QUEUE_RECEIVED_OVERRIDE;
 }
 
 DISPATCH_ALWAYS_INLINE
@@ -952,16 +712,13 @@
 	uint64_t qos_bits = _dq_state_from_qos(qos);
 	if ((dq_state & DISPATCH_QUEUE_MAX_QOS_MASK) < qos_bits) {
 		dq_state &= ~DISPATCH_QUEUE_MAX_QOS_MASK;
-		dq_state |= qos_bits;
-		if (unlikely(_dq_state_is_base_anon(dq_state))) {
-			dq_state |= DISPATCH_QUEUE_RECEIVED_OVERRIDE;
-		}
+		dq_state |= qos_bits | DISPATCH_QUEUE_RECEIVED_OVERRIDE;
 	}
 	return dq_state;
 }
 
 DISPATCH_ALWAYS_INLINE
-static inline dispatch_tid
+static inline dispatch_lock_owner
 _dq_state_drain_owner(uint64_t dq_state)
 {
 	return _dispatch_lock_owner((dispatch_lock)dq_state);
@@ -971,23 +728,33 @@
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
-_dq_state_drain_locked_by(uint64_t dq_state, dispatch_tid tid)
+_dq_state_drain_pended(uint64_t dq_state)
 {
-	return _dispatch_lock_is_locked_by((dispatch_lock)dq_state, tid);
+	return (dq_state & DISPATCH_QUEUE_DRAIN_PENDED);
 }
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
-_dq_state_drain_locked_by_self(uint64_t dq_state)
+_dq_state_drain_locked_by(uint64_t dq_state, uint32_t owner)
 {
-	return _dispatch_lock_is_locked_by_self((dispatch_lock)dq_state);
+	if (_dq_state_drain_pended(dq_state)) {
+		return false;
+	}
+	return _dq_state_drain_owner(dq_state) == owner;
 }
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
 _dq_state_drain_locked(uint64_t dq_state)
 {
-	return _dispatch_lock_is_locked((dispatch_lock)dq_state);
+	return (dq_state & DISPATCH_QUEUE_DRAIN_OWNER_MASK) != 0;
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline bool
+_dq_state_has_waiters(uint64_t dq_state)
+{
+	return _dispatch_lock_has_waiters((dispatch_lock)dq_state);
 }
 
 DISPATCH_ALWAYS_INLINE
@@ -1006,25 +773,17 @@
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
-_dq_state_should_override(uint64_t dq_state)
+_dq_state_should_wakeup(uint64_t dq_state)
 {
-	if (_dq_state_is_suspended(dq_state) ||
-			_dq_state_is_enqueued_on_manager(dq_state)) {
-		return false;
-	}
-	if (_dq_state_is_enqueued_on_target(dq_state)) {
-		return true;
-	}
-	if (_dq_state_is_base_wlh(dq_state)) {
-		return false;
-	}
-	return _dq_state_drain_locked(dq_state);
+	return _dq_state_is_runnable(dq_state) &&
+			!_dq_state_is_enqueued(dq_state) &&
+			!_dq_state_drain_locked(dq_state);
 }
 
-
 #endif // __cplusplus
 #pragma mark -
 #pragma mark dispatch_queue_t state machine
+#ifndef __cplusplus
 
 static inline pthread_priority_t _dispatch_get_priority(void);
 static inline dispatch_priority_t _dispatch_get_basepri(void);
@@ -1032,29 +791,43 @@
 static inline void _dispatch_set_basepri_override_qos(dispatch_qos_t qos);
 static inline void _dispatch_reset_basepri(dispatch_priority_t dbp);
 static inline dispatch_priority_t _dispatch_set_basepri(dispatch_priority_t dbp);
+
 static inline bool _dispatch_queue_need_override_retain(
 		dispatch_queue_class_t dqu, dispatch_qos_t qos);
 
+DISPATCH_ALWAYS_INLINE
+static inline void
+_dispatch_queue_xref_dispose(struct dispatch_queue_s *dq)
+{
+	uint64_t dq_state = os_atomic_load2o(dq, dq_state, relaxed);
+	if (unlikely(_dq_state_is_suspended(dq_state))) {
+		long state = (long)dq_state;
+		if (sizeof(long) < sizeof(uint64_t)) state = (long)(dq_state >> 32);
+		if (unlikely(_dq_state_is_inactive(dq_state))) {
+			// Arguments for and against this assert are within 6705399
+			DISPATCH_CLIENT_CRASH(state, "Release of an inactive object");
+		}
+		DISPATCH_CLIENT_CRASH(dq_state, "Release of a suspended object");
+	}
+	os_atomic_or2o(dq, dq_atomic_flags, DQF_RELEASED, relaxed);
+}
+
+#endif
 #if DISPATCH_PURE_C
 
 // Note to later developers: ensure that any initialization changes are
 // made for statically allocated queues (i.e. _dispatch_main_q).
 static inline void
 _dispatch_queue_init(dispatch_queue_t dq, dispatch_queue_flags_t dqf,
-		uint16_t width, uint64_t initial_state_bits)
+		uint16_t width, bool inactive)
 {
 	uint64_t dq_state = DISPATCH_QUEUE_STATE_INIT_VALUE(width);
 
-	dispatch_assert((initial_state_bits & ~(DISPATCH_QUEUE_ROLE_MASK |
-			DISPATCH_QUEUE_INACTIVE)) == 0);
-
-	if (initial_state_bits & DISPATCH_QUEUE_INACTIVE) {
-		dq_state |= DISPATCH_QUEUE_INACTIVE + DISPATCH_QUEUE_NEEDS_ACTIVATION;
-		dq_state |= DLOCK_OWNER_MASK;
-		dq->do_ref_cnt += 2; // rdar://8181908 see _dispatch_queue_resume
+	if (inactive) {
+		dq_state += DISPATCH_QUEUE_INACTIVE + DISPATCH_QUEUE_NEEDS_ACTIVATION;
+		dq_state += DLOCK_OWNER_INVALID;
+		dq->do_ref_cnt++; // rdar://8181908 see _dispatch_queue_resume
 	}
-
-	dq_state |= (initial_state_bits & DISPATCH_QUEUE_ROLE_MASK);
 	dq->do_next = (struct dispatch_queue_s *)DISPATCH_OBJECT_LISTLESS;
 	dqf |= DQF_WIDTH(width);
 	os_atomic_store2o(dq, dq_atomic_flags, dqf, relaxed);
@@ -1096,13 +869,8 @@
 	return true;
 }
 
-DISPATCH_ALWAYS_INLINE
-static inline bool
-_dq_state_needs_lock_override(uint64_t dq_state, dispatch_qos_t qos)
-{
-	return _dq_state_is_base_anon(dq_state) &&
-			qos < _dq_state_max_qos(dq_state);
-}
+#define _dispatch_queue_should_override_self(dq_state, qos) \
+	unlikely(qos < _dq_state_max_qos(dq_state))
 
 DISPATCH_ALWAYS_INLINE
 static inline dispatch_qos_t
@@ -1116,139 +884,79 @@
 	return qos;
 }
 
+/* Used by:
+ * - _dispatch_queue_class_invoke (normal path)
+ * - _dispatch_queue_override_invoke (stealer)
+ *
+ * Initial state must be { sc:0, ib:0, qf:0, dl:0 }
+ * Final state forces { dl:self, qf:1, d: 0 }
+ *    ib:1 is forced when the width acquired is equivalent to the barrier width
+ */
 DISPATCH_ALWAYS_INLINE DISPATCH_WARN_RESULT
 static inline uint64_t
 _dispatch_queue_drain_try_lock(dispatch_queue_t dq,
-		dispatch_invoke_flags_t flags)
+		dispatch_invoke_flags_t flags, uint64_t *dq_state)
 {
 	uint64_t pending_barrier_width =
 			(dq->dq_width - 1) * DISPATCH_QUEUE_WIDTH_INTERVAL;
-	uint64_t set_owner_and_set_full_width =
-			_dispatch_lock_value_for_self() | DISPATCH_QUEUE_WIDTH_FULL_BIT;
-	uint64_t lock_fail_mask, old_state, new_state, dequeue_mask;
-
-	// same as !_dq_state_is_runnable()
-	lock_fail_mask  = ~(DISPATCH_QUEUE_WIDTH_FULL_BIT - 1);
-	// same as _dq_state_drain_locked()
-	lock_fail_mask |= DISPATCH_QUEUE_DRAIN_OWNER_MASK;
+	uint64_t xor_owner_and_set_full_width =
+			_dispatch_tid_self() | DISPATCH_QUEUE_WIDTH_FULL_BIT;
+	uint64_t clear_enqueued_bit, old_state, new_state;
 
 	if (flags & DISPATCH_INVOKE_STEALING) {
-		lock_fail_mask |= DISPATCH_QUEUE_ENQUEUED_ON_MGR;
-		dequeue_mask = 0;
-	} else if (flags & DISPATCH_INVOKE_MANAGER_DRAIN) {
-		dequeue_mask = DISPATCH_QUEUE_ENQUEUED_ON_MGR;
+		clear_enqueued_bit = 0;
 	} else {
-		lock_fail_mask |= DISPATCH_QUEUE_ENQUEUED_ON_MGR;
-		dequeue_mask = DISPATCH_QUEUE_ENQUEUED;
+		clear_enqueued_bit = DISPATCH_QUEUE_ENQUEUED;
 	}
-	dispatch_assert(!(flags & DISPATCH_INVOKE_WLH));
 
 	dispatch_qos_t oq_floor = _dispatch_get_basepri_override_qos_floor();
 retry:
 	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, acquire, {
 		new_state = old_state;
-		if (likely(!(old_state & lock_fail_mask))) {
-			if (unlikely(_dq_state_needs_lock_override(old_state, oq_floor))) {
+		new_state ^= clear_enqueued_bit;
+		if (likely(_dq_state_is_runnable(old_state) &&
+				!_dq_state_drain_locked(old_state))) {
+			if (_dispatch_queue_should_override_self(old_state, oq_floor)) {
 				os_atomic_rmw_loop_give_up({
 					oq_floor = _dispatch_queue_override_self(old_state);
 					goto retry;
 				});
 			}
 			//
-			// Only keep the HAS_WAITER, MAX_QOS and ENQUEUED bits
+			// Only keep the HAS_WAITER, MAX_QOS and ENQUEUED (if stealing) bits
 			// In particular acquiring the drain lock clears the DIRTY and
-			// RECEIVED_OVERRIDE bits.
+			// RECEIVED_OVERRIDE
 			//
 			new_state &= DISPATCH_QUEUE_DRAIN_PRESERVED_BITS_MASK;
-			new_state |= set_owner_and_set_full_width;
+			//
+			// For the NOWAITERS_BIT case, the thread identity
+			// has NOWAITERS_BIT set, and NOWAITERS_BIT was kept above,
+			// so the xor below flips the NOWAITERS_BIT to 0 as expected.
+			//
+			// For the non inverted WAITERS_BIT case, WAITERS_BIT is not set in
+			// the thread identity, and the xor leaves the bit alone.
+			//
+			new_state ^= xor_owner_and_set_full_width;
 			if (_dq_state_has_pending_barrier(old_state) ||
 					old_state + pending_barrier_width <
 					DISPATCH_QUEUE_WIDTH_FULL_BIT) {
 				new_state |= DISPATCH_QUEUE_IN_BARRIER;
 			}
-		} else if (dequeue_mask) {
-			// dequeue_mask is in a register, xor yields better assembly
-			new_state ^= dequeue_mask;
-		} else {
+		} else if (!clear_enqueued_bit) {
 			os_atomic_rmw_loop_give_up(break);
 		}
 	});
 
-	dispatch_assert((old_state & dequeue_mask) == dequeue_mask);
-	if (likely(!(old_state & lock_fail_mask))) {
-		new_state &= DISPATCH_QUEUE_IN_BARRIER | DISPATCH_QUEUE_WIDTH_FULL_BIT |
-				dequeue_mask;
+	if (dq_state) *dq_state = new_state;
+	if (likely(_dq_state_is_runnable(old_state) &&
+			!_dq_state_drain_locked(old_state))) {
+		new_state &= DISPATCH_QUEUE_IN_BARRIER | DISPATCH_QUEUE_WIDTH_FULL_BIT;
 		old_state &= DISPATCH_QUEUE_WIDTH_MASK;
 		return new_state - old_state;
 	}
 	return 0;
 }
 
-DISPATCH_ALWAYS_INLINE DISPATCH_WARN_RESULT
-static inline bool
-_dispatch_queue_drain_try_lock_wlh(dispatch_queue_t dq, uint64_t *dq_state)
-{
-	uint64_t old_state, new_state;
-	uint64_t lock_bits = _dispatch_lock_value_for_self() |
-			DISPATCH_QUEUE_WIDTH_FULL_BIT | DISPATCH_QUEUE_IN_BARRIER;
-
-	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, acquire, {
-		new_state = old_state;
-		if (unlikely(_dq_state_is_suspended(old_state))) {
-			os_atomic_rmw_loop_give_up(break);
-		} else if (unlikely(_dq_state_drain_locked(old_state))) {
-			os_atomic_rmw_loop_give_up(break);
-		} else {
-			new_state &= DISPATCH_QUEUE_DRAIN_PRESERVED_BITS_MASK;
-			new_state |= lock_bits;
-		}
-	});
-	if (unlikely(!_dq_state_is_base_wlh(old_state) ||
-			!_dq_state_is_enqueued_on_target(old_state) ||
-			_dq_state_is_enqueued_on_manager(old_state))) {
-#if !__LP64__
-		old_state >>= 32;
-#endif
-		DISPATCH_INTERNAL_CRASH(old_state, "Invalid wlh state");
-	}
-
-	if (dq_state) *dq_state = new_state;
-	return !_dq_state_is_suspended(old_state) &&
-			!_dq_state_drain_locked(old_state);
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_queue_mgr_lock(dispatch_queue_t dq)
-{
-	uint64_t old_state, new_state, set_owner_and_set_full_width =
-			_dispatch_lock_value_for_self() | DISPATCH_QUEUE_SERIAL_DRAIN_OWNED;
-
-	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, acquire, {
-		new_state = old_state;
-		if (unlikely(!_dq_state_is_runnable(old_state) ||
-				_dq_state_drain_locked(old_state))) {
-			DISPATCH_INTERNAL_CRASH((uintptr_t)old_state,
-					"Locking the manager should not fail");
-		}
-		new_state &= DISPATCH_QUEUE_DRAIN_PRESERVED_BITS_MASK;
-		new_state |= set_owner_and_set_full_width;
-	});
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline bool
-_dispatch_queue_mgr_unlock(dispatch_queue_t dq)
-{
-	uint64_t old_state, new_state;
-	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
-		new_state = old_state - DISPATCH_QUEUE_SERIAL_DRAIN_OWNED;
-		new_state &= ~DISPATCH_QUEUE_DRAIN_UNLOCK_MASK;
-		new_state &= ~DISPATCH_QUEUE_MAX_QOS_MASK;
-	});
-	return _dq_state_is_dirty(old_state);
-}
-
 /* Used by _dispatch_barrier_{try,}sync
  *
  * Note, this fails if any of e:1 or dl!=0, but that allows this code to be a
@@ -1264,18 +972,11 @@
 static inline bool
 _dispatch_queue_try_acquire_barrier_sync(dispatch_queue_t dq, uint32_t tid)
 {
-	uint64_t init  = DISPATCH_QUEUE_STATE_INIT_VALUE(dq->dq_width);
-	uint64_t value = DISPATCH_QUEUE_WIDTH_FULL_BIT | DISPATCH_QUEUE_IN_BARRIER |
-			_dispatch_lock_value_from_tid(tid);
-	uint64_t old_state, new_state;
+	uint64_t value = DISPATCH_QUEUE_WIDTH_FULL_BIT | DISPATCH_QUEUE_IN_BARRIER;
+	value |= tid;
 
-	return os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, acquire, {
-		uint64_t role = old_state & DISPATCH_QUEUE_ROLE_MASK;
-		if (old_state != (init | role)) {
-			os_atomic_rmw_loop_give_up(break);
-		}
-		new_state = value | role;
-	});
+	return os_atomic_cmpxchg2o(dq, dq_state,
+			DISPATCH_QUEUE_STATE_INIT_VALUE(dq->dq_width), value, acquire);
 }
 
 /* Used by _dispatch_sync for root queues and some drain codepaths
@@ -1448,13 +1149,18 @@
 static inline bool
 _dispatch_queue_drain_try_unlock(dispatch_queue_t dq, uint64_t owned, bool done)
 {
-	uint64_t old_state, new_state;
+	uint64_t old_state = os_atomic_load2o(dq, dq_state, relaxed);
+	uint64_t new_state;
 
 	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
-		new_state  = old_state - owned;
-		new_state &= ~DISPATCH_QUEUE_DRAIN_UNLOCK_MASK;
-		if (unlikely(_dq_state_is_suspended(old_state))) {
-			new_state |= DLOCK_OWNER_MASK;
+		new_state = old_state - owned;
+		if (unlikely(_dq_state_is_suspended(new_state))) {
+#ifdef DLOCK_NOWAITERS_BIT
+			new_state = new_state | DISPATCH_QUEUE_DRAIN_OWNER_MASK;
+#else
+			new_state = new_state | DLOCK_OWNER_INVALID;
+#endif
+			new_state |= DISPATCH_QUEUE_DIRTY;
 		} else if (unlikely(_dq_state_is_dirty(old_state))) {
 			os_atomic_rmw_loop_give_up({
 				// just renew the drain lock with an acquire barrier, to see
@@ -1465,8 +1171,11 @@
 				return false;
 			});
 		} else if (likely(done)) {
+			new_state &= ~DISPATCH_QUEUE_DRAIN_UNLOCK_MASK;
+			new_state &= ~DISPATCH_QUEUE_RECEIVED_OVERRIDE;
 			new_state &= ~DISPATCH_QUEUE_MAX_QOS_MASK;
 		} else {
+			new_state = DISPATCH_QUEUE_DRAIN_UNLOCK(new_state);
 			new_state |= DISPATCH_QUEUE_DIRTY;
 		}
 	});
@@ -1478,6 +1187,80 @@
 	return true;
 }
 
+/* Used to transfer the drain lock to a next thread, because it is known
+ * and that the dirty-head check isn't needed.
+ *
+ * This releases `owned`, clears DIRTY, and handles overrides when seen.
+ */
+DISPATCH_ALWAYS_INLINE
+static inline void
+_dispatch_queue_drain_transfer_lock(dispatch_queue_t dq,
+		uint64_t owned, dispatch_object_t dou)
+{
+	uint64_t old_state, new_state;
+	mach_port_t next_owner = 0;
+	if (dou._dc->dc_flags & DISPATCH_OBJ_BARRIER_BIT) {
+		next_owner = (mach_port_t)dou._dc->dc_data;
+	}
+
+#ifdef DLOCK_NOWAITERS_BIT
+	// The NOWAITERS_BIT state must not change through the transfer. It means
+	// that if next_owner is 0 the bit must be flipped in the rmw_loop below,
+	// and if next_owner is set, then the bit must be left unchanged.
+	//
+	// - when next_owner is 0, the xor below sets NOWAITERS_BIT in next_owner,
+	//   which causes the second xor to flip the bit as expected.
+	// - if next_owner is not 0, it has the NOWAITERS_BIT set, so we have to
+	//   clear it so that the second xor leaves the NOWAITERS_BIT alone.
+	next_owner ^= DLOCK_NOWAITERS_BIT;
+#endif
+	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
+		new_state = old_state - owned;
+		// same as DISPATCH_QUEUE_DRAIN_UNLOCK
+		// but we want to be more efficient wrt the WAITERS_BIT
+		new_state &= ~DISPATCH_QUEUE_DRAIN_OWNER_MASK;
+		new_state &= ~DISPATCH_QUEUE_DRAIN_PENDED;
+		new_state &= ~DISPATCH_QUEUE_RECEIVED_OVERRIDE;
+		new_state &= ~DISPATCH_QUEUE_DIRTY;
+		new_state ^= next_owner;
+	});
+	if (_dq_state_received_override(old_state)) {
+		// Ensure that the root queue sees that this thread was overridden.
+		_dispatch_set_basepri_override_qos(_dq_state_max_qos(old_state));
+	}
+}
+
+/* Used to forcefully unlock the drain lock, bypassing the dirty bit check.
+ * This usually is followed by a wakeup to re-evaluate the state machine
+ * of the queue/source.
+ *
+ * This releases `owned`, clears DIRTY, and handles overrides when seen.
+ */
+DISPATCH_ALWAYS_INLINE
+static inline uint64_t
+_dispatch_queue_drain_unlock(dispatch_queue_t dq, uint64_t owned)
+{
+	uint64_t old_state, new_state;
+
+	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
+		new_state = old_state - owned;
+		// same as DISPATCH_QUEUE_DRAIN_UNLOCK
+		// but we want to be more efficient wrt the WAITERS_BIT
+#ifdef DLOCK_NOWAITERS_BIT
+		new_state ^= DLOCK_NOWAITERS_BIT;
+#endif
+		new_state &= ~DISPATCH_QUEUE_DRAIN_OWNER_MASK;
+		new_state &= ~DISPATCH_QUEUE_DRAIN_PENDED;
+		new_state &= ~DISPATCH_QUEUE_RECEIVED_OVERRIDE;
+	});
+
+	if (_dq_state_received_override(old_state)) {
+		// Ensure that the root queue sees that this thread was overridden.
+		_dispatch_set_basepri_override_qos(_dq_state_max_qos(old_state));
+	}
+	return old_state;
+}
+
 #pragma mark -
 #pragma mark os_mpsc_queue
 
@@ -1585,7 +1368,7 @@
 static inline bool
 _dispatch_queue_sidelock_trylock(dispatch_queue_t dq, dispatch_qos_t qos)
 {
-	dispatch_tid owner;
+	dispatch_lock_owner owner;
 	if (_dispatch_unfair_lock_trylock(&dq->dq_sidelock, &owner)) {
 		return true;
 	}
@@ -1716,11 +1499,11 @@
 	// queue when invoked by _dispatch_queue_drain. <rdar://problem/6932776>
 	bool overriding = _dispatch_queue_need_override_retain(dq, qos);
 	if (unlikely(_dispatch_queue_push_update_tail(dq, tail))) {
-		if (!overriding) _dispatch_retain_2(dq->_as_os_obj);
+		if (!overriding) _dispatch_retain(dq);
 		_dispatch_queue_push_update_head(dq, tail);
-		flags = DISPATCH_WAKEUP_CONSUME_2 | DISPATCH_WAKEUP_MAKE_DIRTY;
+		flags = DISPATCH_WAKEUP_CONSUME | DISPATCH_WAKEUP_FLUSH;
 	} else if (overriding) {
-		flags = DISPATCH_WAKEUP_CONSUME_2;
+		flags = DISPATCH_WAKEUP_CONSUME | DISPATCH_WAKEUP_OVERRIDING;
 	} else {
 		return;
 	}
@@ -1728,14 +1511,6 @@
 }
 
 DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_queue_push_queue(dispatch_queue_t tq, dispatch_queue_t dq,
-		uint64_t dq_state)
-{
-	return dx_push(tq, dq, _dq_state_max_qos(dq_state));
-}
-
-DISPATCH_ALWAYS_INLINE
 static inline dispatch_priority_t
 _dispatch_root_queue_identity_assume(dispatch_queue_t assumed_rq)
 {
@@ -1746,6 +1521,30 @@
 	return old_dbp;
 }
 
+DISPATCH_ALWAYS_INLINE
+static inline bool
+_dispatch_root_queue_allows_wlh_for_queue(dispatch_queue_t rq,
+		dispatch_queue_class_t dqu)
+{
+	// This will discard:
+	// - queues already tagged with the global wlh
+	// - concurrent queues (width != 1)
+	// - non overcommit queues, which includes pthread root queues.
+	return dqu._dq->dq_wlh != DISPATCH_WLH_GLOBAL && dqu._dq->dq_width == 1 &&
+			(rq->dq_priority & DISPATCH_PRIORITY_FLAG_OVERCOMMIT);
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline dispatch_wlh_t
+_dispatch_root_queue_wlh_for_queue(dispatch_queue_t rq,
+		dispatch_queue_class_t dqu)
+{
+	if (likely(_dispatch_root_queue_allows_wlh_for_queue(rq, dqu))) {
+		return (dispatch_wlh_t)dqu._dq;
+	}
+	return DISPATCH_WLH_GLOBAL;
+}
+
 typedef dispatch_queue_wakeup_target_t
 _dispatch_queue_class_invoke_handler_t(dispatch_object_t,
 		dispatch_invoke_context_t dic, dispatch_invoke_flags_t,
@@ -1755,13 +1554,13 @@
 static inline void
 _dispatch_queue_class_invoke(dispatch_object_t dou,
 		dispatch_invoke_context_t dic, dispatch_invoke_flags_t flags,
-		dispatch_invoke_flags_t const_restrict_flags,
 		_dispatch_queue_class_invoke_handler_t invoke)
 {
 	dispatch_queue_t dq = dou._dq;
 	dispatch_queue_wakeup_target_t tq = DISPATCH_QUEUE_WAKEUP_NONE;
+	uint64_t dq_state, to_unlock = 0;
 	bool owning = !(flags & DISPATCH_INVOKE_STEALING);
-	uint64_t owned = 0;
+	bool overriding = (flags & DISPATCH_INVOKE_OVERRIDING);
 
 	// When called from a plain _dispatch_queue_drain:
 	//   overriding = false
@@ -1770,42 +1569,43 @@
 	// When called from an override continuation:
 	//   overriding = true
 	//   owning depends on whether the override embedded the queue or steals
+	DISPATCH_COMPILER_CAN_ASSUME(owning || overriding);
 
-	if (!(flags & (DISPATCH_INVOKE_STEALING | DISPATCH_INVOKE_WLH))) {
+	if (likely(owning)) {
 		dq->do_next = DISPATCH_OBJECT_LISTLESS;
 	}
-	flags |= const_restrict_flags;
-	if (likely(flags & DISPATCH_INVOKE_WLH)) {
-		owned = DISPATCH_QUEUE_SERIAL_DRAIN_OWNED | DISPATCH_QUEUE_ENQUEUED;
-	} else {
-		owned = _dispatch_queue_drain_try_lock(dq, flags);
-	}
-	if (likely(owned)) {
+	to_unlock = _dispatch_queue_drain_try_lock(dq, flags, &dq_state);
+	if (likely(to_unlock)) {
 		dispatch_priority_t old_dbp;
 		if (!(flags & DISPATCH_INVOKE_MANAGER_DRAIN)) {
+			if (unlikely(overriding)) {
+				_dispatch_object_debug(dq, "stolen onto thread 0x%x, 0x%x",
+						_dispatch_tid_self(), _dispatch_get_basepri());
+			}
 			old_dbp = _dispatch_set_basepri(dq->dq_priority);
+			dispatch_wlh_t wlh = _dispatch_get_wlh();
+			if (unlikely(dq->dq_wlh != wlh)) {
+				if (unlikely(dq->dq_wlh)) {
+					_dispatch_ktrace3(DISPATCH_PERF_wlh_change, dq,
+							dq->dq_wlh, wlh);
+					if (!(_dispatch_queue_atomic_flags_set_orig(dq,
+							DQF_WLH_CHANGED) & DQF_WLH_CHANGED)) {
+						_dispatch_bug_deprecated("Changing target queue "
+								"hierarchy after object has started executing");
+					}
+				}
+				dq->dq_wlh = wlh;
+#if DISPATCH_ENFORCE_STATIC_WLH_HIERARCHY
+				_dispatch_queue_atomic_flags_clear(dq, DQF_LEGACY);
+#endif
+			}
 		} else {
 			old_dbp = 0;
 		}
 
 		flags = _dispatch_queue_merge_autorelease_frequency(dq, flags);
 attempt_running_slow_head:
-#if DISPATCH_COCOA_COMPAT
-		if ((flags & DISPATCH_INVOKE_WLH) &&
-				!(flags & DISPATCH_INVOKE_AUTORELEASE_ALWAYS)) {
-			_dispatch_last_resort_autorelease_pool_push(dic);
-		}
-#endif // DISPATCH_COCOA_COMPAT
-		tq = invoke(dq, dic, flags, &owned);
-#if DISPATCH_COCOA_COMPAT
-		if ((flags & DISPATCH_INVOKE_WLH) &&
-				!(flags & DISPATCH_INVOKE_AUTORELEASE_ALWAYS)) {
-			dispatch_thread_frame_s dtf;
-			_dispatch_thread_frame_push(&dtf, dq);
-			_dispatch_last_resort_autorelease_pool_pop(dic);
-			_dispatch_thread_frame_pop(&dtf);
-		}
-#endif // DISPATCH_COCOA_COMPAT
+		tq = invoke(dq, dic, flags, &to_unlock);
 		dispatch_assert(tq != DISPATCH_QUEUE_WAKEUP_TARGET);
 		if (unlikely(tq != DISPATCH_QUEUE_WAKEUP_NONE &&
 				tq != DISPATCH_QUEUE_WAKEUP_WAIT_FOR_EVENT)) {
@@ -1817,15 +1617,14 @@
 			// In both cases, we want to bypass the check for DIRTY.
 			// That may cause us to leave DIRTY in place but all drain lock
 			// acquirers clear it
-		} else if (!_dispatch_queue_drain_try_unlock(dq, owned,
+		} else if (!_dispatch_queue_drain_try_unlock(dq, to_unlock,
 				tq == DISPATCH_QUEUE_WAKEUP_NONE)) {
 			tq = _dispatch_queue_get_current();
 			if (dx_hastypeflag(tq, QUEUE_ROOT) || !owning) {
 				goto attempt_running_slow_head;
 			}
-			DISPATCH_COMPILER_CAN_ASSUME(tq != DISPATCH_QUEUE_WAKEUP_NONE);
 		} else {
-			owned = 0;
+			to_unlock = 0;
 			tq = NULL;
 		}
 		if (!(flags & DISPATCH_INVOKE_MANAGER_DRAIN)) {
@@ -1836,43 +1635,32 @@
 		_dispatch_introspection_queue_item_complete(dq);
 	}
 
-	if (tq) {
-		if (const_restrict_flags & DISPATCH_INVOKE_DISALLOW_SYNC_WAITERS) {
-			dispatch_assert(dic->dic_deferred == NULL);
-		} else if (dic->dic_deferred) {
-			return _dispatch_queue_drain_sync_waiter(dq, dic,
-					flags, owned);
-		}
+	if (tq && dic->dic_deferred) {
+		return _dispatch_queue_drain_deferred_invoke(dq, dic, flags, to_unlock);
+	}
 
-		uint64_t old_state, new_state, enqueued = DISPATCH_QUEUE_ENQUEUED;
-		if (tq == DISPATCH_QUEUE_WAKEUP_MGR) {
-			enqueued = DISPATCH_QUEUE_ENQUEUED_ON_MGR;
-		}
+	if (tq) {
+		uint64_t old_state, new_state;
+
 		os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
-			new_state  = old_state - owned;
-			new_state &= ~DISPATCH_QUEUE_DRAIN_UNLOCK_MASK;
+			new_state  = DISPATCH_QUEUE_DRAIN_UNLOCK(old_state - to_unlock);
 			new_state |= DISPATCH_QUEUE_DIRTY;
-			if (_dq_state_is_suspended(new_state)) {
-				new_state |= DLOCK_OWNER_MASK;
-			} else if (_dq_state_is_runnable(new_state) &&
-					!_dq_state_is_enqueued(new_state)) {
+			if (_dq_state_should_wakeup(new_state)) {
 				// drain was not interupted for suspension
 				// we will reenqueue right away, just put ENQUEUED back
-				new_state |= enqueued;
+				new_state |= DISPATCH_QUEUE_ENQUEUED;
 			}
 		});
-		old_state -= owned;
 		if (_dq_state_received_override(old_state)) {
 			// Ensure that the root queue sees that this thread was overridden.
-			_dispatch_set_basepri_override_qos(_dq_state_max_qos(new_state));
+			_dispatch_set_basepri_override_qos(_dq_state_max_qos(old_state));
 		}
-		if ((old_state ^ new_state) & enqueued) {
-			dispatch_assert(_dq_state_is_enqueued(new_state));
-			return _dispatch_queue_push_queue(tq, dq, new_state);
+		if ((old_state ^ new_state) & DISPATCH_QUEUE_ENQUEUED) {
+			return dx_push(tq, dq, _dq_state_max_qos(old_state));
 		}
 	}
 
-	_dispatch_release_2_tailcall(dq);
+	return _dispatch_release_tailcall(dq);
 }
 
 DISPATCH_ALWAYS_INLINE
@@ -1910,21 +1698,23 @@
 {
 	// Tag thread-bound queues with the owning thread
 	dispatch_assert(_dispatch_queue_is_thread_bound(dq));
-	uint64_t old_state, new_state;
-	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, relaxed, {
-		new_state = old_state;
-		new_state &= ~DISPATCH_QUEUE_DRAIN_OWNER_MASK;
-		new_state |= _dispatch_lock_value_for_self();
-	});
+	mach_port_t old_owner, self = _dispatch_tid_self();
+	uint64_t dq_state = os_atomic_or_orig2o(dq, dq_state, self, relaxed);
+	if (unlikely(old_owner = _dq_state_drain_owner(dq_state))) {
+		DISPATCH_INTERNAL_CRASH(old_owner, "Queue bound twice");
+	}
 }
 
 DISPATCH_ALWAYS_INLINE
 static inline void
 _dispatch_queue_clear_bound_thread(dispatch_queue_t dq)
 {
+	uint64_t old_state, new_state;
+
 	dispatch_assert(_dispatch_queue_is_thread_bound(dq));
-	_dispatch_queue_atomic_flags_clear(dq, DQF_THREAD_BOUND|DQF_CANNOT_TRYSYNC);
-	os_atomic_and2o(dq, dq_state, ~DISPATCH_QUEUE_DRAIN_OWNER_MASK, relaxed);
+	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, relaxed, {
+		new_state = DISPATCH_QUEUE_DRAIN_UNLOCK(old_state);
+	});
 }
 
 DISPATCH_ALWAYS_INLINE
@@ -2050,21 +1840,6 @@
 }
 
 DISPATCH_ALWAYS_INLINE
-static inline dispatch_priority_t
-_dispatch_set_basepri_wlh(dispatch_priority_t dbp)
-{
-#if HAVE_PTHREAD_WORKQUEUE_QOS
-	dispatch_assert(!_dispatch_get_basepri());
-	// _dispatch_set_basepri_override_qos(DISPATCH_QOS_SATURATED)
-	dbp |= DISPATCH_QOS_SATURATED << DISPATCH_PRIORITY_OVERRIDE_SHIFT;
-	_dispatch_thread_setspecific(dispatch_basepri_key, (void*)(uintptr_t)dbp);
-#else
-	(void)dbp;
-#endif
-	return 0;
-}
-
-DISPATCH_ALWAYS_INLINE
 static inline pthread_priority_t
 _dispatch_priority_adopt(pthread_priority_t pp, unsigned long flags)
 {
@@ -2261,7 +2036,7 @@
 		dispatch_qos_t qos)
 {
 	if (_dispatch_queue_need_override(dqu, qos)) {
-		_os_object_retain_internal_n_inline(dqu._oq->_as_os_obj, 2);
+		_os_object_retain_internal_inline(dqu._oq->_as_os_obj);
 		return true;
 	}
 	return false;
@@ -2278,37 +2053,37 @@
 	return MAX(qos, _dispatch_priority_qos(dqu._oq->oq_priority));
 }
 
-#define DISPATCH_PRIORITY_PROPAGATE_CURRENT 0x1
-#define DISPATCH_PRIORITY_PROPAGATE_FOR_SYNC_IPC 0x2
-
 DISPATCH_ALWAYS_INLINE
-static inline pthread_priority_t
-_dispatch_priority_compute_propagated(pthread_priority_t pp,
-		unsigned int flags)
+static inline dispatch_qos_t
+_dispatch_queue_reset_max_qos(dispatch_queue_class_t dqu)
 {
-#if HAVE_PTHREAD_WORKQUEUE_QOS
-	if (flags & DISPATCH_PRIORITY_PROPAGATE_CURRENT) {
-		pp = _dispatch_get_priority();
-	}
-	pp &= ~_PTHREAD_PRIORITY_FLAGS_MASK;
-	if (!(flags & DISPATCH_PRIORITY_PROPAGATE_FOR_SYNC_IPC) &&
-			pp > _dispatch_qos_to_pp(DISPATCH_QOS_USER_INITIATED)) {
-		// Cap QOS for propagation at user-initiated <rdar://16681262&16998036>
-		return _dispatch_qos_to_pp(DISPATCH_QOS_USER_INITIATED);
-	}
-	return pp;
-#else
-	(void)pp; (void)flags;
-	return 0;
-#endif
+	uint64_t old_state, new_state;
+	os_atomic_rmw_loop2o(dqu._dq, dq_state, old_state, new_state, relaxed, {
+		new_state = old_state;
+		new_state &= ~DISPATCH_QUEUE_MAX_QOS_MASK;
+		new_state &= ~DISPATCH_QUEUE_RECEIVED_OVERRIDE;
+		if (old_state == new_state) {
+			os_atomic_rmw_loop_give_up(return DISPATCH_QOS_UNSPECIFIED);
+		}
+	});
+	return _dq_state_max_qos(old_state);
 }
 
 DISPATCH_ALWAYS_INLINE
 static inline pthread_priority_t
 _dispatch_priority_propagate(void)
 {
-	return _dispatch_priority_compute_propagated(0,
-			DISPATCH_PRIORITY_PROPAGATE_CURRENT);
+#if HAVE_PTHREAD_WORKQUEUE_QOS
+	pthread_priority_t pp = _dispatch_get_priority();
+	pp &= ~_PTHREAD_PRIORITY_FLAGS_MASK;
+	if (pp > _dispatch_qos_to_pp(DISPATCH_QOS_USER_INITIATED)) {
+		// Cap QOS for propagation at user-initiated <rdar://16681262&16998036>
+		return _dispatch_qos_to_pp(DISPATCH_QOS_USER_INITIATED);
+	}
+	return pp;
+#else
+	return 0;
+#endif
 }
 
 // including maintenance
@@ -2325,6 +2100,66 @@
 }
 
 #pragma mark -
+#pragma mark dispatch_wlh_t
+
+static inline dispatch_wlh_t
+_dispatch_queue_class_compute_wlh(dispatch_queue_class_t dqu)
+{
+	// TODO: combine with _dispatch_source_compute_kevent_priority
+	dispatch_queue_t dq = dqu._dq;
+	dispatch_queue_t tq = dq->do_targetq;
+
+	while (unlikely(!dx_hastypeflag(tq, QUEUE_ROOT))) {
+		if (tq->dq_wlh) {
+			return tq->dq_wlh;
+		}
+		dispatch_assert(!_dispatch_queue_is_thread_bound(tq));
+		if (unlikely(DISPATCH_QUEUE_IS_SUSPENDED(tq))) {
+			// this queue may not be activated yet, so the queue graph may not
+			// have stabilized yet
+			return NULL;
+		}
+		if (unlikely(_dispatch_queue_is_legacy(tq))) {
+			if (!_dispatch_is_in_root_queues_array(tq->do_targetq)) {
+				// we're not allowed to dereference tq->do_targetq
+				return NULL;
+			}
+		}
+		dq = tq;
+		tq = dq->do_targetq;
+	}
+	dispatch_assert(tq->dq_wlh);
+	return _dispatch_root_queue_wlh_for_queue(tq, dq);
+}
+
+static inline void
+_dispatch_queue_class_record_wlh_hierarchy(dispatch_queue_class_t dqu,
+		dispatch_wlh_t wlh)
+{
+	dispatch_queue_t dq = dqu._dq;
+	dispatch_queue_t tq = dq->do_targetq;
+
+	dispatch_assert(wlh);
+	dispatch_assert(!dq->dq_wlh);
+	dq->dq_wlh = wlh;
+#if DISPATCH_ENFORCE_STATIC_WLH_HIERARCHY
+	_dispatch_queue_atomic_flags_clear(dq, DQF_LEGACY);
+#endif
+	while (unlikely(!dx_hastypeflag(tq, QUEUE_ROOT))) {
+		if (tq->dq_wlh) {
+			return;
+		}
+		tq->dq_wlh = wlh;
+#if DISPATCH_ENFORCE_STATIC_WLH_HIERARCHY
+		_dispatch_queue_atomic_flags_set_and_clear(tq, DQF_TARGETED,DQF_LEGACY);
+#else
+		_dispatch_queue_atomic_flags_set(tq, DQF_TARGETED);
+#endif
+		tq = tq->do_targetq;
+	}
+}
+
+#pragma mark -
 #pragma mark dispatch_block_t
 
 #ifdef __BLOCKS__
diff --git a/src/internal.h b/src/internal.h
index 0536db1..688d5dd 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -38,7 +38,6 @@
 
 #ifdef __APPLE__
 #include <Availability.h>
-#include <os/availability.h>
 #include <TargetConditionals.h>
 
 #ifndef TARGET_OS_MAC_DESKTOP
@@ -49,15 +48,15 @@
 #if TARGET_OS_MAC_DESKTOP
 #  define DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(x) \
 		(__MAC_OS_X_VERSION_MIN_REQUIRED >= (x))
-#  if !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
-#    error "OS X hosts older than OS X 10.12 aren't supported anymore"
-#  endif // !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
+#  if !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101100)
+#    error "OS X hosts older than OS X 10.11 aren't supported anymore"
+#  endif // !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101000)
 #elif TARGET_OS_SIMULATOR
 #  define DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(x) \
 		(IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED >= (x))
-#  if !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
-#    error "Simulator hosts older than OS X 10.12 aren't supported anymore"
-#  endif // !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
+#  if !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101100)
+#    error "Simulator hosts older than OS X 10.11 aren't supported anymore"
+#  endif // !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101000)
 #else
 #  define DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(x) 1
 #  if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000
@@ -189,8 +188,6 @@
 #define DISPATCH_USE_CLIENT_CALLOUT 1
 #endif
 
-#define DISPATCH_ALLOW_NON_LEAF_RETARGET 1
-
 /* The "_debug" library build */
 #ifndef DISPATCH_DEBUG
 #define DISPATCH_DEBUG 0
@@ -242,6 +239,9 @@
 #if HAVE_MALLOC_MALLOC_H
 #include <malloc/malloc.h>
 #endif
+#if __has_include(<malloc_private.h>)
+#include <malloc_private.h>
+#endif // __has_include(<malloc_private.h)
 
 #include <sys/stat.h>
 
@@ -260,11 +260,7 @@
 #endif
 
 #ifdef __BLOCKS__
-#if __has_include(<Block_private.h>)
 #include <Block_private.h>
-#else
-#include "BlocksRuntime/Block_private.h"
-#endif // __has_include(<Block_private.h>)
 #include <Block.h>
 #endif /* __BLOCKS__ */
 
@@ -454,14 +450,14 @@
  * For reporting bugs within libdispatch when using the "_debug" version of the
  * library.
  */
-#if __APPLE__
+#if __GNUC__
 #define dispatch_assert(e) do { \
 		if (__builtin_constant_p(e)) { \
 			dispatch_static_assert(e); \
 		} else { \
 			typeof(e) _e = fastpath(e); /* always eval 'e' */ \
-			if (!_e) { \
-				__assert_rtn(__func__, __FILE__, __LINE__, #e); \
+			if (DISPATCH_DEBUG && !_e) { \
+				_dispatch_abort(__LINE__, (long)_e); \
 			} \
 		} \
 	} while (0)
@@ -472,7 +468,7 @@
 #define dispatch_assert(e) _dispatch_assert((long)(e), __LINE__)
 #endif	/* __GNUC__ */
 
-#if __APPLE__
+#if __GNUC__
 /*
  * A lot of API return zero upon success and not-zero on fail. Let's capture
  * and log the non-zero value
@@ -482,8 +478,8 @@
 			dispatch_static_assert(e); \
 		} else { \
 			typeof(e) _e = slowpath(e); /* always eval 'e' */ \
-			if (_e) { \
-				__assert_rtn(__func__, __FILE__, __LINE__, #e); \
+			if (DISPATCH_DEBUG && _e) { \
+				_dispatch_abort(__LINE__, (long)_e); \
 			} \
 		} \
 	} while (0)
@@ -491,7 +487,7 @@
 static inline void _dispatch_assert_zero(long e, long line) {
 	if (DISPATCH_DEBUG && e) _dispatch_abort(line, e);
 }
-#define dispatch_assert_zero(e) _dispatch_assert_zero((long)(e), __LINE__)
+#define dispatch_assert_zero(e) _dispatch_assert((long)(e), __LINE__)
 #endif	/* __GNUC__ */
 
 /*
@@ -600,7 +596,6 @@
 const char *_dispatch_strdup_if_mutable(const char *str);
 void _dispatch_vtable_init(void);
 char *_dispatch_get_build(void);
-int _dispatch_sigmask(void);
 
 uint64_t _dispatch_timeout(dispatch_time_t when);
 uint64_t _dispatch_time_nanoseconds_since_epoch(dispatch_time_t when);
@@ -635,16 +630,35 @@
 
 // Older Mac OS X and iOS Simulator fallbacks
 
+#if HAVE_PTHREAD_WORKQUEUES || DISPATCH_USE_INTERNAL_WORKQUEUE
+#ifndef WORKQ_ADDTHREADS_OPTION_OVERCOMMIT
+#define WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 0x00000001
+#endif
+#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
 #endif
-#if HAVE__PTHREAD_WORKQUEUE_INIT && PTHREAD_WORKQUEUE_SPI_VERSION >= 20150304 \
+#if HAVE__PTHREAD_WORKQUEUE_INIT && (PTHREAD_WORKQUEUE_SPI_VERSION >= 20150304 \
+		|| (PTHREAD_WORKQUEUE_SPI_VERSION == 20140730 && \
+			defined(WORKQ_FEATURE_KEVENT))) \
 		&& !defined(HAVE_PTHREAD_WORKQUEUE_KEVENT)
+#if PTHREAD_WORKQUEUE_SPI_VERSION == 20140730
+// rdar://problem/20609877
+typedef pthread_worqueue_function_kevent_t pthread_workqueue_function_kevent_t;
+#endif
 #define HAVE_PTHREAD_WORKQUEUE_KEVENT 1
 #endif
 
 
+#ifndef PTHREAD_WORKQUEUE_RESETS_VOUCHER_AND_PRIORITY_ON_PARK
+#if HAVE_PTHREAD_WORKQUEUE_QOS && DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
+#define PTHREAD_WORKQUEUE_RESETS_VOUCHER_AND_PRIORITY_ON_PARK 1
+#else
+#define PTHREAD_WORKQUEUE_RESETS_VOUCHER_AND_PRIORITY_ON_PARK 0
+#endif
+#endif // PTHREAD_WORKQUEUE_RESETS_VOUCHER_AND_PRIORITY_ON_PARK
+
 #ifndef HAVE_PTHREAD_WORKQUEUE_NARROWING
 #if !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(109900)
 #define HAVE_PTHREAD_WORKQUEUE_NARROWING 0
@@ -667,29 +681,31 @@
 #define DISPATCH_USE_MEMORYPRESSURE_SOURCE 1
 #endif
 #if DISPATCH_USE_MEMORYPRESSURE_SOURCE
-#if __has_include(<malloc_private.h>)
-#include <malloc_private.h>
-#else
-extern void malloc_memory_event_handler(unsigned long);
-#endif // __has_include(<malloc_private.h)
 extern bool _dispatch_memory_warn;
 #endif
 
 #if HAVE_PTHREAD_WORKQUEUE_KEVENT && defined(KEVENT_FLAG_WORKQ) && \
+		DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200) && \
 		!defined(DISPATCH_USE_KEVENT_WORKQUEUE)
 #define DISPATCH_USE_KEVENT_WORKQUEUE 1
 #endif
 
-#if (!DISPATCH_USE_KEVENT_WORKQUEUE || DISPATCH_DEBUG || DISPATCH_PROFILE) && \
+
+#if (!DISPATCH_USE_KEVENT_WORKQUEUE || DISPATCH_DEBUG) && \
 		!defined(DISPATCH_USE_MGR_THREAD)
 #define DISPATCH_USE_MGR_THREAD 1
 #endif
 
+#if DISPATCH_USE_KEVENT_WORKQUEUE && \
+		DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200) && \
+		!defined(DISPATCH_USE_EVFILT_MACHPORT_DIRECT)
+#define DISPATCH_USE_EVFILT_MACHPORT_DIRECT 1
+#endif
 
-#if defined(MACH_SEND_SYNC_OVERRIDE) && defined(MACH_RCV_SYNC_WAIT) && \
-		DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(109900) && \
-		!defined(DISPATCH_USE_MACH_SEND_SYNC_OVERRIDE)
-#define DISPATCH_USE_MACH_SEND_SYNC_OVERRIDE 1
+
+#if (!DISPATCH_USE_EVFILT_MACHPORT_DIRECT || DISPATCH_DEBUG) && \
+		!defined(DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK)
+#define DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK 1
 #endif
 
 #if defined(F_SETNOSIGPIPE) && defined(F_GETNOSIGPIPE)
@@ -745,8 +761,7 @@
 #else
 #define ARIADNE_ENTER_DISPATCH_MAIN_CODE 0
 #endif
-#if !defined(DISPATCH_USE_VOUCHER_KDEBUG_TRACE) && \
-		(DISPATCH_INTROSPECTION || DISPATCH_PROFILE)
+#if !defined(DISPATCH_USE_VOUCHER_KDEBUG_TRACE) && DISPATCH_INTROSPECTION
 #define DISPATCH_USE_VOUCHER_KDEBUG_TRACE 1
 #endif
 
@@ -762,6 +777,7 @@
 #define DISPATCH_PERF_delayed_registration DISPATCH_CODE(PERF, 4)
 #define DISPATCH_PERF_mutable_target DISPATCH_CODE(PERF, 5)
 #define DISPATCH_PERF_strict_bg_timer DISPATCH_CODE(PERF, 6)
+#define DISPATCH_PERF_wlh_change DISPATCH_CODE(PERF, 7)
 
 #define DISPATCH_MACH_MSG_hdr_move DISPATCH_CODE(MACH_MSG, 1)
 
@@ -821,12 +837,32 @@
 #endif
 #endif // VOUCHER_USE_MACH_VOUCHER
 
-#ifndef VOUCHER_USE_EMPTY_MACH_BASE_VOUCHER
 #if RDAR_24272659 // FIXME: <rdar://problem/24272659>
+#if !VOUCHER_USE_MACH_VOUCHER || !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
+#undef VOUCHER_USE_EMPTY_MACH_BASE_VOUCHER
+#define VOUCHER_USE_EMPTY_MACH_BASE_VOUCHER 0
+#elif !defined(VOUCHER_USE_EMPTY_MACH_BASE_VOUCHER)
 #define VOUCHER_USE_EMPTY_MACH_BASE_VOUCHER 1
+#endif
 #else // RDAR_24272659
+#undef VOUCHER_USE_EMPTY_MACH_BASE_VOUCHER
 #define VOUCHER_USE_EMPTY_MACH_BASE_VOUCHER 0
 #endif // RDAR_24272659
+
+#if !VOUCHER_USE_MACH_VOUCHER || !DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
+#undef VOUCHER_USE_BANK_AUTOREDEEM
+#define VOUCHER_USE_BANK_AUTOREDEEM 0
+#elif !defined(VOUCHER_USE_BANK_AUTOREDEEM)
+#define VOUCHER_USE_BANK_AUTOREDEEM 1
+#endif
+
+#if !VOUCHER_USE_MACH_VOUCHER || \
+		!__has_include(<voucher/ipc_pthread_priority_types.h>) || \
+		!DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
+#undef VOUCHER_USE_MACH_VOUCHER_PRIORITY
+#define VOUCHER_USE_MACH_VOUCHER_PRIORITY 0
+#elif !defined(VOUCHER_USE_MACH_VOUCHER_PRIORITY)
+#define VOUCHER_USE_MACH_VOUCHER_PRIORITY 1
 #endif
 
 #ifndef VOUCHER_USE_PERSONA
@@ -940,6 +976,22 @@
 #endif // DISPATCH_USE_KEVENT_WORKQUEUE
 
 
+#if DISPATCH_USE_EVFILT_MACHPORT_DIRECT
+#if !DISPATCH_USE_KEVENT_WORKQUEUE || !EV_UDATA_SPECIFIC
+#error Invalid build configuration
+#endif
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+extern int _dispatch_evfilt_machport_direct_enabled;
+#else
+#define _dispatch_evfilt_machport_direct_enabled (1)
+#endif
+#else
+#define _dispatch_evfilt_machport_direct_enabled (0)
+#endif // DISPATCH_USE_EVFILT_MACHPORT_DIRECT
+
+
+int _dispatch_sigmask(void);
+
 /* #includes dependent on internal.h */
 #include "object_internal.h"
 #include "semaphore_internal.h"
diff --git a/src/introspection.c b/src/introspection.c
index 8692a8b..cd6bcff 100644
--- a/src/introspection.c
+++ b/src/introspection.c
@@ -219,7 +219,7 @@
 	} else {
 		if (flags & DISPATCH_OBJ_SYNC_WAITER_BIT) {
 			dispatch_sync_context_t dsc = (dispatch_sync_context_t)dc;
-			waiter = pthread_from_mach_thread_np(dsc->dsc_waiter);
+			waiter = pthread_from_mach_thread_np((mach_port_t)dc->dc_data);
 			ctxt = dsc->dsc_ctxt;
 			func = dsc->dsc_func;
 		}
diff --git a/src/io.c b/src/io.c
index 2904373..f538862 100644
--- a/src/io.c
+++ b/src/io.c
@@ -233,7 +233,7 @@
 static dispatch_io_t
 _dispatch_io_create(dispatch_io_type_t type)
 {
-	dispatch_io_t channel = _dispatch_object_alloc(DISPATCH_VTABLE(io),
+	dispatch_io_t channel = _dispatch_alloc(DISPATCH_VTABLE(io),
 			sizeof(struct dispatch_io_s));
 	channel->do_next = DISPATCH_OBJECT_LISTLESS;
 	channel->do_targetq = _dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, true);
@@ -278,7 +278,7 @@
 }
 
 void
-_dispatch_io_dispose(dispatch_io_t channel, DISPATCH_UNUSED bool *allow_free)
+_dispatch_io_dispose(dispatch_io_t channel)
 {
 	_dispatch_object_debug(channel, "%s", __func__);
 	if (channel->fd_entry &&
@@ -682,9 +682,6 @@
 				_dispatch_channel_debug("stop cleanup", channel);
 				_dispatch_fd_entry_cleanup_operations(fd_entry, channel);
 				if (!(channel->atomic_flags & DIO_CLOSED)) {
-					if (fd_entry->path_data) {
-						fd_entry->path_data->channel = NULL;
-					}
 					channel->fd_entry = NULL;
 					_dispatch_fd_entry_release(fd_entry);
 				}
@@ -735,10 +732,9 @@
 						relaxed);
 				dispatch_fd_entry_t fd_entry = channel->fd_entry;
 				if (fd_entry) {
-					if (fd_entry->path_data) {
-						fd_entry->path_data->channel = NULL;
+					if (!fd_entry->path_data) {
+						channel->fd_entry = NULL;
 					}
-					channel->fd_entry = NULL;
 					_dispatch_fd_entry_release(fd_entry);
 				}
 			}
@@ -1023,13 +1019,14 @@
 		});
 		return NULL;
 	}
-	dispatch_operation_t op = _dispatch_object_alloc(DISPATCH_VTABLE(operation),
+	dispatch_operation_t op = _dispatch_alloc(DISPATCH_VTABLE(operation),
 			sizeof(struct dispatch_operation_s));
 	_dispatch_channel_debug("operation create: %p", channel, op);
 	op->do_next = DISPATCH_OBJECT_LISTLESS;
 	op->do_xref_cnt = -1; // operation object is not exposed externally
-	op->op_q = dispatch_queue_create_with_target("com.apple.libdispatch-io.opq",
-			NULL, queue);
+	op->op_q = dispatch_queue_create("com.apple.libdispatch-io.opq", NULL);
+	op->op_q->do_targetq = queue;
+	_dispatch_retain(queue);
 	op->active = false;
 	op->direction = direction;
 	op->offset = offset + channel->f_ptr;
@@ -1050,8 +1047,7 @@
 }
 
 void
-_dispatch_operation_dispose(dispatch_operation_t op,
-		DISPATCH_UNUSED bool *allow_free)
+_dispatch_operation_dispose(dispatch_operation_t op)
 {
 	_dispatch_object_debug(op, "%s", __func__);
 	_dispatch_op_debug("dispose", op);
@@ -1309,10 +1305,12 @@
 {
 	dispatch_fd_entry_t fd_entry;
 	fd_entry = _dispatch_calloc(1ul, sizeof(struct dispatch_fd_entry_s));
+	fd_entry->close_queue = dispatch_queue_create(
+			"com.apple.libdispatch-io.closeq", NULL);
 	// Use target queue to ensure that no concurrent lookups are going on when
 	// the close queue is running
-	fd_entry->close_queue = dispatch_queue_create_with_target(
-			"com.apple.libdispatch-io.closeq", NULL, q);
+	fd_entry->close_queue->do_targetq = q;
+	_dispatch_retain(q);
 	// Suspend the cleanup queue until closing
 	_dispatch_fd_entry_retain(fd_entry);
 	return fd_entry;
@@ -1586,9 +1584,11 @@
 	for (direction = 0; direction < DOP_DIR_MAX; direction++) {
 		dispatch_stream_t stream;
 		stream = _dispatch_calloc(1ul, sizeof(struct dispatch_stream_s));
-		stream->dq = dispatch_queue_create_with_target(
-				"com.apple.libdispatch-io.streamq", NULL, tq);
+		stream->dq = dispatch_queue_create("com.apple.libdispatch-io.streamq",
+				NULL);
 		dispatch_set_context(stream->dq, stream);
+		_dispatch_retain(tq);
+		stream->dq->do_targetq = tq;
 		TAILQ_INIT(&stream->operations[DISPATCH_IO_RANDOM]);
 		TAILQ_INIT(&stream->operations[DISPATCH_IO_STREAM]);
 		fd_entry->streams[direction] = stream;
@@ -1633,7 +1633,7 @@
 	}
 	// Otherwise create a new entry
 	size_t pending_reqs_depth = dispatch_io_defaults.max_pending_io_reqs;
-	disk = _dispatch_object_alloc(DISPATCH_VTABLE(disk),
+	disk = _dispatch_alloc(DISPATCH_VTABLE(disk),
 			sizeof(struct dispatch_disk_s) +
 			(pending_reqs_depth * sizeof(dispatch_operation_t)));
 	disk->do_next = DISPATCH_OBJECT_LISTLESS;
@@ -1654,7 +1654,7 @@
 }
 
 void
-_dispatch_disk_dispose(dispatch_disk_t disk, DISPATCH_UNUSED bool *allow_free)
+_dispatch_disk_dispose(dispatch_disk_t disk)
 {
 	uintptr_t hash = DIO_HASH(disk->dev);
 	TAILQ_REMOVE(&_dispatch_io_devs[hash], disk, disk_list);
diff --git a/src/io_internal.h b/src/io_internal.h
index 672727f..ad8259a 100644
--- a/src/io_internal.h
+++ b/src/io_internal.h
@@ -178,11 +178,10 @@
 
 void _dispatch_io_set_target_queue(dispatch_io_t channel, dispatch_queue_t dq);
 size_t _dispatch_io_debug(dispatch_io_t channel, char* buf, size_t bufsiz);
-void _dispatch_io_dispose(dispatch_io_t channel, bool *allow_free);
+void _dispatch_io_dispose(dispatch_io_t channel);
 size_t _dispatch_operation_debug(dispatch_operation_t op, char* buf,
 		size_t bufsiz);
-void _dispatch_operation_dispose(dispatch_operation_t operation,
-		bool *allow_free);
-void _dispatch_disk_dispose(dispatch_disk_t disk, bool *allow_free);
+void _dispatch_operation_dispose(dispatch_operation_t operation);
+void _dispatch_disk_dispose(dispatch_disk_t disk);
 
 #endif // __DISPATCH_IO_INTERNAL__
diff --git a/src/libdispatch.codes b/src/libdispatch.codes
index 0ecc333..64f82b5 100644
--- a/src/libdispatch.codes
+++ b/src/libdispatch.codes
@@ -12,6 +12,7 @@
 0x2e020010	DISPATCH_PERF_delayed_registration
 0x2e020014	DISPATCH_PERF_mutable_target
 0x2e020018	DISPATCH_PERF_strict_bg_timer
+0x2e02001c	DISPATCH_PERF_wlh_change
 
 0x2e030004	DISPATCH_MACH_MSG_hdr_move
 
diff --git a/src/mach.c b/src/mach.c
index 0f9e9a8..cc20645 100644
--- a/src/mach.c
+++ b/src/mach.c
@@ -33,7 +33,7 @@
 
 DISPATCH_ENUM(dispatch_mach_send_invoke_flags, uint32_t,
 	DM_SEND_INVOKE_NONE            = 0x0,
-	DM_SEND_INVOKE_MAKE_DIRTY      = 0x1,
+	DM_SEND_INVOKE_FLUSH           = 0x1,
 	DM_SEND_INVOKE_NEEDS_BARRIER   = 0x2,
 	DM_SEND_INVOKE_CANCEL          = 0x4,
 	DM_SEND_INVOKE_CAN_RUN_BARRIER = 0x8,
@@ -43,6 +43,8 @@
 		((dispatch_mach_send_invoke_flags_t)DM_SEND_INVOKE_IMMEDIATE_SEND)
 
 static inline mach_msg_option_t _dispatch_mach_checkin_options(void);
+static inline pthread_priority_t _dispatch_mach_priority_propagate(
+		mach_msg_option_t options);
 static mach_port_t _dispatch_mach_msg_get_remote_port(dispatch_object_t dou);
 static mach_port_t _dispatch_mach_msg_get_reply_port(dispatch_object_t dou);
 static void _dispatch_mach_msg_disconnected(dispatch_mach_t dm,
@@ -121,14 +123,6 @@
 			"_dispatch_mach_default_async_reply_handler called");
 }
 
-// Default dmxh_enable_sigterm_notification callback that enables delivery of
-// SIGTERM notifications (for backwards compatibility).
-static bool
-_dispatch_mach_enable_sigterm(void *_Nullable context DISPATCH_UNUSED)
-{
-	return true;
-}
-
 // Callbacks from dispatch to XPC. The default is to not support any callbacks.
 static const struct dispatch_mach_xpc_hooks_s _dispatch_mach_xpc_hooks_default
 		= {
@@ -137,7 +131,6 @@
 	.dmxh_msg_context_reply_queue =
 			&_dispatch_mach_msg_context_no_async_reply_queue,
 	.dmxh_async_reply_handler = &_dispatch_mach_default_async_reply_handler,
-	.dmxh_enable_sigterm_notification = &_dispatch_mach_enable_sigterm,
 };
 
 static dispatch_mach_xpc_hooks_t _dispatch_mach_xpc_hooks
@@ -164,17 +157,17 @@
 	dispatch_mach_recv_refs_t dmrr;
 	dispatch_mach_send_refs_t dmsr;
 	dispatch_mach_t dm;
-	dm = _dispatch_object_alloc(DISPATCH_VTABLE(mach),
+	// ensure _dispatch_evfilt_machport_direct_enabled is initialized
+	_dispatch_root_queues_init();
+	dm = _dispatch_alloc(DISPATCH_VTABLE(mach),
 			sizeof(struct dispatch_mach_s));
-	_dispatch_queue_init(dm->_as_dq, DQF_LEGACY, 1,
-			DISPATCH_QUEUE_INACTIVE | DISPATCH_QUEUE_ROLE_INNER);
+	_dispatch_queue_init(dm->_as_dq, DQF_LEGACY, 1, true);
 
 	dm->dq_label = label;
 	dm->do_ref_cnt++; // the reference _dispatch_mach_cancel_invoke holds
 	dm->dm_is_xpc = is_xpc;
 
 	dmrr = dux_create(&_dispatch_mach_type_recv, 0, 0)._dmrr;
-	dispatch_assert(dmrr->du_is_direct);
 	dmrr->du_owner_wref = _dispatch_ptr2wref(dm);
 	dmrr->dmrr_handler_func = handler;
 	dmrr->dmrr_handler_ctxt = context;
@@ -186,6 +179,13 @@
 	dmsr->du_owner_wref = _dispatch_ptr2wref(dm);
 	dm->dm_send_refs = dmsr;
 
+	if (is_xpc) {
+		dispatch_xpc_term_refs_t _dxtr =
+				dux_create(&_dispatch_xpc_type_sigterm, SIGTERM, 0)._dxtr;
+		_dxtr->du_owner_wref = _dispatch_ptr2wref(dm);
+		dm->dm_xpc_term_refs = _dxtr;
+	}
+
 	if (slowpath(!q)) {
 		q = _dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, true);
 	} else {
@@ -221,7 +221,7 @@
 }
 
 void
-_dispatch_mach_dispose(dispatch_mach_t dm, bool *allow_free)
+_dispatch_mach_dispose(dispatch_mach_t dm)
 {
 	_dispatch_object_debug(dm, "%s", __func__);
 	_dispatch_unote_dispose(dm->dm_recv_refs);
@@ -232,7 +232,7 @@
 		_dispatch_unote_dispose(dm->dm_xpc_term_refs);
 		dm->dm_xpc_term_refs = NULL;
 	}
-	_dispatch_queue_destroy(dm->_as_dq, allow_free);
+	_dispatch_queue_destroy(dm->_as_dq);
 }
 
 void
@@ -309,66 +309,69 @@
 	if (dmsgr) {
 		return _dispatch_mach_handle_or_push_received_msg(dm, dmsgr);
 	}
+	dispatch_assert(!(options & DU_UNREGISTER_WAKEUP));
 }
 
 DISPATCH_NOINLINE
-static bool
-_dispatch_mach_reply_list_remove(dispatch_mach_t dm,
-		dispatch_mach_reply_refs_t dmr) {
-	// dmsr_replies_lock must be held by the caller.
-	bool removed = false;
-	if (likely(_TAILQ_IS_ENQUEUED(dmr, dmr_list))) {
-		TAILQ_REMOVE(&dm->dm_send_refs->dmsr_replies, dmr, dmr_list);
-		_TAILQ_MARK_NOT_ENQUEUED(dmr, dmr_list);
-		removed = true;
-	}
-	return removed;
-}
-
-DISPATCH_NOINLINE
-static bool
+static void
 _dispatch_mach_reply_kevent_unregister(dispatch_mach_t dm,
 		dispatch_mach_reply_refs_t dmr, uint32_t options)
 {
-	dispatch_assert(!_TAILQ_IS_ENQUEUED(dmr, dmr_list));
-
-	bool disconnected = (options & DU_UNREGISTER_DISCONNECTED);
-	_dispatch_debug("machport[0x%08x]: unregistering for reply%s, ctxt %p",
-			(mach_port_t)dmr->du_ident, disconnected ? " (disconnected)" : "",
-			dmr->dmr_ctxt);
-	if (!_dispatch_unote_unregister(dmr, options)) {
-		_dispatch_debug("machport[0x%08x]: deferred delete kevent[%p]",
-						(mach_port_t)dmr->du_ident, dmr);
-		dispatch_assert(options == DU_UNREGISTER_DISCONNECTED);
-		return false;
-	}
-
 	dispatch_mach_msg_t dmsgr = NULL;
 	dispatch_queue_t drq = NULL;
+	bool replies_empty = false;
+	bool disconnected = (options & DU_UNREGISTER_DISCONNECTED);
+	if (options & DU_UNREGISTER_REPLY_REMOVE) {
+		_dispatch_unfair_lock_lock(&dm->dm_send_refs->dmsr_replies_lock);
+		if (unlikely(!_TAILQ_IS_ENQUEUED(dmr, dmr_list))) {
+			DISPATCH_INTERNAL_CRASH(0, "Could not find reply registration");
+		}
+		TAILQ_REMOVE(&dm->dm_send_refs->dmsr_replies, dmr, dmr_list);
+		_TAILQ_MARK_NOT_ENQUEUED(dmr, dmr_list);
+		replies_empty = TAILQ_EMPTY(&dm->dm_send_refs->dmsr_replies);
+		_dispatch_unfair_lock_unlock(&dm->dm_send_refs->dmsr_replies_lock);
+	}
 	if (disconnected) {
-		// The next call is guaranteed to always transfer or consume the voucher
-		// in the dmr, if there is one.
 		dmsgr = _dispatch_mach_msg_create_reply_disconnected(NULL, dmr,
 			dmr->dmr_async_reply ? DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED
 			: DISPATCH_MACH_DISCONNECTED);
 		if (dmr->dmr_ctxt) {
 			drq = _dispatch_mach_msg_context_async_reply_queue(dmr->dmr_ctxt);
 		}
-		dispatch_assert(dmr->dmr_voucher == NULL);
 	} else if (dmr->dmr_voucher) {
 		_voucher_release(dmr->dmr_voucher);
 		dmr->dmr_voucher = NULL;
 	}
+	_dispatch_debug("machport[0x%08x]: unregistering for reply%s, ctxt %p",
+			(mach_port_t)dmr->du_ident, disconnected ? " (disconnected)" : "",
+			dmr->dmr_ctxt);
+	if (!_dispatch_unote_unregister(dmr, options)) {
+		_dispatch_debug("machport[0x%08x]: deferred delete kevent[%p]",
+				(mach_port_t)dmr->du_ident, dmr);
+		dispatch_assert(options == DU_UNREGISTER_DISCONNECTED);
+		// dmr must be put back so that the event delivery finds it, the
+		// replies lock is held by the caller.
+		TAILQ_INSERT_HEAD(&dm->dm_send_refs->dmsr_replies, dmr, dmr_list);
+		if (dmsgr) {
+			dmr->dmr_voucher = dmsgr->dmsg_voucher;
+			dmsgr->dmsg_voucher = NULL;
+			_dispatch_release(dmsgr);
+		}
+		return; // deferred unregistration
+	}
 	_dispatch_unote_dispose(dmr);
-
 	if (dmsgr) {
 		if (drq) {
-			_dispatch_mach_push_async_reply_msg(dm, dmsgr, drq);
+			return _dispatch_mach_push_async_reply_msg(dm, dmsgr, drq);
 		} else {
-			_dispatch_mach_handle_or_push_received_msg(dm, dmsgr);
+			return _dispatch_mach_handle_or_push_received_msg(dm, dmsgr);
 		}
 	}
-	return true;
+	if ((options & DU_UNREGISTER_WAKEUP) && replies_empty &&
+			(dm->dm_send_refs->dmsr_disconnect_cnt ||
+			(dm->dq_atomic_flags & DSF_CANCELED))) {
+		dx_wakeup(dm, 0, DISPATCH_WAKEUP_FLUSH);
+	}
 }
 
 DISPATCH_NOINLINE
@@ -409,11 +412,10 @@
 		dispatch_mach_msg_t dmsg)
 {
 	dispatch_mach_reply_refs_t dmr;
-	dispatch_priority_t mpri, pri, overcommit;
-	dispatch_wlh_t wlh;
+	dispatch_priority_t mpri, pri, rpri;
+	dispatch_priority_t overcommit;
 
 	dmr = dux_create(&_dispatch_mach_type_reply, reply_port, 0)._dmr;
-	dispatch_assert(dmr->du_is_direct);
 	dmr->du_owner_wref = _dispatch_ptr2wref(dm);
 	if (dmsg->dmsg_voucher) {
 		dmr->dmr_voucher = _voucher_retain(dmsg->dmsg_voucher);
@@ -428,22 +430,18 @@
 		drq = _dispatch_mach_msg_context_async_reply_queue(dmsg->do_ctxt);
 	}
 
-	if (!drq) {
-		pri = dm->dq_priority;
-		wlh = dm->dm_recv_refs->du_wlh;
-	} else if (dx_hastypeflag(drq, QUEUE_ROOT)) {
-		pri = drq->dq_priority;
-		wlh = DISPATCH_WLH_ANON;
-	} else if (drq == dm->do_targetq) {
-		pri = dm->dq_priority;
-		wlh = dm->dm_recv_refs->du_wlh;
-	} else if (!(pri = _dispatch_queue_compute_priority_and_wlh(drq, &wlh))) {
-		pri = drq->dq_priority;
-		wlh = DISPATCH_WLH_ANON;
+	dispatch_wlh_t wlh = dm->dq_wlh;
+	pri = (dm->dq_priority & DISPATCH_PRIORITY_REQUESTED_MASK);
+	overcommit = dm->dq_priority & DISPATCH_PRIORITY_FLAG_OVERCOMMIT;
+	if (drq) {
+		rpri = drq->dq_priority & DISPATCH_PRIORITY_REQUESTED_MASK;
+		if (rpri > pri) {
+			pri = rpri;
+			overcommit = drq->dq_priority & DISPATCH_PRIORITY_FLAG_OVERCOMMIT;
+		}
+		if (drq->dq_wlh) wlh = drq->dq_wlh;
 	}
-	if (pri & DISPATCH_PRIORITY_REQUESTED_MASK) {
-		overcommit = pri & DISPATCH_PRIORITY_FLAG_OVERCOMMIT;
-		pri &= DISPATCH_PRIORITY_REQUESTED_MASK;
+	if (pri && dmr->du_is_direct) {
 		mpri = _dispatch_priority_from_pp_strip_flags(dmsg->dmsg_priority);
 		if (pri < mpri) pri = mpri;
 		pri |= overcommit;
@@ -462,54 +460,25 @@
 	_dispatch_unfair_lock_unlock(&dm->dm_send_refs->dmsr_replies_lock);
 
 	if (!_dispatch_unote_register(dmr, wlh, pri)) {
-		_dispatch_unfair_lock_lock(&dm->dm_send_refs->dmsr_replies_lock);
-		_dispatch_mach_reply_list_remove(dm, dmr);
-		_dispatch_unfair_lock_unlock(&dm->dm_send_refs->dmsr_replies_lock);
 		_dispatch_mach_reply_kevent_unregister(dm, dmr,
-				DU_UNREGISTER_DISCONNECTED);
+				DU_UNREGISTER_DISCONNECTED|DU_UNREGISTER_REPLY_REMOVE);
 	}
 }
 
 #pragma mark -
 #pragma mark dispatch_mach_msg
 
-DISPATCH_ALWAYS_INLINE DISPATCH_CONST
-static inline bool
-_dispatch_use_mach_special_reply_port(void)
-{
-#if DISPATCH_USE_MACH_SEND_SYNC_OVERRIDE
-	return true;
-#else
-#define thread_get_special_reply_port() ({__builtin_trap(); MACH_PORT_NULL;})
-	return false;
-#endif
-}
-
 static mach_port_t
 _dispatch_get_thread_reply_port(void)
 {
-	mach_port_t reply_port, mrp;
-	if (_dispatch_use_mach_special_reply_port()) {
-		mrp = _dispatch_get_thread_special_reply_port();
-	} else {
-		mrp = _dispatch_get_thread_mig_reply_port();
-	}
+	mach_port_t reply_port, mrp = _dispatch_get_thread_mig_reply_port();
 	if (mrp) {
 		reply_port = mrp;
 		_dispatch_debug("machport[0x%08x]: borrowed thread sync reply port",
 				reply_port);
 	} else {
-		if (_dispatch_use_mach_special_reply_port()) {
-			reply_port = thread_get_special_reply_port();
-			_dispatch_set_thread_special_reply_port(reply_port);
-		} else {
-			reply_port = mach_reply_port();
-			_dispatch_set_thread_mig_reply_port(reply_port);
-		}
-		if (unlikely(!MACH_PORT_VALID(reply_port))) {
-			DISPATCH_CLIENT_CRASH(_dispatch_use_mach_special_reply_port(),
-				"Unable to allocate reply port, possible port leak");
-		}
+		reply_port = mach_reply_port();
+		_dispatch_set_thread_mig_reply_port(reply_port);
 		_dispatch_debug("machport[0x%08x]: allocated thread sync reply port",
 				reply_port);
 	}
@@ -520,12 +489,7 @@
 static void
 _dispatch_clear_thread_reply_port(mach_port_t reply_port)
 {
-	mach_port_t mrp;
-	if (_dispatch_use_mach_special_reply_port()) {
-		mrp = _dispatch_get_thread_special_reply_port();
-	} else {
-		mrp = _dispatch_get_thread_mig_reply_port();
-	}
+	mach_port_t mrp = _dispatch_get_thread_mig_reply_port();
 	if (reply_port != mrp) {
 		if (mrp) {
 			_dispatch_debug("machport[0x%08x]: did not clear thread sync reply "
@@ -533,11 +497,7 @@
 		}
 		return;
 	}
-	if (_dispatch_use_mach_special_reply_port()) {
-		_dispatch_set_thread_special_reply_port(MACH_PORT_NULL);
-	} else {
-		_dispatch_set_thread_mig_reply_port(MACH_PORT_NULL);
-	}
+	_dispatch_set_thread_mig_reply_port(MACH_PORT_NULL);
 	_dispatch_debug_machport(reply_port);
 	_dispatch_debug("machport[0x%08x]: cleared thread sync reply port",
 			reply_port);
@@ -547,12 +507,7 @@
 _dispatch_set_thread_reply_port(mach_port_t reply_port)
 {
 	_dispatch_debug_machport(reply_port);
-	mach_port_t mrp;
-	if (_dispatch_use_mach_special_reply_port()) {
-		mrp = _dispatch_get_thread_special_reply_port();
-	} else {
-		mrp = _dispatch_get_thread_mig_reply_port();
-	}
+	mach_port_t mrp = _dispatch_get_thread_mig_reply_port();
 	if (mrp) {
 		kern_return_t kr = mach_port_mod_refs(mach_task_self(), reply_port,
 				MACH_PORT_RIGHT_RECEIVE, -1);
@@ -561,11 +516,7 @@
 		_dispatch_debug("machport[0x%08x]: deallocated sync reply port "
 				"(found 0x%08x)", reply_port, mrp);
 	} else {
-		if (_dispatch_use_mach_special_reply_port()) {
-			_dispatch_set_thread_special_reply_port(reply_port);
-		} else {
-			_dispatch_set_thread_mig_reply_port(reply_port);
-		}
+		_dispatch_set_thread_mig_reply_port(reply_port);
 		_dispatch_debug("machport[0x%08x]: restored thread sync reply port",
 				reply_port);
 	}
@@ -627,8 +578,7 @@
 		dmr->dmr_voucher = NULL; // transfer reference
 	} else {
 		voucher = voucher_create_with_mach_msg(hdr);
-		pp = _dispatch_priority_compute_propagated(
-				_voucher_get_priority(voucher), 0);
+		pp = _voucher_get_priority(voucher);
 	}
 
 	destructor = (flags & DISPATCH_EV_MSG_NEEDS_FREE) ?
@@ -659,6 +609,7 @@
 
 	dispatch_mach_recv_refs_t dmrr = du._dmrr;
 	dispatch_mach_t dm = _dispatch_wref2ptr(dmrr->du_owner_wref);
+	dispatch_wakeup_flags_t wflags = 0;
 	dispatch_queue_flags_t dqf;
 	dispatch_mach_msg_t dmsg;
 
@@ -669,24 +620,31 @@
 				"Unexpected EV_VANISHED (do not destroy random mach ports)");
 	}
 
-	// once we modify the queue atomic flags below, it will allow concurrent
-	// threads running _dispatch_mach_invoke2 to dispose of the source,
-	// so we can't safely borrow the reference we get from the muxnote udata
-	// anymore, and need our own
-	dispatch_wakeup_flags_t wflags = DISPATCH_WAKEUP_CONSUME_2;
-	_dispatch_retain_2(dm); // rdar://20382435
+	if (dmrr->du_is_direct || (flags & (EV_DELETE | EV_ONESHOT))) {
+		// once we modify the queue atomic flags below, it will allow concurrent
+		// threads running _dispatch_mach_invoke2 to dispose of the source,
+		// so we can't safely borrow the reference we get from the muxnote udata
+		// anymore, and need our own
+		wflags = DISPATCH_WAKEUP_CONSUME;
+		_dispatch_retain(dm); // rdar://20382435
+	}
 
 	if (unlikely((flags & EV_ONESHOT) && !(flags & EV_DELETE))) {
-		dqf = _dispatch_queue_atomic_flags_set_and_clear(dm->_as_dq,
-				DSF_DEFERRED_DELETE, DSF_ARMED);
+		dqf = _dispatch_queue_atomic_flags(dm->_as_dq);
 		_dispatch_debug("kevent-source[%p]: deferred delete oneshot kevent[%p]",
 				dm, dmrr);
-	} else if (unlikely(flags & (EV_ONESHOT | EV_DELETE))) {
+	} else if (unlikely(flags & EV_DELETE)) {
 		_dispatch_source_refs_unregister(dm->_as_ds,
 				DU_UNREGISTER_ALREADY_DELETED);
 		dqf = _dispatch_queue_atomic_flags(dm->_as_dq);
 		_dispatch_debug("kevent-source[%p]: deleted kevent[%p]", dm, dmrr);
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+	} else if (unlikely(!dmrr->du_is_direct)) {
+		dqf = _dispatch_queue_atomic_flags(dm->_as_dq);
+		_dispatch_unote_resume(du);
+#endif
 	} else {
+		dispatch_assert(dmrr->du_is_direct);
 		dqf = _dispatch_queue_atomic_flags_clear(dm->_as_dq, DSF_ARMED);
 		_dispatch_debug("kevent-source[%p]: disarmed kevent[%p]", dm, dmrr);
 	}
@@ -702,20 +660,14 @@
 		if (flags & DISPATCH_EV_MSG_NEEDS_FREE) {
 			free(hdr);
 		}
-		return dx_wakeup(dm, 0, wflags | DISPATCH_WAKEUP_MAKE_DIRTY);
+		return dx_wakeup(dm, 0, wflags | DISPATCH_WAKEUP_FLUSH);
 	}
 
-	// Once the mach channel disarming is visible, cancellation will switch to
-	// immediate deletion.  If we're preempted here, then the whole cancellation
-	// sequence may be complete by the time we really enqueue the message.
-	//
-	// _dispatch_mach_msg_invoke_with_mach() is responsible for filtering it out
-	// to keep the promise that DISPATCH_MACH_DISCONNECTED is the last
-	// event sent.
-
 	dmsg = _dispatch_mach_msg_create_recv(hdr, siz, NULL, flags);
 	_dispatch_mach_handle_or_push_received_msg(dm, dmsg);
-	return _dispatch_release_2_tailcall(dm);
+	if (wflags & DISPATCH_WAKEUP_CONSUME) {
+		return _dispatch_release_tailcall(dm);
+	}
 }
 
 void
@@ -731,11 +683,23 @@
 	_dispatch_debug("machport[0x%08x]: received msg id 0x%x, reply on 0x%08x",
 			hdr->msgh_local_port, hdr->msgh_id, hdr->msgh_remote_port);
 
-	if (!canceled) {
+	uint32_t options = DU_UNREGISTER_IMMEDIATE_DELETE;
+	options |= DU_UNREGISTER_REPLY_REMOVE;
+	options |= DU_UNREGISTER_WAKEUP;
+	if (canceled) {
+		_dispatch_debug("machport[0x%08x]: drop msg id 0x%x, reply on 0x%08x",
+				hdr->msgh_local_port, hdr->msgh_id, hdr->msgh_remote_port);
+		options |= DU_UNREGISTER_DISCONNECTED;
+		mach_msg_destroy(hdr);
+		if (flags & DISPATCH_EV_MSG_NEEDS_FREE) {
+			free(hdr);
+		}
+	} else {
 		dmsg = _dispatch_mach_msg_create_recv(hdr, siz, dmr, flags);
 	}
+	_dispatch_mach_reply_kevent_unregister(dm, dmr, options);
 
-	if (dmsg) {
+	if (!canceled) {
 		dispatch_queue_t drq = NULL;
 		if (dmsg->do_ctxt) {
 			drq = _dispatch_mach_msg_context_async_reply_queue(dmsg->do_ctxt);
@@ -745,45 +709,13 @@
 		} else {
 			_dispatch_mach_handle_or_push_received_msg(dm, dmsg);
 		}
-	} else {
-		_dispatch_debug("machport[0x%08x]: drop msg id 0x%x, reply on 0x%08x",
-				hdr->msgh_local_port, hdr->msgh_id, hdr->msgh_remote_port);
-		mach_msg_destroy(hdr);
-		if (flags & DISPATCH_EV_MSG_NEEDS_FREE) {
-			free(hdr);
-		}
 	}
-
-	dispatch_wakeup_flags_t wflags = 0;
-	uint32_t options = DU_UNREGISTER_IMMEDIATE_DELETE;
-	if (canceled) {
-		options |= DU_UNREGISTER_DISCONNECTED;
-	}
-
-	_dispatch_unfair_lock_lock(&dm->dm_send_refs->dmsr_replies_lock);
-	bool removed = _dispatch_mach_reply_list_remove(dm, dmr);
-	dispatch_assert(removed);
-	if (TAILQ_EMPTY(&dm->dm_send_refs->dmsr_replies) &&
-			(dm->dm_send_refs->dmsr_disconnect_cnt ||
-			(dm->dq_atomic_flags & DSF_CANCELED))) {
-		// When the list is empty, _dispatch_mach_disconnect() may release the
-		// last reference count on the Mach channel. To avoid this, take our
-		// own reference before releasing the lock.
-		wflags = DISPATCH_WAKEUP_MAKE_DIRTY | DISPATCH_WAKEUP_CONSUME_2;
-		_dispatch_retain_2(dm);
-	}
-	_dispatch_unfair_lock_unlock(&dm->dm_send_refs->dmsr_replies_lock);
-
-	bool result = _dispatch_mach_reply_kevent_unregister(dm, dmr, options);
-	dispatch_assert(result);
-	if (wflags) dx_wakeup(dm, 0, wflags);
 }
 
 DISPATCH_ALWAYS_INLINE
 static inline dispatch_mach_msg_t
 _dispatch_mach_msg_reply_recv(dispatch_mach_t dm,
-		dispatch_mach_reply_refs_t dmr, mach_port_t reply_port,
-		mach_port_t send)
+		dispatch_mach_reply_refs_t dmr, mach_port_t reply_port)
 {
 	if (slowpath(!MACH_PORT_VALID(reply_port))) {
 		DISPATCH_CLIENT_CRASH(reply_port, "Invalid reply port");
@@ -794,7 +726,6 @@
 	mach_msg_size_t siz, msgsiz = 0;
 	mach_msg_return_t kr;
 	mach_msg_option_t options;
-	mach_port_t notify = MACH_PORT_NULL;
 	siz = mach_vm_round_page(DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE +
 			DISPATCH_MACH_TRAILER_SIZE);
 	hdr = alloca(siz);
@@ -803,17 +734,12 @@
 		*(char*)p = 0; // ensure alloca buffer doesn't overlap with stack guard
 	}
 	options = DISPATCH_MACH_RCV_OPTIONS & (~MACH_RCV_VOUCHER);
-	if (MACH_PORT_VALID(send)) {
-		notify = send;
-		options |= MACH_RCV_SYNC_WAIT;
-	}
-
 retry:
 	_dispatch_debug_machport(reply_port);
 	_dispatch_debug("machport[0x%08x]: MACH_RCV_MSG %s", reply_port,
 			(options & MACH_RCV_TIMEOUT) ? "poll" : "wait");
 	kr = mach_msg(hdr, options, 0, siz, reply_port, MACH_MSG_TIMEOUT_NONE,
-			notify);
+			MACH_PORT_NULL);
 	hdr_copyout_addr = hdr;
 	_dispatch_debug_machport(reply_port);
 	_dispatch_debug("machport[0x%08x]: MACH_RCV_MSG (size %u, opts 0x%x) "
@@ -861,9 +787,8 @@
 			if (shrink) hdr = hdr2 = shrink;
 		}
 		break;
-	case MACH_RCV_INVALID_NOTIFY:
 	default:
-		DISPATCH_INTERNAL_CRASH(kr, "Unexpected error from mach_msg_receive");
+		dispatch_assume_zero(kr);
 		break;
 	}
 	_dispatch_mach_msg_reply_received(dm, dmr, hdr->msgh_local_port);
@@ -1099,20 +1024,15 @@
 			} else {
 				clear_voucher = _voucher_mach_msg_set(msg, voucher);
 			}
-			if (qos) {
+			if (qos && _dispatch_evfilt_machport_direct_enabled) {
 				opts |= MACH_SEND_OVERRIDE;
-				msg_priority = (mach_msg_priority_t)
-						_dispatch_priority_compute_propagated(
-						_dispatch_qos_to_pp(qos), 0);
+				msg_priority = (mach_msg_priority_t)_dispatch_qos_to_pp(qos);
 			}
 		}
 		_dispatch_debug_machport(msg->msgh_remote_port);
 		if (reply_port) _dispatch_debug_machport(reply_port);
 		if (msg_opts & DISPATCH_MACH_WAIT_FOR_REPLY) {
 			if (msg_opts & DISPATCH_MACH_OWNED_REPLY_PORT) {
-				if (_dispatch_use_mach_special_reply_port()) {
-					opts |= MACH_SEND_SYNC_OVERRIDE;
-				}
 				_dispatch_clear_thread_reply_port(reply_port);
 			}
 			_dispatch_mach_reply_waiter_register(dm, dmr, reply_port, dmsg,
@@ -1165,6 +1085,13 @@
 	if (!(msg_opts & DISPATCH_MACH_WAIT_FOR_REPLY) && !kr && reply_port &&
 			!(_dispatch_unote_registered(dmrr) &&
 			dmrr->du_ident == reply_port)) {
+		if (!dmrr->du_is_direct &&
+				_dispatch_queue_get_current() != &_dispatch_mgr_q) {
+			// reply receive kevent must be installed on the manager queue
+			dm->dm_needs_mgr = 1;
+			dmsg->dmsg_options = msg_opts | DISPATCH_MACH_REGISTER_FOR_REPLY;
+			goto out;
+		}
 		_dispatch_mach_reply_kevent_register(dm, reply_port, dmsg);
 	}
 	if (unlikely(!is_reply && dmsg == dsrr->dmsr_checkin &&
@@ -1204,9 +1131,6 @@
 #pragma mark -
 #pragma mark dispatch_mach_send_refs_t
 
-#define _dmsr_state_needs_lock_override(dq_state, qos) \
-		unlikely(qos < _dq_state_max_qos(dq_state))
-
 DISPATCH_ALWAYS_INLINE
 static inline dispatch_qos_t
 _dmsr_state_max_qos(uint64_t dmsr_state)
@@ -1246,8 +1170,11 @@
 #define _dispatch_mach_send_pop_head(dmsr, head) \
 		os_mpsc_pop_head(dmsr, dmsr, head, do_next)
 
-#define dm_push(dm, dc, qos) \
-		_dispatch_queue_push((dm)->_as_dq, dc, qos)
+#define dm_push(dm, dc, qos) ({ \
+		dispatch_queue_t _dq = (dm)->_as_dq; \
+		dispatch_assert(dx_vtable(_dq)->do_push == _dispatch_queue_push); \
+		_dispatch_queue_push(_dq, dc, qos); \
+	})
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
@@ -1299,7 +1226,8 @@
 				dmsg = (dispatch_mach_msg_t)dc;
 				dmr = NULL;
 			} else {
-				if (_dispatch_unote_registered(dmsr) &&
+				if ((_dispatch_unote_registered(dmsr) ||
+						!dm->dm_recv_refs->du_is_direct) &&
 						(_dispatch_queue_get_current() != &_dispatch_mgr_q)) {
 					// send kevent must be uninstalled on the manager queue
 					needs_mgr = true;
@@ -1393,7 +1321,7 @@
 		} else {
 			qos = 0;
 		}
-		if (!disconnecting) dx_wakeup(dm, qos, DISPATCH_WAKEUP_MAKE_DIRTY);
+		if (!disconnecting) dx_wakeup(dm, qos, DISPATCH_WAKEUP_FLUSH);
 	}
 	return returning_send_result;
 }
@@ -1404,7 +1332,7 @@
 		dispatch_mach_send_invoke_flags_t send_flags)
 {
 	dispatch_mach_send_refs_t dmsr = dm->dm_send_refs;
-	dispatch_lock owner_self = _dispatch_lock_value_for_self();
+	dispatch_lock_owner tid_self = _dispatch_tid_self();
 	uint64_t old_state, new_state;
 
 	uint64_t canlock_mask = DISPATCH_MACH_STATE_UNLOCK_MASK;
@@ -1422,18 +1350,18 @@
 	os_atomic_rmw_loop2o(dmsr, dmsr_state, old_state, new_state, acquire, {
 		new_state = old_state;
 		if (unlikely((old_state & canlock_mask) != canlock_state)) {
-			if (!(send_flags & DM_SEND_INVOKE_MAKE_DIRTY)) {
+			if (!(send_flags & DM_SEND_INVOKE_FLUSH)) {
 				os_atomic_rmw_loop_give_up(break);
 			}
 			new_state |= DISPATCH_MACH_STATE_DIRTY;
 		} else {
-			if (_dmsr_state_needs_lock_override(old_state, oq_floor)) {
+			if (_dispatch_queue_should_override_self(old_state, oq_floor)) {
 				os_atomic_rmw_loop_give_up({
 					oq_floor = _dispatch_queue_override_self(old_state);
 					goto retry;
 				});
 			}
-			new_state |= owner_self;
+			new_state |= tid_self;
 			new_state &= ~DISPATCH_MACH_STATE_DIRTY;
 			new_state &= ~DISPATCH_MACH_STATE_RECEIVED_OVERRIDE;
 			new_state &= ~DISPATCH_MACH_STATE_PENDING_BARRIER;
@@ -1491,14 +1419,14 @@
 {
 	dispatch_mach_send_refs_t dmsr = dm->dm_send_refs;
 	uint64_t old_state, new_state, state_flags = 0;
-	dispatch_tid owner;
+	dispatch_lock_owner owner;
 	bool wakeup;
 
 	// <rdar://problem/25896179> when pushing a send barrier that destroys
 	// the last reference to this channel, and the send queue is already
 	// draining on another thread, the send barrier may run as soon as
 	// _dispatch_mach_send_push_inline() returns.
-	_dispatch_retain_2(dm);
+	_dispatch_retain(dm);
 
 	wakeup = _dispatch_mach_send_push_inline(dmsr, dc);
 	if (wakeup) {
@@ -1529,7 +1457,7 @@
 			_dispatch_wqthread_override_start_check_owner(owner, qos,
 					&dmsr->dmsr_state_lock.dul_lock);
 		}
-		return _dispatch_release_2_tailcall(dm);
+		return _dispatch_release_tailcall(dm);
 	}
 
 	dispatch_wakeup_flags_t wflags = 0;
@@ -1537,14 +1465,14 @@
 		_dispatch_mach_send_barrier_drain_push(dm, qos);
 	} else if (wakeup || dmsr->dmsr_disconnect_cnt ||
 			(dm->dq_atomic_flags & DSF_CANCELED)) {
-		wflags = DISPATCH_WAKEUP_MAKE_DIRTY | DISPATCH_WAKEUP_CONSUME_2;
+		wflags = DISPATCH_WAKEUP_FLUSH | DISPATCH_WAKEUP_CONSUME;
 	} else if (old_state & DISPATCH_MACH_STATE_PENDING_BARRIER) {
-		wflags = DISPATCH_WAKEUP_CONSUME_2;
+		wflags = DISPATCH_WAKEUP_OVERRIDING | DISPATCH_WAKEUP_CONSUME;
 	}
 	if (wflags) {
 		return dx_wakeup(dm, qos, wflags);
 	}
-	return _dispatch_release_2_tailcall(dm);
+	return _dispatch_release_tailcall(dm);
 }
 
 DISPATCH_NOINLINE
@@ -1554,9 +1482,9 @@
 		dispatch_mach_send_invoke_flags_t send_flags)
 {
 	dispatch_mach_send_refs_t dmsr = dm->dm_send_refs;
-	dispatch_lock owner_self = _dispatch_lock_value_for_self();
+	dispatch_lock_owner tid_self = _dispatch_tid_self();
 	uint64_t old_state, new_state, canlock_mask, state_flags = 0;
-	dispatch_tid owner;
+	dispatch_lock_owner owner;
 
 	bool wakeup = _dispatch_mach_send_push_inline(dmsr, dou);
 	if (wakeup) {
@@ -1569,7 +1497,7 @@
 			new_state = _dmsr_state_merge_override(old_state, qos);
 			new_state |= state_flags;
 		});
-		dx_wakeup(dm, qos, DISPATCH_WAKEUP_MAKE_DIRTY);
+		dx_wakeup(dm, qos, DISPATCH_WAKEUP_FLUSH);
 		return false;
 	}
 
@@ -1580,7 +1508,7 @@
 			new_state = _dmsr_state_merge_override(old_state, qos);
 			new_state |= state_flags;
 			if (likely((old_state & canlock_mask) == 0)) {
-				new_state |= owner_self;
+				new_state |= tid_self;
 				new_state &= ~DISPATCH_MACH_STATE_DIRTY;
 				new_state &= ~DISPATCH_MACH_STATE_RECEIVED_OVERRIDE;
 				new_state &= ~DISPATCH_MACH_STATE_PENDING_BARRIER;
@@ -1593,7 +1521,7 @@
 				os_atomic_rmw_loop_give_up(return false);
 			}
 			if (likely((old_state & canlock_mask) == 0)) {
-				new_state |= owner_self;
+				new_state |= tid_self;
 				new_state &= ~DISPATCH_MACH_STATE_DIRTY;
 				new_state &= ~DISPATCH_MACH_STATE_RECEIVED_OVERRIDE;
 				new_state &= ~DISPATCH_MACH_STATE_PENDING_BARRIER;
@@ -1611,7 +1539,7 @@
 	}
 
 	if (old_state & DISPATCH_MACH_STATE_PENDING_BARRIER) {
-		dx_wakeup(dm, qos, 0);
+		dx_wakeup(dm, qos, DISPATCH_WAKEUP_OVERRIDING);
 		return false;
 	}
 
@@ -1647,7 +1575,7 @@
 	DISPATCH_ASSERT_ON_MANAGER_QUEUE();
 	dm->dm_send_refs->du_ident = send;
 	dispatch_assume(_dispatch_unote_register(dm->dm_send_refs,
-			DISPATCH_WLH_ANON, 0));
+			DISPATCH_WLH_MANAGER, 0));
 }
 
 void
@@ -1661,7 +1589,7 @@
 
 	if (data & dmsr->du_fflags) {
 		_dispatch_mach_send_invoke(dm, DISPATCH_INVOKE_MANAGER_DRAIN,
-				DM_SEND_INVOKE_MAKE_DIRTY);
+				DM_SEND_INVOKE_FLUSH);
 	}
 }
 
@@ -1672,7 +1600,7 @@
 {
 	mach_error_t error;
 	dispatch_mach_reason_t reason = _dispatch_mach_msg_get_reason(dmsg, &error);
-	if (reason == DISPATCH_MACH_MESSAGE_RECEIVED || !dm->dm_is_xpc ||
+	if (!dm->dm_is_xpc ||
 			!_dispatch_mach_xpc_hooks->dmxh_direct_message_handler(
 			dm->dm_recv_refs->dmrr_handler_ctxt, reason, dmsg, error)) {
 		// Not XPC client or not a message that XPC can handle inline - push
@@ -1721,25 +1649,15 @@
 }
 
 DISPATCH_ALWAYS_INLINE
-static inline dispatch_qos_t
-_dispatch_mach_priority_propagate(mach_msg_option_t options,
-		pthread_priority_t *msg_pp)
+static inline pthread_priority_t
+_dispatch_mach_priority_propagate(mach_msg_option_t options)
 {
 #if DISPATCH_USE_NOIMPORTANCE_QOS
-	if (options & MACH_SEND_NOIMPORTANCE) {
-		*msg_pp = 0;
-		return 0;
-	}
+	if (options & MACH_SEND_NOIMPORTANCE) return 0;
+#else
+	(void)options;
 #endif
-	unsigned int flags = DISPATCH_PRIORITY_PROPAGATE_CURRENT;
-	if ((options & DISPATCH_MACH_WAIT_FOR_REPLY) &&
-			(options & DISPATCH_MACH_OWNED_REPLY_PORT) &&
-			_dispatch_use_mach_special_reply_port()) {
-		flags |= DISPATCH_PRIORITY_PROPAGATE_FOR_SYNC_IPC;
-	}
-	*msg_pp = _dispatch_priority_compute_propagated(0, flags);
-	// TODO: remove QoS contribution of sync IPC messages to send queue
-	return _dispatch_qos_from_pp(*msg_pp);
+	return _dispatch_priority_propagate();
 }
 
 DISPATCH_NOINLINE
@@ -1752,15 +1670,14 @@
 		DISPATCH_CLIENT_CRASH(dmsg->do_next, "Message already enqueued");
 	}
 	dispatch_retain(dmsg);
-	pthread_priority_t msg_pp;
-	dispatch_qos_t qos = _dispatch_mach_priority_propagate(options, &msg_pp);
+	pthread_priority_t priority = _dispatch_mach_priority_propagate(options);
 	options |= _dispatch_mach_send_options();
 	dmsg->dmsg_options = options;
 	mach_msg_header_t *msg = _dispatch_mach_msg_get_msg(dmsg);
 	dmsg->dmsg_reply = _dispatch_mach_msg_get_reply_port(dmsg);
 	bool is_reply = (MACH_MSGH_BITS_REMOTE(msg->msgh_bits) ==
 			MACH_MSG_TYPE_MOVE_SEND_ONCE);
-	dmsg->dmsg_priority = msg_pp;
+	dmsg->dmsg_priority = priority;
 	dmsg->dmsg_voucher = _voucher_copy();
 	_dispatch_voucher_debug("mach-msg[%p] set", dmsg->dmsg_voucher, dmsg);
 
@@ -1783,7 +1700,7 @@
 		dispatch_object_t dou = { ._dmsg = dmsg };
 		if (dc_wait) dou._dc = dc_wait;
 		returning_send_result = _dispatch_mach_send_push_and_trydrain(dm, dou,
-				qos, send_flags);
+				_dispatch_qos_from_pp(priority), send_flags);
 	}
 	if (returning_send_result) {
 		_dispatch_voucher_debug("mach-msg[%p] clear", dmsg->dmsg_voucher, dmsg);
@@ -1834,7 +1751,6 @@
 		dispatch_mach_msg_t dmsg, mach_msg_option_t options,
 		bool *returned_send_result)
 {
-	mach_port_t send = MACH_PORT_NULL;
 	mach_port_t reply_port = _dispatch_mach_msg_get_reply_port(dmsg);
 	if (!reply_port) {
 		// use per-thread mach reply port <rdar://24597802>
@@ -1845,7 +1761,6 @@
 		hdr->msgh_local_port = reply_port;
 		options |= DISPATCH_MACH_OWNED_REPLY_PORT;
 	}
-	options |= DISPATCH_MACH_WAIT_FOR_REPLY;
 
 	dispatch_mach_reply_refs_t dmr;
 #if DISPATCH_DEBUG
@@ -1866,13 +1781,8 @@
 	*returned_send_result = _dispatch_mach_send_msg(dm, dmsg, &dc_wait,options);
 	if (options & DISPATCH_MACH_OWNED_REPLY_PORT) {
 		_dispatch_clear_thread_reply_port(reply_port);
-		if (_dispatch_use_mach_special_reply_port()) {
-			// link special reply port to send right for remote receive right
-			// TODO: extend to pre-connect phase <rdar://problem/31823384>
-			send = dm->dm_send_refs->dmsr_send;
-		}
 	}
-	dmsg = _dispatch_mach_msg_reply_recv(dm, dmr, reply_port, send);
+	dmsg = _dispatch_mach_msg_reply_recv(dm, dmr, reply_port);
 #if DISPATCH_DEBUG
 	free(dmr);
 #endif
@@ -1888,6 +1798,7 @@
 	dispatch_mach_msg_t reply;
 	dispatch_assert_zero(options & DISPATCH_MACH_OPTIONS_MASK);
 	options &= ~DISPATCH_MACH_OPTIONS_MASK;
+	options |= DISPATCH_MACH_WAIT_FOR_REPLY;
 	reply = _dispatch_mach_send_and_wait_for_reply(dm, dmsg, options,
 			&returned_send_result);
 	dispatch_assert(!returned_send_result);
@@ -1908,6 +1819,7 @@
 	dispatch_mach_msg_t reply;
 	dispatch_assert_zero(options & DISPATCH_MACH_OPTIONS_MASK);
 	options &= ~DISPATCH_MACH_OPTIONS_MASK;
+	options |= DISPATCH_MACH_WAIT_FOR_REPLY;
 	options |= DISPATCH_MACH_RETURN_IMMEDIATE_SEND_RESULT;
 	reply = _dispatch_mach_send_and_wait_for_reply(dm, dmsg, options,
 			&returned_send_result);
@@ -1965,8 +1877,8 @@
 	}
 	if (MACH_PORT_VALID(dmsr->dmsr_send)) {
 		_dispatch_mach_msg_disconnected(dm, MACH_PORT_NULL, dmsr->dmsr_send);
-		dmsr->dmsr_send = MACH_PORT_NULL;
 	}
+	dmsr->dmsr_send = MACH_PORT_NULL;
 	if (dmsr->dmsr_checkin) {
 		_dispatch_mach_msg_not_sent(dm, dmsr->dmsr_checkin);
 		dmsr->dmsr_checkin = NULL;
@@ -1977,14 +1889,11 @@
 		TAILQ_REMOVE(&dm->dm_send_refs->dmsr_replies, dmr, dmr_list);
 		_TAILQ_MARK_NOT_ENQUEUED(dmr, dmr_list);
 		if (_dispatch_unote_registered(dmr)) {
-			if (!_dispatch_mach_reply_kevent_unregister(dm, dmr,
-					DU_UNREGISTER_DISCONNECTED)) {
-				TAILQ_INSERT_HEAD(&dm->dm_send_refs->dmsr_replies, dmr,
-					dmr_list);
-			}
+			_dispatch_mach_reply_kevent_unregister(dm, dmr,
+					DU_UNREGISTER_DISCONNECTED);
 		} else {
 			_dispatch_mach_reply_waiter_unregister(dm, dmr,
-				DU_UNREGISTER_DISCONNECTED);
+					DU_UNREGISTER_DISCONNECTED);
 		}
 	}
 	disconnected = TAILQ_EMPTY(&dm->dm_send_refs->dmsr_replies);
@@ -2008,18 +1917,8 @@
 	dispatch_mach_recv_refs_t dmrr = dm->dm_recv_refs;
 	mach_port_t local_port = (mach_port_t)dmrr->du_ident;
 	if (local_port) {
-		// handle the deferred delete case properly, similar to what
-		// _dispatch_source_invoke2() does
-		dispatch_queue_flags_t dqf = _dispatch_queue_atomic_flags(dm->_as_dq);
-		if ((dqf & DSF_DEFERRED_DELETE) && !(dqf & DSF_ARMED)) {
-			_dispatch_source_refs_unregister(dm->_as_ds,
-					DU_UNREGISTER_IMMEDIATE_DELETE);
-			dqf = _dispatch_queue_atomic_flags(dm->_as_dq);
-		} else if (!(dqf & DSF_DEFERRED_DELETE) && !(dqf & DSF_DELETED)) {
-			_dispatch_source_refs_unregister(dm->_as_ds, 0);
-			dqf = _dispatch_queue_atomic_flags(dm->_as_dq);
-		}
-		if ((dqf & DSF_STATE_MASK) == DSF_DELETED) {
+		_dispatch_source_refs_unregister(dm->_as_ds, 0);
+		if ((dm->dq_atomic_flags & DSF_STATE_MASK) == DSF_DELETED) {
 			_dispatch_mach_msg_disconnected(dm, local_port, MACH_PORT_NULL);
 			dmrr->du_ident = 0;
 		} else {
@@ -2029,10 +1928,6 @@
 		_dispatch_queue_atomic_flags_set_and_clear(dm->_as_dq, DSF_DELETED,
 				DSF_ARMED | DSF_DEFERRED_DELETE);
 	}
-
-	if (dm->dm_send_refs->dmsr_disconnect_cnt) {
-		uninstalled = false; // <rdar://problem/31233110>
-	}
 	if (uninstalled) dm->dm_uninstalled = uninstalled;
 }
 
@@ -2128,21 +2023,8 @@
 			if (slowpath(!dm->dm_connect_handler_called)) {
 				_dispatch_mach_connect_invoke(dm);
 			}
-			if (reason == DISPATCH_MACH_MESSAGE_RECEIVED &&
-					(_dispatch_queue_atomic_flags(dm->_as_dq) & DSF_CANCELED)) {
-				// <rdar://problem/32184699> Do not deliver message received
-				// after cancellation: _dispatch_mach_merge_msg can be preempted
-				// for a long time between clearing DSF_ARMED but before
-				// enqueuing the message, allowing for cancellation to complete,
-				// and then the message event to be delivered.
-				//
-				// This makes XPC unhappy because some of these messages are
-				// port-destroyed notifications that can cause it to try to
-				// reconnect on a channel that is almost fully canceled
-			} else {
-				_dispatch_client_callout4(dmrr->dmrr_handler_ctxt, reason, dmsg,
-						err, dmrr->dmrr_handler_func);
-			}
+			_dispatch_client_callout4(dmrr->dmrr_handler_ctxt, reason, dmsg,
+					err, dmrr->dmrr_handler_func);
 		}
 		_dispatch_perfmon_workitem_inc();
 	});
@@ -2292,37 +2174,22 @@
 }
 
 static void
-_dispatch_mach_install(dispatch_mach_t dm, dispatch_wlh_t wlh,
-		dispatch_priority_t pri)
+_dispatch_mach_install(dispatch_mach_t dm, dispatch_priority_t pri,
+		dispatch_wlh_t wlh)
 {
 	dispatch_mach_recv_refs_t dmrr = dm->dm_recv_refs;
 	uint32_t disconnect_cnt;
 
+	if (!dm->dq_wlh && wlh) {
+		_dispatch_queue_class_record_wlh_hierarchy(dm, wlh);
+	}
 	if (dmrr->du_ident) {
-		_dispatch_source_refs_register(dm->_as_ds, wlh, pri);
-		dispatch_assert(dmrr->du_is_direct);
+		_dispatch_source_refs_register(dm->_as_ds, pri);
 	}
-
-	if (dm->dm_is_xpc) {
-		bool monitor_sigterm;
-		if (_dispatch_mach_xpc_hooks->version < 3) {
-			monitor_sigterm = true;
-		} else if (!_dispatch_mach_xpc_hooks->dmxh_enable_sigterm_notification){
-			monitor_sigterm = true;
-		} else {
-			monitor_sigterm =
-					_dispatch_mach_xpc_hooks->dmxh_enable_sigterm_notification(
-					dm->dm_recv_refs->dmrr_handler_ctxt);
-		}
-		if (monitor_sigterm) {
-			dispatch_xpc_term_refs_t _dxtr =
-					dux_create(&_dispatch_xpc_type_sigterm, SIGTERM, 0)._dxtr;
-			_dxtr->du_owner_wref = _dispatch_ptr2wref(dm);
-			dm->dm_xpc_term_refs = _dxtr;
-			_dispatch_unote_register(dm->dm_xpc_term_refs, wlh, pri);
-		}
+	if (dm->dm_xpc_term_refs) {
+		_dispatch_unote_register(dm->dm_xpc_term_refs, dm->dq_wlh, pri);
 	}
-	if (!dm->dq_priority) {
+	if (dmrr->du_is_direct && !dm->dq_priority) {
 		// _dispatch_mach_reply_kevent_register assumes this has been done
 		// which is unlike regular sources or queues, the DEFAULTQUEUE flag
 		// is used so that the priority of the channel doesn't act as
@@ -2337,17 +2204,21 @@
 }
 
 void
-_dispatch_mach_finalize_activation(dispatch_mach_t dm, bool *allow_resume)
+_dispatch_mach_finalize_activation(dispatch_mach_t dm)
 {
-	dispatch_priority_t pri;
-	dispatch_wlh_t wlh;
+	dispatch_mach_recv_refs_t dmrr = dm->dm_recv_refs;
 
 	// call "super"
-	_dispatch_queue_finalize_activation(dm->_as_dq, allow_resume);
+	_dispatch_queue_finalize_activation(dm->_as_dq);
 
-	if (!dm->ds_is_installed) {
-		pri = _dispatch_queue_compute_priority_and_wlh(dm->_as_dq, &wlh);
-		if (pri) _dispatch_mach_install(dm, wlh, pri);
+	if (dmrr->du_is_direct && !dm->ds_is_installed) {
+		dispatch_source_t ds = dm->_as_ds;
+		dispatch_priority_t pri = _dispatch_source_compute_kevent_priority(ds);
+		if (pri) {
+			dispatch_wlh_t wlh = dm->dq_wlh;
+			if (!wlh) wlh = _dispatch_queue_class_compute_wlh(dm);
+			_dispatch_mach_install(dm, pri, wlh);
+		}
 	}
 }
 
@@ -2379,24 +2250,8 @@
 	dispatch_mach_t dm = dou._dm;
 	dispatch_queue_wakeup_target_t retq = NULL;
 	dispatch_queue_t dq = _dispatch_queue_get_current();
-	dispatch_mach_send_refs_t dmsr = dm->dm_send_refs;
-	dispatch_mach_recv_refs_t dmrr = dm->dm_recv_refs;
-	dispatch_queue_flags_t dqf = 0;
 
-	if (!(flags & DISPATCH_INVOKE_MANAGER_DRAIN) && dmrr &&
-			_dispatch_unote_wlh_changed(dmrr, _dispatch_get_wlh())) {
-		dqf = _dispatch_queue_atomic_flags_set_orig(dm->_as_dq,
-				DSF_WLH_CHANGED);
-		if (!(dqf & DSF_WLH_CHANGED)) {
-			if (dm->dm_is_xpc) {
-				_dispatch_bug_deprecated("Changing target queue "
-						"hierarchy after xpc connection was activated");
-			} else {
-				_dispatch_bug_deprecated("Changing target queue "
-						"hierarchy after mach channel was activated");
-			}
-		}
-	}
+	flags |= DISPATCH_INVOKE_DISALLOW_SYNC_WAITERS;
 
 	// This function performs all mach channel actions. Each action is
 	// responsible for verifying that it takes place on the appropriate queue.
@@ -2406,12 +2261,20 @@
 
 	// The order of tests here in invoke and in wakeup should be consistent.
 
+	dispatch_mach_send_refs_t dmsr = dm->dm_send_refs;
+	dispatch_mach_recv_refs_t dmrr = dm->dm_recv_refs;
+	dispatch_queue_t dkq = &_dispatch_mgr_q;
+
+	if (dmrr->du_is_direct) {
+		dkq = dm->do_targetq;
+	}
+
 	if (unlikely(!dm->ds_is_installed)) {
 		// The channel needs to be installed on the kevent queue.
-		if (unlikely(flags & DISPATCH_INVOKE_MANAGER_DRAIN)) {
-			return dm->do_targetq;
+		if (dq != dkq) {
+			return dkq;
 		}
-		_dispatch_mach_install(dm, _dispatch_get_wlh(),_dispatch_get_basepri());
+		_dispatch_mach_install(dm, _dispatch_get_basepri(),_dispatch_get_wlh());
 		_dispatch_perfmon_workitem_inc();
 	}
 
@@ -2424,12 +2287,13 @@
 		}
 	}
 
-	if (!retq && _dispatch_unote_registered(dmrr)) {
+	dispatch_queue_flags_t dqf = 0;
+	if (!retq && dmrr->du_is_direct) {
 		if (_dispatch_mach_tryarm(dm, &dqf)) {
 			_dispatch_unote_resume(dmrr);
 			if (dq == dm->do_targetq && !dq->do_targetq && !dmsr->dmsr_tail &&
 					(dq->dq_priority & DISPATCH_PRIORITY_FLAG_OVERCOMMIT) &&
-					_dispatch_wlh_should_poll_unote(dmrr)) {
+					dmrr->du_wlh != DISPATCH_WLH_GLOBAL) {
 				// try to redrive the drain from under the lock for channels
 				// targeting an overcommit root queue to avoid parking
 				// when the next message has already fired
@@ -2443,7 +2307,7 @@
 
 	if (dmsr->dmsr_tail) {
 		bool requires_mgr = dm->dm_needs_mgr || (dmsr->dmsr_disconnect_cnt &&
-				_dispatch_unote_registered(dmsr));
+				(_dispatch_unote_registered(dmsr) || !dmrr->du_is_direct));
 		if (!os_atomic_load2o(dmsr, dmsr_notification_armed, relaxed) ||
 				(dqf & DSF_CANCELED) || dmsr->dmsr_disconnect_cnt) {
 			// The channel has pending messages to send.
@@ -2493,8 +2357,7 @@
 _dispatch_mach_invoke(dispatch_mach_t dm,
 		dispatch_invoke_context_t dic, dispatch_invoke_flags_t flags)
 {
-	_dispatch_queue_class_invoke(dm, dic, flags,
-			DISPATCH_INVOKE_DISALLOW_SYNC_WAITERS, _dispatch_mach_invoke2);
+	_dispatch_queue_class_invoke(dm, dic, flags, _dispatch_mach_invoke2);
 }
 
 void
@@ -2505,12 +2368,18 @@
 	// The order of tests here in probe and in invoke should be consistent.
 
 	dispatch_mach_send_refs_t dmsr = dm->dm_send_refs;
+	dispatch_mach_recv_refs_t dmrr = dm->dm_recv_refs;
+	dispatch_queue_wakeup_target_t dkq = DISPATCH_QUEUE_WAKEUP_MGR;
 	dispatch_queue_wakeup_target_t tq = DISPATCH_QUEUE_WAKEUP_NONE;
 	dispatch_queue_flags_t dqf = _dispatch_queue_atomic_flags(dm->_as_dq);
 
+	if (dmrr->du_is_direct) {
+		dkq = DISPATCH_QUEUE_WAKEUP_TARGET;
+	}
+
 	if (!dm->ds_is_installed) {
 		// The channel needs to be installed on the kevent queue.
-		tq = DISPATCH_QUEUE_WAKEUP_TARGET;
+		tq = dkq;
 		goto done;
 	}
 
@@ -2527,7 +2396,7 @@
 
 	if (dmsr->dmsr_tail) {
 		bool requires_mgr = dm->dm_needs_mgr || (dmsr->dmsr_disconnect_cnt &&
-				_dispatch_unote_registered(dmsr));
+				(_dispatch_unote_registered(dmsr) || !dmrr->du_is_direct));
 		if (!os_atomic_load2o(dmsr, dmsr_notification_armed, relaxed) ||
 				(dqf & DSF_CANCELED) || dmsr->dmsr_disconnect_cnt) {
 			if (unlikely(requires_mgr)) {
@@ -2552,12 +2421,13 @@
 	}
 
 done:
-	if ((tq == DISPATCH_QUEUE_WAKEUP_TARGET) &&
-			dm->do_targetq == &_dispatch_mgr_q) {
-		tq = DISPATCH_QUEUE_WAKEUP_MGR;
+	if (tq) {
+		return _dispatch_queue_class_wakeup(dm->_as_dq, qos, flags, tq);
+	} else if (qos) {
+		return _dispatch_queue_class_override_drainer(dm->_as_dq, qos, flags);
+	} else if (flags & DISPATCH_WAKEUP_CONSUME) {
+		return _dispatch_release_tailcall(dm);
 	}
-
-	return _dispatch_queue_class_wakeup(dm->_as_dq, qos, flags, tq);
 }
 
 static void
@@ -2592,7 +2462,7 @@
 		_dispatch_barrier_async_detached_f(dm->_as_dq, dm,
 				_dispatch_mach_sigterm_invoke);
 	} else {
-		dx_wakeup(dm, _dispatch_qos_from_pp(pp), DISPATCH_WAKEUP_MAKE_DIRTY);
+		dx_wakeup(dm, _dispatch_qos_from_pp(pp), DISPATCH_WAKEUP_FLUSH);
 	}
 }
 
@@ -2607,15 +2477,9 @@
 			slowpath(destructor && !msg)) {
 		DISPATCH_CLIENT_CRASH(size, "Empty message");
 	}
-
-	dispatch_mach_msg_t dmsg;
-	size_t msg_size = sizeof(struct dispatch_mach_msg_s);
-	if (!destructor && os_add_overflow(msg_size,
-			  (size - sizeof(dmsg->dmsg_msg)), &msg_size)) {
-		DISPATCH_CLIENT_CRASH(size, "Message size too large");
-	}
-
-	dmsg = _dispatch_object_alloc(DISPATCH_VTABLE(mach_msg), msg_size);
+	dispatch_mach_msg_t dmsg = _dispatch_alloc(DISPATCH_VTABLE(mach_msg),
+			sizeof(struct dispatch_mach_msg_s) +
+			(destructor ? 0 : size - sizeof(dmsg->dmsg_msg)));
 	if (destructor) {
 		dmsg->dmsg_msg = msg;
 	} else if (msg) {
@@ -2632,8 +2496,7 @@
 }
 
 void
-_dispatch_mach_msg_dispose(dispatch_mach_msg_t dmsg,
-		DISPATCH_UNUSED bool *allow_free)
+_dispatch_mach_msg_dispose(dispatch_mach_msg_t dmsg)
 {
 	if (dmsg->dmsg_voucher) {
 		_voucher_release(dmsg->dmsg_voucher);
@@ -2676,7 +2539,8 @@
 	size_t offset = 0;
 	offset += dsnprintf(&buf[offset], bufsiz - offset, "%s[%p] = { ",
 			dx_kind(dmsg), dmsg);
-	offset += _dispatch_object_debug_attr(dmsg, buf + offset, bufsiz - offset);
+	offset += dsnprintf(&buf[offset], bufsiz - offset, "xrefcnt = 0x%x, "
+			"refcnt = 0x%x, ", dmsg->do_xref_cnt + 1, dmsg->do_ref_cnt + 1);
 	offset += dsnprintf(&buf[offset], bufsiz - offset, "opts/err = 0x%x, "
 			"msgh[%p] = { ", dmsg->dmsg_options, dmsg->dmsg_buf);
 	mach_msg_header_t *hdr = _dispatch_mach_msg_get_msg(dmsg);
diff --git a/src/mach_internal.h b/src/mach_internal.h
index 8c8edd8..8600a38 100644
--- a/src/mach_internal.h
+++ b/src/mach_internal.h
@@ -99,8 +99,8 @@
 
 void _dispatch_mach_msg_async_reply_invoke(dispatch_continuation_t dc,
 		dispatch_invoke_context_t dic, dispatch_invoke_flags_t flags);
-void _dispatch_mach_dispose(dispatch_mach_t dm, bool *allow_free);
-void _dispatch_mach_finalize_activation(dispatch_mach_t dm, bool *allow_resume);
+void _dispatch_mach_dispose(dispatch_mach_t dm);
+void _dispatch_mach_finalize_activation(dispatch_mach_t dm);
 void _dispatch_mach_invoke(dispatch_mach_t dm, dispatch_invoke_context_t dic,
 		dispatch_invoke_flags_t flags);
 void _dispatch_mach_wakeup(dispatch_mach_t dm, dispatch_qos_t qos,
@@ -116,7 +116,7 @@
 void _dispatch_xpc_sigterm_merge(dispatch_unote_t du, uint32_t flags,
 		uintptr_t data, uintptr_t status, pthread_priority_t pp);
 
-void _dispatch_mach_msg_dispose(dispatch_mach_msg_t dmsg, bool *allow_free);
+void _dispatch_mach_msg_dispose(dispatch_mach_msg_t dmsg);
 void _dispatch_mach_msg_invoke(dispatch_mach_msg_t dmsg,
 		dispatch_invoke_context_t dic, dispatch_invoke_flags_t flags);
 size_t _dispatch_mach_msg_debug(dispatch_mach_msg_t dmsg, char* buf,
diff --git a/src/object.c b/src/object.c
index 43f580b..1ca41bc 100644
--- a/src/object.c
+++ b/src/object.c
@@ -37,28 +37,14 @@
 _os_object_t
 _os_object_retain_internal(_os_object_t obj)
 {
-	return _os_object_retain_internal_n_inline(obj, 1);
-}
-
-DISPATCH_NOINLINE
-_os_object_t
-_os_object_retain_internal_n(_os_object_t obj, uint16_t n)
-{
-	return _os_object_retain_internal_n_inline(obj, n);
+	return _os_object_retain_internal_inline(obj);
 }
 
 DISPATCH_NOINLINE
 void
 _os_object_release_internal(_os_object_t obj)
 {
-	return _os_object_release_internal_n_inline(obj, 1);
-}
-
-DISPATCH_NOINLINE
-void
-_os_object_release_internal_n(_os_object_t obj, uint16_t n)
-{
-	return _os_object_release_internal_n_inline(obj, n);
+	return _os_object_release_internal_inline(obj);
 }
 
 DISPATCH_NOINLINE
@@ -138,7 +124,7 @@
 #pragma mark dispatch_object_t
 
 void *
-_dispatch_object_alloc(const void *vtable, size_t size)
+_dispatch_alloc(const void *vtable, size_t size)
 {
 #if OS_OBJECT_HAVE_OBJC1
 	const struct dispatch_object_vtable_s *_vtable = vtable;
@@ -152,27 +138,6 @@
 }
 
 void
-_dispatch_object_finalize(dispatch_object_t dou)
-{
-#if USE_OBJC
-	objc_destructInstance((id)dou._do);
-#else
-	(void)dou;
-#endif
-}
-
-void
-_dispatch_object_dealloc(dispatch_object_t dou)
-{
-	// so that ddt doesn't pick up bad objects when malloc reuses this memory
-	dou._os_obj->os_obj_isa = NULL;
-#if OS_OBJECT_HAVE_OBJC1
-	dou._do->do_vtable = NULL;
-#endif
-	free(dou._os_obj);
-}
-
-void
 dispatch_retain(dispatch_object_t dou)
 {
 	DISPATCH_OBJECT_TFB(_dispatch_objc_retain, dou);
@@ -186,6 +151,24 @@
 	_os_object_release(dou._os_obj);
 }
 
+static void
+_dispatch_dealloc(dispatch_object_t dou)
+{
+	dispatch_queue_t tq = dou._do->do_targetq;
+	dispatch_function_t func = dou._do->do_finalizer;
+	void *ctxt = dou._do->do_ctxt;
+#if OS_OBJECT_HAVE_OBJC1
+	// so that ddt doesn't pick up bad objects when malloc reuses this memory
+	dou._do->do_vtable = NULL;
+#endif
+	_os_object_dealloc(dou._os_obj);
+
+	if (func && ctxt) {
+		dispatch_async_f(tq, ctxt, func);
+	}
+	_dispatch_release_tailcall(tq);
+}
+
 #if !USE_OBJC
 void
 _dispatch_xref_dispose(dispatch_object_t dou)
@@ -210,26 +193,11 @@
 void
 _dispatch_dispose(dispatch_object_t dou)
 {
-	dispatch_queue_t tq = dou._do->do_targetq;
-	dispatch_function_t func = dou._do->do_finalizer;
-	void *ctxt = dou._do->do_ctxt;
-	bool allow_free = true;
-
 	if (slowpath(dou._do->do_next != DISPATCH_OBJECT_LISTLESS)) {
 		DISPATCH_INTERNAL_CRASH(dou._do->do_next, "Release while enqueued");
 	}
-
-	dx_dispose(dou._do, &allow_free);
-
-	// Past this point, the only thing left of the object is its memory
-	if (likely(allow_free)) {
-		_dispatch_object_finalize(dou);
-		_dispatch_object_dealloc(dou);
-	}
-	if (func && ctxt) {
-		dispatch_async_f(tq, ctxt, func);
-	}
-	if (tq) _dispatch_release_tailcall(tq);
+	dx_dispose(dou._do);
+	return _dispatch_dealloc(dou);
 }
 
 void *
@@ -302,9 +270,7 @@
 dispatch_resume(dispatch_object_t dou)
 {
 	DISPATCH_OBJECT_TFB(_dispatch_objc_resume, dou);
-	// the do_suspend below is not a typo. Having a do_resume but no do_suspend
-	// allows for objects to support activate, but have no-ops suspend/resume
-	if (dx_vtable(dou._do)->do_suspend) {
+	if (dx_vtable(dou._do)->do_resume) {
 		dx_vtable(dou._do)->do_resume(dou._do, false);
 	}
 }
@@ -312,6 +278,6 @@
 size_t
 _dispatch_object_debug_attr(dispatch_object_t dou, char* buf, size_t bufsiz)
 {
-	return dsnprintf(buf, bufsiz, "xref = %d, ref = %d, ",
+	return dsnprintf(buf, bufsiz, "xrefcnt = 0x%x, refcnt = 0x%x, ",
 			dou._do->do_xref_cnt + 1, dou._do->do_ref_cnt + 1);
 }
diff --git a/src/object.m b/src/object.m
index cc97cc3..59cbc9d 100644
--- a/src/object.m
+++ b/src/object.m
@@ -29,21 +29,10 @@
 #error Objective C GC isn't supported anymore
 #endif
 
-#if __has_include(<objc/objc-internal.h>)
 #include <objc/objc-internal.h>
-#else
-extern id _Nullable objc_retain(id _Nullable obj) __asm__("_objc_retain");
-extern void objc_release(id _Nullable obj) __asm__("_objc_release");
-extern void _objc_init(void);
-extern void _objc_atfork_prepare(void);
-extern void _objc_atfork_parent(void);
-extern void _objc_atfork_child(void);
-#endif // __has_include(<objc/objc-internal.h>)
 #include <objc/objc-exception.h>
 #include <Foundation/NSString.h>
 
-// NOTE: this file must not contain any atomic operations
-
 #pragma mark -
 #pragma mark _os_object_t
 
@@ -297,11 +286,6 @@
 	return [nsstring stringWithFormat:format, class_getName([self class]), buf];
 }
 
-- (void)dealloc DISPATCH_NORETURN {
-	DISPATCH_INTERNAL_CRASH(0, "Calling dealloc on a dispatch object");
-	[super dealloc]; // make clang happy
-}
-
 @end
 
 @implementation DISPATCH_CLASS(queue)
@@ -429,20 +413,20 @@
 
 #if DISPATCH_COCOA_COMPAT
 
-void
-_dispatch_last_resort_autorelease_pool_push(dispatch_invoke_context_t dic)
+void *
+_dispatch_last_resort_autorelease_pool_push(void)
 {
 	if (!slowpath(_os_object_debug_missing_pools)) {
-		dic->dic_autorelease_pool = _dispatch_autorelease_pool_push();
+		return _dispatch_autorelease_pool_push();
 	}
+	return NULL;
 }
 
 void
-_dispatch_last_resort_autorelease_pool_pop(dispatch_invoke_context_t dic)
+_dispatch_last_resort_autorelease_pool_pop(void *context)
 {
 	if (!slowpath(_os_object_debug_missing_pools)) {
-		_dispatch_autorelease_pool_pop(dic->dic_autorelease_pool);
-		dic->dic_autorelease_pool = NULL;
+		return _dispatch_autorelease_pool_pop(context);
 	}
 }
 
diff --git a/src/object_internal.h b/src/object_internal.h
index 0060f27..61caebf 100644
--- a/src/object_internal.h
+++ b/src/object_internal.h
@@ -188,14 +188,14 @@
 	DISPATCH_INVOKABLE_VTABLE_HEADER(x); \
 	void (*const do_wakeup)(struct x##_s *, \
 			dispatch_qos_t, dispatch_wakeup_flags_t); \
-	void (*const do_dispose)(struct x##_s *, bool *allow_free)
+	void (*const do_dispose)(struct x##_s *)
 
 #define DISPATCH_OBJECT_VTABLE_HEADER(x) \
 	DISPATCH_QUEUEABLE_VTABLE_HEADER(x); \
 	void (*const do_set_targetq)(struct x##_s *, dispatch_queue_t); \
 	void (*const do_suspend)(struct x##_s *); \
 	void (*const do_resume)(struct x##_s *, bool activate); \
-	void (*const do_finalize_activation)(struct x##_s *, bool *allow_resume); \
+	void (*const do_finalize_activation)(struct x##_s *); \
 	size_t (*const do_debug)(struct x##_s *, char *, size_t)
 
 #define dx_vtable(x) (&(x)->do_vtable->_os_obj_vtable)
@@ -205,7 +205,7 @@
 #define dx_hastypeflag(x, f) (dx_vtable(x)->do_type & _DISPATCH_##f##_TYPEFLAG)
 #define dx_kind(x) dx_vtable(x)->do_kind
 #define dx_debug(x, y, z) dx_vtable(x)->do_debug((x), (y), (z))
-#define dx_dispose(x, y) dx_vtable(x)->do_dispose(x, y)
+#define dx_dispose(x) dx_vtable(x)->do_dispose(x)
 #define dx_invoke(x, y, z) dx_vtable(x)->do_invoke(x, y, z)
 #define dx_push(x, y, z) dx_vtable(x)->do_push(x, y, z)
 #define dx_wakeup(x, y, z) dx_vtable(x)->do_wakeup(x, y, z)
@@ -230,29 +230,32 @@
 // we sign extend the 64-bit version so that a better instruction encoding is
 // generated on Intel
 #define DISPATCH_OBJECT_LISTLESS ((void *)0xffffffff89abcdef)
+#define DISPATCH_OBJECT_WLH_REQ  ((void *)0xffffffff7009cdef)
 #else
 #define DISPATCH_OBJECT_LISTLESS ((void *)0x89abcdef)
+#define DISPATCH_OBJECT_WLH_REQ  ((void *)0x7009cdef)
 #endif
 
 DISPATCH_ENUM(dispatch_wakeup_flags, uint32_t,
-	// The caller of dx_wakeup owns two internal refcounts on the object being
-	// woken up. Two are needed for WLH wakeups where two threads need
-	// the object to remain valid in a non-coordinated way
-	// - the thread doing the poke for the duration of the poke
-	// - drainers for the duration of their drain
-	DISPATCH_WAKEUP_CONSUME_2               = 0x00000001,
+	// The caller of dx_wakeup owns an internal refcount on the object being
+	// woken up
+	DISPATCH_WAKEUP_CONSUME                 = 0x00000001,
 
 	// Some change to the object needs to be published to drainers.
 	// If the drainer isn't the same thread, some scheme such as the dispatch
 	// queue DIRTY bit must be used and a release barrier likely has to be
 	// involved before dx_wakeup returns
-	DISPATCH_WAKEUP_MAKE_DIRTY              = 0x00000002,
+	DISPATCH_WAKEUP_FLUSH					= 0x00000002,
 
-	// This wakeup is made by a sync owner that still holds the drain lock
-	DISPATCH_WAKEUP_BARRIER_COMPLETE        = 0x00000004,
+	// The caller desires to apply an override on the object being woken up.
+	// When this flag is passed, the qos passed to dx_wakeup() should not be 0
+	DISPATCH_WAKEUP_OVERRIDING              = 0x00000004,
+
+	// This wakeup is caused by a handoff from a slow waiter.
+	DISPATCH_WAKEUP_WAITER_HANDOFF          = 0x00000008,
 
 	// This wakeup is caused by a dispatch_block_wait()
-	DISPATCH_WAKEUP_BLOCK_WAIT              = 0x00000008,
+	DISPATCH_WAKEUP_BLOCK_WAIT              = 0x00000010,
 );
 
 typedef struct dispatch_invoke_context_s {
@@ -260,12 +263,11 @@
 #if HAVE_PTHREAD_WORKQUEUE_NARROWING
 	uint64_t dic_next_narrow_check;
 #endif
-#if DISPATCH_COCOA_COMPAT
-	void *dic_autorelease_pool;
-#endif
 } dispatch_invoke_context_s, *dispatch_invoke_context_t;
 
 #if HAVE_PTHREAD_WORKQUEUE_NARROWING
+#define DISPATCH_NARROW_CHECK_INTERVAL \
+		_dispatch_time_nano2mach(50 * NSEC_PER_MSEC)
 #define DISPATCH_THREAD_IS_NARROWING 1
 
 #define dispatch_with_disabled_narrowing(dic, ...) ({ \
@@ -287,11 +289,12 @@
 	// This invoke is a stealer, meaning that it doesn't own the
 	// enqueue lock at drain lock time.
 	//
-	// @const DISPATCH_INVOKE_WLH
-	// This invoke is for a bottom WLH
+	// @const DISPATCH_INVOKE_OVERRIDING
+	// This invoke is draining the hierarchy on another root queue and needs
+	// to fake the identity of the original one.
 	//
 	DISPATCH_INVOKE_STEALING				= 0x00000001,
-	DISPATCH_INVOKE_WLH						= 0x00000002,
+	DISPATCH_INVOKE_OVERRIDING				= 0x00000002,
 
 	// Misc flags
 	//
@@ -358,31 +361,29 @@
 
 #define DISPATCH_CONTINUATION_TYPE(name)  \
 		(_DISPATCH_CONTINUATION_TYPE | DC_##name##_TYPE)
-	DISPATCH_DATA_TYPE					= 1 | _DISPATCH_NODE_TYPE,
-	DISPATCH_MACH_MSG_TYPE				= 2 | _DISPATCH_NODE_TYPE,
-	DISPATCH_QUEUE_ATTR_TYPE			= 3 | _DISPATCH_NODE_TYPE,
+	DISPATCH_DATA_TYPE				= 1 | _DISPATCH_NODE_TYPE,
+	DISPATCH_MACH_MSG_TYPE			= 2 | _DISPATCH_NODE_TYPE,
+	DISPATCH_QUEUE_ATTR_TYPE		= 3 | _DISPATCH_NODE_TYPE,
 
-	DISPATCH_IO_TYPE					= 0 | _DISPATCH_IO_TYPE,
-	DISPATCH_OPERATION_TYPE				= 0 | _DISPATCH_OPERATION_TYPE,
-	DISPATCH_DISK_TYPE					= 0 | _DISPATCH_DISK_TYPE,
+	DISPATCH_IO_TYPE				= 0 | _DISPATCH_IO_TYPE,
+	DISPATCH_OPERATION_TYPE			= 0 | _DISPATCH_OPERATION_TYPE,
+	DISPATCH_DISK_TYPE				= 0 | _DISPATCH_DISK_TYPE,
 
-	DISPATCH_QUEUE_LEGACY_TYPE			= 1 | _DISPATCH_QUEUE_TYPE,
-	DISPATCH_QUEUE_SERIAL_TYPE			= 2 | _DISPATCH_QUEUE_TYPE,
-	DISPATCH_QUEUE_CONCURRENT_TYPE		= 3 | _DISPATCH_QUEUE_TYPE,
-	DISPATCH_QUEUE_GLOBAL_ROOT_TYPE		= 4 | _DISPATCH_QUEUE_TYPE |
+	DISPATCH_QUEUE_LEGACY_TYPE		= 1 | _DISPATCH_QUEUE_TYPE,
+	DISPATCH_QUEUE_SERIAL_TYPE		= 2 | _DISPATCH_QUEUE_TYPE,
+	DISPATCH_QUEUE_CONCURRENT_TYPE	= 3 | _DISPATCH_QUEUE_TYPE,
+	DISPATCH_QUEUE_GLOBAL_ROOT_TYPE	= 4 | _DISPATCH_QUEUE_TYPE |
 			_DISPATCH_QUEUE_ROOT_TYPEFLAG,
-	DISPATCH_QUEUE_NETWORK_EVENT_TYPE	= 5 | _DISPATCH_QUEUE_TYPE |
+	DISPATCH_QUEUE_RUNLOOP_TYPE		= 5 | _DISPATCH_QUEUE_TYPE |
 			_DISPATCH_QUEUE_ROOT_TYPEFLAG,
-	DISPATCH_QUEUE_RUNLOOP_TYPE			= 6 | _DISPATCH_QUEUE_TYPE |
-			_DISPATCH_QUEUE_ROOT_TYPEFLAG,
-	DISPATCH_QUEUE_MGR_TYPE				= 7 | _DISPATCH_QUEUE_TYPE,
-	DISPATCH_QUEUE_SPECIFIC_TYPE		= 8 | _DISPATCH_QUEUE_TYPE,
+	DISPATCH_QUEUE_MGR_TYPE			= 6 | _DISPATCH_QUEUE_TYPE,
+	DISPATCH_QUEUE_SPECIFIC_TYPE	= 7 | _DISPATCH_QUEUE_TYPE,
 
-	DISPATCH_SEMAPHORE_TYPE				= 1 | _DISPATCH_SEMAPHORE_TYPE,
-	DISPATCH_GROUP_TYPE					= 2 | _DISPATCH_SEMAPHORE_TYPE,
+	DISPATCH_SEMAPHORE_TYPE			= 1 | _DISPATCH_SEMAPHORE_TYPE,
+	DISPATCH_GROUP_TYPE				= 2 | _DISPATCH_SEMAPHORE_TYPE,
 
-	DISPATCH_SOURCE_KEVENT_TYPE			= 1 | _DISPATCH_SOURCE_TYPE,
-	DISPATCH_MACH_CHANNEL_TYPE			= 2 | _DISPATCH_SOURCE_TYPE,
+	DISPATCH_SOURCE_KEVENT_TYPE		= 1 | _DISPATCH_SOURCE_TYPE,
+	DISPATCH_MACH_CHANNEL_TYPE		= 2 | _DISPATCH_SOURCE_TYPE,
 
 };
 
@@ -449,9 +450,9 @@
 	struct dispatch_object_s *volatile ns##_items_head; \
 	unsigned long ns##_serialnum; \
 	const char *ns##_label; \
+	dispatch_wlh_t ns##_wlh; \
 	struct dispatch_object_s *volatile ns##_items_tail; \
-	dispatch_priority_t ns##_priority; \
-	int volatile ns##_sref_cnt
+	dispatch_priority_t ns##_priority
 #else
 #define _OS_MPSC_QUEUE_FIELDS(ns, __state_field__) \
 	struct dispatch_object_s *volatile ns##_items_head; \
@@ -462,9 +463,10 @@
 	/* LP64 global queue cacheline boundary */ \
 	unsigned long ns##_serialnum; \
 	const char *ns##_label; \
+	dispatch_wlh_t ns##_wlh; \
 	struct dispatch_object_s *volatile ns##_items_tail; \
-	dispatch_priority_t ns##_priority; \
-	int volatile ns##_sref_cnt
+	dispatch_priority_t ns##_priority
+	/* LP64: 32bit hole */
 #endif
 
 OS_OBJECT_INTERNAL_CLASS_DECL(os_mpsc_queue, object,
@@ -482,9 +484,7 @@
 
 size_t _dispatch_object_debug_attr(dispatch_object_t dou, char* buf,
 		size_t bufsiz);
-void *_dispatch_object_alloc(const void *vtable, size_t size);
-void _dispatch_object_finalize(dispatch_object_t dou);
-void _dispatch_object_dealloc(dispatch_object_t dou);
+void *_dispatch_alloc(const void *vtable, size_t size);
 #if !USE_OBJC
 void _dispatch_xref_dispose(dispatch_object_t dou);
 #endif
@@ -492,22 +492,17 @@
 #if DISPATCH_COCOA_COMPAT
 #if USE_OBJC
 #include <objc/runtime.h>
-#if __has_include(<objc/objc-internal.h>)
 #include <objc/objc-internal.h>
-#else
-extern void *objc_autoreleasePoolPush(void);
-extern void objc_autoreleasePoolPop(void *context);
-#endif // __has_include(<objc/objc-internal.h>)
 #define _dispatch_autorelease_pool_push() \
-		objc_autoreleasePoolPush()
+	objc_autoreleasePoolPush()
 #define _dispatch_autorelease_pool_pop(context) \
-		objc_autoreleasePoolPop(context)
+	objc_autoreleasePoolPop(context)
 #else
 void *_dispatch_autorelease_pool_push(void);
 void _dispatch_autorelease_pool_pop(void *context);
 #endif
-void _dispatch_last_resort_autorelease_pool_push(dispatch_invoke_context_t dic);
-void _dispatch_last_resort_autorelease_pool_pop(dispatch_invoke_context_t dic);
+void *_dispatch_last_resort_autorelease_pool_push(void);
+void _dispatch_last_resort_autorelease_pool_pop(void *context);
 
 #define dispatch_invoke_with_autoreleasepool(flags, ...)  ({ \
 		void *pool = NULL; \
@@ -523,6 +518,7 @@
 	do { (void)flags; __VA_ARGS__; } while (0)
 #endif
 
+
 #if USE_OBJC
 OS_OBJECT_OBJC_CLASS_DECL(object);
 #endif
@@ -586,20 +582,20 @@
  *   a barrier to perform prior to tearing down an object when the refcount
  *   reached -1.
  */
-#define _os_atomic_refcnt_perform2o(o, f, op, n, m)   ({ \
+#define _os_atomic_refcnt_perform2o(o, f, op, m)   ({ \
 		typeof(o) _o = (o); \
 		int _ref_cnt = _o->f; \
 		if (fastpath(_ref_cnt != _OS_OBJECT_GLOBAL_REFCNT)) { \
-			_ref_cnt = os_atomic_##op##2o(_o, f, n, m); \
+			_ref_cnt = os_atomic_##op##2o(_o, f, m); \
 		} \
 		_ref_cnt; \
 	})
 
-#define _os_atomic_refcnt_add2o(o, m, n) \
-		_os_atomic_refcnt_perform2o(o, m, add, n, relaxed)
+#define _os_atomic_refcnt_inc2o(o, m) \
+		_os_atomic_refcnt_perform2o(o, m, inc, relaxed)
 
-#define _os_atomic_refcnt_sub2o(o, m, n) \
-		_os_atomic_refcnt_perform2o(o, m, sub, n, release)
+#define _os_atomic_refcnt_dec2o(o, m) \
+		_os_atomic_refcnt_perform2o(o, m, dec, release)
 
 #define _os_atomic_refcnt_dispose_barrier2o(o, m) \
 		(void)os_atomic_load2o(o, m, acquire)
@@ -622,19 +618,19 @@
  *
  */
 #define _os_object_xrefcnt_inc(o) \
-		_os_atomic_refcnt_add2o(o, os_obj_xref_cnt, 1)
+		_os_atomic_refcnt_inc2o(o, os_obj_xref_cnt)
 
 #define _os_object_xrefcnt_dec(o) \
-		_os_atomic_refcnt_sub2o(o, os_obj_xref_cnt, 1)
+		_os_atomic_refcnt_dec2o(o, os_obj_xref_cnt)
 
 #define _os_object_xrefcnt_dispose_barrier(o) \
 		_os_atomic_refcnt_dispose_barrier2o(o, os_obj_xref_cnt)
 
-#define _os_object_refcnt_add(o, n) \
-		_os_atomic_refcnt_add2o(o, os_obj_ref_cnt, n)
+#define _os_object_refcnt_inc(o) \
+		_os_atomic_refcnt_inc2o(o, os_obj_ref_cnt)
 
-#define _os_object_refcnt_sub(o, n) \
-		_os_atomic_refcnt_sub2o(o, os_obj_ref_cnt, n)
+#define _os_object_refcnt_dec(o) \
+		_os_atomic_refcnt_dec2o(o, os_obj_ref_cnt)
 
 #define _os_object_refcnt_dispose_barrier(o) \
 		_os_atomic_refcnt_dispose_barrier2o(o, os_obj_ref_cnt)
diff --git a/src/queue.c b/src/queue.c
index 435ac96..6d74b79 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -50,16 +50,12 @@
 static void _dispatch_deferred_items_cleanup(void *ctxt);
 static void _dispatch_frame_cleanup(void *ctxt);
 static void _dispatch_context_cleanup(void *ctxt);
-static void _dispatch_queue_barrier_complete(dispatch_queue_t dq,
-		dispatch_qos_t qos, dispatch_wakeup_flags_t flags);
-static void _dispatch_queue_non_barrier_complete(dispatch_queue_t dq);
+static void _dispatch_non_barrier_complete(dispatch_queue_t dq);
 static void _dispatch_queue_push_sync_waiter(dispatch_queue_t dq,
-		dispatch_sync_context_t dsc, dispatch_qos_t qos);
+		dispatch_sync_context_t dsc);
 #if HAVE_PTHREAD_WORKQUEUE_QOS
-static void _dispatch_root_queue_push_override_stealer(dispatch_queue_t orig_rq,
-		dispatch_queue_t dq, dispatch_qos_t qos);
-static inline void _dispatch_queue_class_wakeup_with_override(dispatch_queue_t,
-		uint64_t dq_state, dispatch_wakeup_flags_t flags);
+static void _dispatch_root_queue_push_queue_override(dispatch_queue_t rq,
+		dispatch_queue_class_t dqu, dispatch_qos_t qos);
 #endif
 #if HAVE_PTHREAD_WORKQUEUES
 static void _dispatch_worker_thread4(void *context);
@@ -332,6 +328,7 @@
 		.do_ctxt = &_dispatch_root_queue_contexts[ \
 				_DISPATCH_ROOT_QUEUE_IDX(n, flags)], \
 		.dq_atomic_flags = DQF_WIDTH(DISPATCH_QUEUE_WIDTH_POOL), \
+		.dq_wlh = DISPATCH_WLH_GLOBAL, \
 		.dq_priority = _dispatch_priority_make(DISPATCH_QOS_##n, 0) | flags | \
 				DISPATCH_PRIORITY_FLAG_ROOTQUEUE | \
 				((flags & DISPATCH_PRIORITY_FLAG_DEFAULTQUEUE) ? 0 : \
@@ -426,13 +423,13 @@
 DISPATCH_CACHELINE_ALIGN
 struct dispatch_queue_s _dispatch_mgr_q = {
 	DISPATCH_GLOBAL_OBJECT_HEADER(queue_mgr),
-	.dq_state = DISPATCH_QUEUE_STATE_INIT_VALUE(1) |
-			DISPATCH_QUEUE_ROLE_BASE_ANON,
+	.dq_state = DISPATCH_QUEUE_STATE_INIT_VALUE(1),
 	.do_targetq = &_dispatch_mgr_root_queue,
 	.dq_label = "com.apple.libdispatch-manager",
 	.dq_atomic_flags = DQF_WIDTH(1),
 	.dq_priority = DISPATCH_PRIORITY_FLAG_MANAGER |
 			DISPATCH_PRIORITY_SATURATED_OVERRIDE,
+	.dq_wlh = DISPATCH_WLH_GLOBAL,
 	.dq_serialnum = 2,
 };
 
@@ -497,7 +494,10 @@
 				"dispatch_assert_queue()");
 	}
 	uint64_t dq_state = os_atomic_load2o(dq, dq_state, relaxed);
-	if (likely(_dq_state_drain_locked_by_self(dq_state))) {
+	if (unlikely(_dq_state_drain_pended(dq_state))) {
+		goto fail;
+	}
+	if (likely(_dq_state_drain_owner(dq_state) == _dispatch_tid_self())) {
 		return;
 	}
 	// we can look at the width: if it is changing while we read it,
@@ -511,6 +511,7 @@
 			return;
 		}
 	}
+fail:
 	_dispatch_assert_queue_fail(dq, true);
 }
 
@@ -523,7 +524,10 @@
 				"dispatch_assert_queue_not()");
 	}
 	uint64_t dq_state = os_atomic_load2o(dq, dq_state, relaxed);
-	if (likely(!_dq_state_drain_locked_by_self(dq_state))) {
+	if (_dq_state_drain_pended(dq_state)) {
+		return;
+	}
+	if (likely(_dq_state_drain_owner(dq_state) != _dispatch_tid_self())) {
 		// we can look at the width: if it is changing while we read it,
 		// it means that a barrier is running on `dq` concurrently, which
 		// proves that we're not on `dq`. Hence reading a stale '1' is ok.
@@ -588,7 +592,7 @@
 #endif
 #if DISPATCH_USE_KEVENT_WORKQUEUE
 	bool disable_kevent_wq = false;
-#if DISPATCH_DEBUG || DISPATCH_PROFILE
+#if DISPATCH_DEBUG
 	disable_kevent_wq = slowpath(getenv("LIBDISPATCH_DISABLE_KEVENT_WQ"));
 #endif
 #endif
@@ -604,6 +608,9 @@
 #if DISPATCH_USE_MGR_THREAD
 			_dispatch_kevent_workqueue_enabled = !r;
 #endif
+#if DISPATCH_EVFILT_MACHPORT_PORTSET_FALLBACK
+			_dispatch_evfilt_machport_direct_enabled = !r;
+#endif
 			result = !r;
 		} else
 #endif // DISPATCH_USE_KEVENT_WORKQUEUE
@@ -780,6 +787,7 @@
 	dispatch_assert(sizeof(struct dispatch_root_queue_context_s) %
 			DISPATCH_CACHELINE_SIZE == 0);
 
+
 #if HAVE_PTHREAD_WORKQUEUE_QOS
 	dispatch_qos_t qos = _dispatch_qos_from_qos_class(qos_class_main());
 	dispatch_priority_t pri = _dispatch_priority_make(qos, 0);
@@ -827,7 +835,6 @@
 			dispatch_atfork_parent, dispatch_atfork_child));
 #endif
 	_dispatch_hw_config_init();
-	_dispatch_time_init();
 	_dispatch_vtable_init();
 	_os_object_init();
 	_voucher_init();
@@ -895,18 +902,13 @@
 void
 _dispatch_queue_atfork_child(void)
 {
-	dispatch_queue_t main_q = &_dispatch_main_q;
 	void *crash = (void *)0x100;
 	size_t i;
 
-	if (_dispatch_queue_is_thread_bound(main_q)) {
-		_dispatch_queue_set_bound_thread(main_q);
-	}
-
 	if (!_dispatch_is_multithreaded_inline()) return;
 
-	main_q->dq_items_head = crash;
-	main_q->dq_items_tail = crash;
+	_dispatch_main_q.dq_items_head = crash;
+	_dispatch_main_q.dq_items_tail = crash;
 
 	_dispatch_mgr_q.dq_items_head = crash;
 	_dispatch_mgr_q.dq_items_tail = crash;
@@ -917,33 +919,6 @@
 	}
 }
 
-DISPATCH_NOINLINE
-void
-_dispatch_fork_becomes_unsafe_slow(void)
-{
-	uint8_t value = os_atomic_or(&_dispatch_unsafe_fork,
-			_DISPATCH_UNSAFE_FORK_MULTITHREADED, relaxed);
-	if (value & _DISPATCH_UNSAFE_FORK_PROHIBIT) {
-		DISPATCH_CLIENT_CRASH(0, "Transition to multithreaded is prohibited");
-	}
-}
-
-DISPATCH_NOINLINE
-void
-_dispatch_prohibit_transition_to_multithreaded(bool prohibit)
-{
-	if (prohibit) {
-		uint8_t value = os_atomic_or(&_dispatch_unsafe_fork,
-				_DISPATCH_UNSAFE_FORK_PROHIBIT, relaxed);
-		if (value & _DISPATCH_UNSAFE_FORK_MULTITHREADED) {
-			DISPATCH_CLIENT_CRASH(0, "The executable is already multithreaded");
-		}
-	} else {
-		os_atomic_and(&_dispatch_unsafe_fork,
-				(uint8_t)~_DISPATCH_UNSAFE_FORK_PROHIBIT, relaxed);
-	}
-}
-
 #pragma mark -
 #pragma mark dispatch_queue_attr_t
 
@@ -1100,107 +1075,13 @@
 	dq->dq_label = label;
 }
 
-static inline bool
-_dispatch_base_queue_is_wlh(dispatch_queue_t dq, dispatch_queue_t tq)
-{
-	(void)dq; (void)tq;
-	return false;
-}
-
-static void
-_dispatch_queue_inherit_wlh_from_target(dispatch_queue_t dq,
-		dispatch_queue_t tq)
-{
-	uint64_t old_state, new_state, role;
-
-	if (!dx_hastypeflag(tq, QUEUE_ROOT)) {
-		role = DISPATCH_QUEUE_ROLE_INNER;
-	} else if (_dispatch_base_queue_is_wlh(dq, tq)) {
-		role = DISPATCH_QUEUE_ROLE_BASE_WLH;
-	} else {
-		role = DISPATCH_QUEUE_ROLE_BASE_ANON;
-	}
-
-	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, relaxed, {
-		new_state = old_state & ~DISPATCH_QUEUE_ROLE_MASK;
-		new_state |= role;
-		if (old_state == new_state) {
-			os_atomic_rmw_loop_give_up(break);
-		}
-	});
-
-	dispatch_wlh_t cur_wlh = _dispatch_get_wlh();
-	if (cur_wlh == (dispatch_wlh_t)dq && !_dq_state_is_base_wlh(new_state)) {
-		_dispatch_event_loop_leave_immediate(cur_wlh, new_state);
-	}
-	if (!dx_hastypeflag(tq, QUEUE_ROOT)) {
-#if DISPATCH_ALLOW_NON_LEAF_RETARGET
-		_dispatch_queue_atomic_flags_set(tq, DQF_TARGETED);
-#else
-		_dispatch_queue_atomic_flags_set_and_clear(tq, DQF_TARGETED, DQF_LEGACY);
-#endif
-	}
-}
-
-unsigned long volatile _dispatch_queue_serial_numbers =
-		DISPATCH_QUEUE_SERIAL_NUMBER_INIT;
-
-dispatch_priority_t
-_dispatch_queue_compute_priority_and_wlh(dispatch_queue_t dq,
-		dispatch_wlh_t *wlh_out)
-{
-	dispatch_priority_t p = dq->dq_priority & DISPATCH_PRIORITY_REQUESTED_MASK;
-	dispatch_queue_t tq = dq->do_targetq;
-	dispatch_priority_t tqp = tq->dq_priority &DISPATCH_PRIORITY_REQUESTED_MASK;
-	dispatch_wlh_t wlh = DISPATCH_WLH_ANON;
-
-	if (_dq_state_is_base_wlh(dq->dq_state)) {
-		wlh = (dispatch_wlh_t)dq;
-	}
-
-	while (unlikely(!dx_hastypeflag(tq, QUEUE_ROOT))) {
-		if (unlikely(tq == &_dispatch_mgr_q)) {
-			if (wlh_out) *wlh_out = DISPATCH_WLH_ANON;
-			return DISPATCH_PRIORITY_FLAG_MANAGER;
-		}
-		if (unlikely(_dispatch_queue_is_thread_bound(tq))) {
-			// thread-bound hierarchies are weird, we need to install
-			// from the context of the thread this hierarchy is bound to
-			if (wlh_out) *wlh_out = NULL;
-			return 0;
-		}
-		if (unlikely(DISPATCH_QUEUE_IS_SUSPENDED(tq))) {
-			// this queue may not be activated yet, so the queue graph may not
-			// have stabilized yet
-			_dispatch_ktrace1(DISPATCH_PERF_delayed_registration, dq);
-			if (wlh_out) *wlh_out = NULL;
-			return 0;
-		}
-
-		if (_dq_state_is_base_wlh(tq->dq_state)) {
-			wlh = (dispatch_wlh_t)tq;
-		} else if (unlikely(_dispatch_queue_is_legacy(tq))) {
-			// we're not allowed to dereference tq->do_targetq
-			_dispatch_ktrace1(DISPATCH_PERF_delayed_registration, dq);
-			if (wlh_out) *wlh_out = NULL;
-			return 0;
-		}
-
-		if (!(tq->dq_priority & DISPATCH_PRIORITY_FLAG_INHERIT)) {
-			if (p < tqp) p = tqp;
-		}
-		tq = tq->do_targetq;
-		tqp = tq->dq_priority & DISPATCH_PRIORITY_REQUESTED_MASK;
-	}
-
-	if (unlikely(!tqp)) {
-		// pthread root queues opt out of QoS
-		if (wlh_out) *wlh_out = DISPATCH_WLH_ANON;
-		return DISPATCH_PRIORITY_FLAG_MANAGER;
-	}
-	if (wlh_out) *wlh_out = wlh;
-	return _dispatch_priority_inherit_from_root_queue(p, tq);
-}
+// skip zero
+// 1 - main_q
+// 2 - mgr_q
+// 3 - mgr_root_q
+// 4,5,6,7,8,9,10,11,12,13,14,15 - global queues
+// we use 'xadd' on Intel, so the initial value == next assigned
+unsigned long volatile _dispatch_queue_serial_numbers = 16;
 
 DISPATCH_NOINLINE
 static dispatch_queue_t
@@ -1319,13 +1200,13 @@
 		}
 	}
 
-	dispatch_queue_t dq = _dispatch_object_alloc(vtable,
+	dispatch_queue_t dq = _dispatch_alloc(vtable,
 			sizeof(struct dispatch_queue_s) - DISPATCH_QUEUE_CACHELINE_PAD);
 	_dispatch_queue_init(dq, dqf, dqa->dqa_concurrent ?
-			DISPATCH_QUEUE_WIDTH_MAX : 1, DISPATCH_QUEUE_ROLE_INNER |
-			(dqa->dqa_inactive ? DISPATCH_QUEUE_INACTIVE : 0));
+			DISPATCH_QUEUE_WIDTH_MAX : 1, dqa->dqa_inactive);
 
 	dq->dq_label = label;
+
 #if HAVE_PTHREAD_WORKQUEUE_QOS
 	dq->dq_priority = dqa->dqa_qos_and_relpri;
 	if (overcommit == _dispatch_queue_attr_overcommit_enabled) {
@@ -1337,10 +1218,17 @@
 		// legacy way of inherithing the QoS from the target
 		_dispatch_queue_priority_inherit_from_target(dq, tq);
 	}
-	if (!dqa->dqa_inactive) {
-		_dispatch_queue_inherit_wlh_from_target(dq, tq);
+	if (!dqa->dqa_inactive && !dx_hastypeflag(tq, QUEUE_ROOT)) {
+		_dispatch_queue_atomic_flags_set(tq, DQF_TARGETED);
 	}
 	dq->do_targetq = tq;
+	if (!_dispatch_queue_is_legacy(dq) && !dqa->dqa_inactive) {
+		if (dx_hastypeflag(tq, QUEUE_ROOT)) {
+			dq->dq_wlh = _dispatch_root_queue_wlh_for_queue(tq, dq);
+		} else {
+			dq->dq_wlh = tq->dq_wlh;
+		}
+	}
 	_dispatch_object_debug(dq, "%s", __func__);
 	return _dispatch_introspection_queue_create(dq);
 }
@@ -1368,7 +1256,7 @@
 }
 
 void
-_dispatch_queue_destroy(dispatch_queue_t dq, bool *allow_free)
+_dispatch_queue_destroy(dispatch_queue_t dq)
 {
 	uint64_t dq_state = os_atomic_load2o(dq, dq_state, relaxed);
 	uint64_t initial_state = DISPATCH_QUEUE_STATE_INIT_VALUE(dq->dq_width);
@@ -1376,13 +1264,21 @@
 	if (dx_type(dq) == DISPATCH_QUEUE_GLOBAL_ROOT_TYPE) {
 		initial_state = DISPATCH_ROOT_QUEUE_STATE_INIT_VALUE;
 	}
-	dq_state &= ~DISPATCH_QUEUE_MAX_QOS_MASK;
-	dq_state &= ~DISPATCH_QUEUE_DIRTY;
-	dq_state &= ~DISPATCH_QUEUE_ROLE_MASK;
+	if (dx_metatype(dq) == _DISPATCH_SOURCE_TYPE) {
+		// dispatch_cancel_and_wait may apply overrides in a racy way with
+		// the source cancellation finishing. This race is expensive and not
+		// really worthwhile to resolve since the source becomes dead anyway.
+		//
+		// In a similar way using DISPATCH_QUEUE_WAKEUP_WAIT_FOR_EVENT causes
+		// DIRTY & MAX_QOS bits to stay with the channel or source sometimes
+		// never woken up before it dies, so we have to ignore them.
+		dq_state &= ~DISPATCH_QUEUE_MAX_QOS_MASK;
+		dq_state &= ~DISPATCH_QUEUE_DIRTY;
+		dq_state &= ~DISPATCH_QUEUE_RECEIVED_OVERRIDE;
+	}
 	if (slowpath(dq_state != initial_state)) {
 		if (_dq_state_drain_locked(dq_state)) {
-			DISPATCH_CLIENT_CRASH((uintptr_t)dq_state,
-					"Release of a locked queue");
+			DISPATCH_CLIENT_CRASH(dq, "Release of a locked queue");
 		}
 #ifndef __LP64__
 		dq_state >>= 32;
@@ -1390,6 +1286,9 @@
 		DISPATCH_CLIENT_CRASH((uintptr_t)dq_state,
 				"Release of a queue with corrupt state");
 	}
+	if (slowpath(dq == _dispatch_queue_get_current())) {
+		DISPATCH_CLIENT_CRASH(dq, "Release of a queue by itself");
+	}
 	if (slowpath(dq->dq_items_tail)) {
 		DISPATCH_CLIENT_CRASH(dq->dq_items_tail,
 				"Release of a queue while items are enqueued");
@@ -1398,61 +1297,30 @@
 	// trash the queue so that use after free will crash
 	dq->dq_items_head = (void *)0x200;
 	dq->dq_items_tail = (void *)0x200;
+	// poison the state with something that is suspended and is easy to spot
+	dq->dq_state = 0xdead000000000000;
 
 	dispatch_queue_t dqsq = os_atomic_xchg2o(dq, dq_specific_q,
 			(void *)0x200, relaxed);
 	if (dqsq) {
 		_dispatch_release(dqsq);
 	}
-
-	// fastpath for queues that never got their storage retained
-	if (likely(os_atomic_load2o(dq, dq_sref_cnt, relaxed) == 0)) {
-		// poison the state with something that is suspended and is easy to spot
-		dq->dq_state = 0xdead000000000000;
-		return;
+	if (dq->dq_wlh) {
+		dq->dq_wlh = NULL;
 	}
-
-	// Take over freeing the memory from _dispatch_object_dealloc()
-	//
-	// As soon as we call _dispatch_queue_release_storage(), we forfeit
-	// the possibility for the caller of dx_dispose() to finalize the object
-	// so that responsibility is ours.
-	_dispatch_object_finalize(dq);
-	*allow_free = false;
-	dq->dq_label = "<released queue, pending free>";
-	dq->do_targetq = NULL;
-	dq->do_finalizer = NULL;
-	dq->do_ctxt = NULL;
-	return _dispatch_queue_release_storage(dq);
 }
 
 // 6618342 Contact the team that owns the Instrument DTrace probe before
 //         renaming this symbol
 void
-_dispatch_queue_dispose(dispatch_queue_t dq, bool *allow_free)
+_dispatch_queue_dispose(dispatch_queue_t dq)
 {
 	_dispatch_object_debug(dq, "%s", __func__);
 	_dispatch_introspection_queue_dispose(dq);
 	if (dq->dq_label && _dispatch_queue_label_needs_free(dq)) {
 		free((void*)dq->dq_label);
 	}
-	_dispatch_queue_destroy(dq, allow_free);
-}
-
-void
-_dispatch_queue_xref_dispose(dispatch_queue_t dq)
-{
-	uint64_t dq_state = os_atomic_load2o(dq, dq_state, relaxed);
-	if (unlikely(_dq_state_is_suspended(dq_state))) {
-		long state = (long)dq_state;
-		if (sizeof(long) < sizeof(uint64_t)) state = (long)(dq_state >> 32);
-		if (unlikely(_dq_state_is_inactive(dq_state))) {
-			// Arguments for and against this assert are within 6705399
-			DISPATCH_CLIENT_CRASH(state, "Release of an inactive object");
-		}
-		DISPATCH_CLIENT_CRASH(dq_state, "Release of a suspended object");
-	}
-	os_atomic_or2o(dq, dq_atomic_flags, DQF_RELEASED, relaxed);
+	_dispatch_queue_destroy(dq);
 }
 
 DISPATCH_NOINLINE
@@ -1506,15 +1374,21 @@
 				return _dispatch_queue_suspend_slow(dq);
 			});
 		}
-		if (!_dq_state_drain_locked(dq_state)) {
-			value |= DLOCK_OWNER_MASK;
+#ifdef DLOCK_NOWAITERS_BIT
+		if (_dq_state_drain_locked(dq_state)) {
+			value |= DISPATCH_QUEUE_DRAIN_OWNER_MASK;
+		} else {
+			value ^= DLOCK_OWNER_INVALID;
 		}
+#else
+		value |= DLOCK_OWNER_INVALID;
+#endif
 	});
 
 	if (!_dq_state_is_suspended(dq_state)) {
 		// rdar://8181908 we need to extend the queue life for the duration
 		// of the call to wakeup at _dispatch_queue_resume() time.
-		_dispatch_retain_2(dq);
+		_dispatch_retain(dq);
 	}
 }
 
@@ -1559,15 +1433,12 @@
 static void
 _dispatch_queue_resume_finalize_activation(dispatch_queue_t dq)
 {
-	bool allow_resume = true;
 	// Step 2: run the activation finalizer
 	if (dx_vtable(dq)->do_finalize_activation) {
-		dx_vtable(dq)->do_finalize_activation(dq, &allow_resume);
+		dx_vtable(dq)->do_finalize_activation(dq);
 	}
 	// Step 3: consume the suspend count
-	if (allow_resume) {
-		return dx_vtable(dq)->do_resume(dq, false);
-	}
+	return dx_vtable(dq)->do_resume(dq, false);
 }
 
 void
@@ -1575,15 +1446,12 @@
 {
 	// covers all suspend and inactive bits, including side suspend bit
 	const uint64_t suspend_bits = DISPATCH_QUEUE_SUSPEND_BITS_MASK;
-	uint64_t pending_barrier_width =
-			(dq->dq_width - 1) * DISPATCH_QUEUE_WIDTH_INTERVAL;
-	uint64_t set_owner_and_set_full_width_and_in_barrier =
-			_dispatch_lock_value_for_self() | DISPATCH_QUEUE_WIDTH_FULL_BIT |
-			DISPATCH_QUEUE_IN_BARRIER;
-
+	// covers all suspend and inactive bits and owner mask
+	const uint64_t suspend_owner_bits = DISPATCH_QUEUE_SUSPEND_BITS_MASK |
+			DISPATCH_QUEUE_DRAIN_OWNER_MASK;
 	// backward compatibility: only dispatch sources can abuse
 	// dispatch_resume() to really mean dispatch_activate()
-	bool is_source = (dx_metatype(dq) == _DISPATCH_SOURCE_TYPE);
+	bool resume_can_activate = (dx_type(dq) == DISPATCH_SOURCE_KEVENT_TYPE);
 	uint64_t dq_state, value;
 
 	dispatch_assert(dq->do_ref_cnt != DISPATCH_OBJECT_GLOBAL_REFCNT);
@@ -1633,49 +1501,51 @@
 					+ DISPATCH_QUEUE_NEEDS_ACTIVATION) {
 				// { sc:1 i:0 na:1 } -> { sc:1 i:0 na:0 }
 				value = dq_state - DISPATCH_QUEUE_NEEDS_ACTIVATION;
-			} else if (is_source && (dq_state & suspend_bits) ==
+			} else if (resume_can_activate && (dq_state & suspend_bits) ==
 					DISPATCH_QUEUE_NEEDS_ACTIVATION + DISPATCH_QUEUE_INACTIVE) {
 				// { sc:0 i:1 na:1 } -> { sc:1 i:0 na:0 }
 				value = dq_state - DISPATCH_QUEUE_INACTIVE
 						- DISPATCH_QUEUE_NEEDS_ACTIVATION
 						+ DISPATCH_QUEUE_SUSPEND_INTERVAL;
-			} else if (unlikely(os_sub_overflow(dq_state,
-					DISPATCH_QUEUE_SUSPEND_INTERVAL, &value))) {
-				// underflow means over-resume or a suspend count transfer
-				// to the side count is needed
-				os_atomic_rmw_loop_give_up({
-					if (!(dq_state & DISPATCH_QUEUE_HAS_SIDE_SUSPEND_CNT)) {
-						goto over_resume;
-					}
-					return _dispatch_queue_resume_slow(dq);
-				});
-		//
-		// below this, value = dq_state - DISPATCH_QUEUE_SUSPEND_INTERVAL
-		//
-			} else if (!_dq_state_is_runnable(value)) {
-				// Out of width or still suspended.
-				// For the former, force _dispatch_queue_non_barrier_complete
-				// to reconsider whether it has work to do
-				value |= DISPATCH_QUEUE_DIRTY;
-			} else if (!_dq_state_drain_locked_by(value, DLOCK_OWNER_MASK)) {
-				dispatch_assert(_dq_state_drain_locked(value));
-				// still locked by someone else, make drain_try_unlock() fail
-				// and reconsider whether it has work to do
-				value |= DISPATCH_QUEUE_DIRTY;
-			} else if (!is_source && (_dq_state_has_pending_barrier(value) ||
-					value + pending_barrier_width <
-					DISPATCH_QUEUE_WIDTH_FULL_BIT)) {
-				// if we can, acquire the full width drain lock
-				// and then perform a lock transfer
-				//
-				// However this is never useful for a source where there are no
-				// sync waiters, so never take the lock and do a plain wakeup
-				value &= DISPATCH_QUEUE_DRAIN_PRESERVED_BITS_MASK;
-				value |= set_owner_and_set_full_width_and_in_barrier;
+			} else if ((dq_state & suspend_owner_bits) == (suspend_owner_bits &
+					(DISPATCH_QUEUE_SUSPEND_INTERVAL + DLOCK_OWNER_INVALID))) {
+				value = dq_state;
+				value ^= DISPATCH_QUEUE_SUSPEND_INTERVAL + DLOCK_OWNER_INVALID;
+				uint64_t full_width = value;
+				if (_dq_state_has_pending_barrier(full_width)) {
+					full_width -= DISPATCH_QUEUE_PENDING_BARRIER;
+					full_width += DISPATCH_QUEUE_WIDTH_INTERVAL;
+					full_width += DISPATCH_QUEUE_IN_BARRIER;
+				} else {
+					full_width += dq->dq_width * DISPATCH_QUEUE_WIDTH_INTERVAL;
+					full_width += DISPATCH_QUEUE_IN_BARRIER;
+				}
+				if ((full_width & DISPATCH_QUEUE_WIDTH_MASK) ==
+						DISPATCH_QUEUE_WIDTH_FULL_BIT) {
+					value = full_width;
+					value &= ~DISPATCH_QUEUE_DIRTY;
+					value ^= _dispatch_tid_self();
+				} else {
+					value &= ~DISPATCH_QUEUE_MAX_QOS_MASK;
+					value &= ~DISPATCH_QUEUE_RECEIVED_OVERRIDE;
+				}
 			} else {
-				// clear overrides and force a wakeup
-				value &= ~DISPATCH_QUEUE_DRAIN_UNLOCK_MASK;
-				value &= ~DISPATCH_QUEUE_MAX_QOS_MASK;
+				value = DISPATCH_QUEUE_SUSPEND_INTERVAL;
+				if (unlikely(os_sub_overflow(dq_state, value, &value))) {
+					// underflow means over-resume or a suspend count transfer
+					// to the side count is needed
+					os_atomic_rmw_loop_give_up({
+						if (!(dq_state & DISPATCH_QUEUE_HAS_SIDE_SUSPEND_CNT)) {
+							goto over_resume;
+						}
+						return _dispatch_queue_resume_slow(dq);
+					});
+				}
+				if (unlikely(_dq_state_is_runnable(value))) {
+					// make drain_try_unlock() fail and reconsider whether
+					// it has work to do
+					value |= DISPATCH_QUEUE_DIRTY;
+				}
 			}
 		});
 	}
@@ -1698,26 +1568,21 @@
 		return;
 	}
 
-	if (_dq_state_is_dirty(dq_state)) {
+	if ((dq_state ^ value) & DISPATCH_QUEUE_IN_BARRIER) {
+		_dispatch_try_lock_transfer_or_wakeup(dq);
+	} else if (_dq_state_should_wakeup(value)) {
 		// <rdar://problem/14637483>
 		// dependency ordering for dq state changes that were flushed
 		// and not acted upon
 		os_atomic_thread_fence(dependency);
-		dq = os_atomic_force_dependency_on(dq, dq_state);
+		dq = os_atomic_force_dependency_on(dq, value);
+		dispatch_qos_t qos = _dq_state_max_qos(dq_state);
+		// Balancing the retain() done in suspend() for rdar://8181908
+		return dx_wakeup(dq, qos, DISPATCH_WAKEUP_CONSUME);
 	}
-	// Balancing the retain_2 done in suspend() for rdar://8181908
-	dispatch_wakeup_flags_t flags = DISPATCH_WAKEUP_CONSUME_2;
-	if ((dq_state ^ value) & DISPATCH_QUEUE_IN_BARRIER) {
-		flags |= DISPATCH_WAKEUP_BARRIER_COMPLETE;
-	} else if (!_dq_state_is_runnable(value)) {
-		if (_dq_state_is_base_wlh(dq_state)) {
-			_dispatch_event_loop_assert_not_owned((dispatch_wlh_t)dq);
-		}
-		return _dispatch_release_2(dq);
-	}
-	dispatch_assert(!_dq_state_received_sync_wait(dq_state));
-	dispatch_assert(!_dq_state_in_sync_transfer(dq_state));
-	return dx_wakeup(dq, _dq_state_max_qos(dq_state), flags);
+
+	// Balancing the retain() done in suspend() for rdar://8181908
+	return _dispatch_release_tailcall(dq);
 
 over_resume:
 	if (unlikely(_dq_state_is_inactive(dq_state))) {
@@ -1778,7 +1643,6 @@
 	os_atomic_rmw_loop2o(dq, dq_atomic_flags, old_dqf, new_dqf, relaxed, {
 		new_dqf = (old_dqf & DQF_FLAGS_MASK) | DQF_WIDTH(tmp);
 	});
-	_dispatch_queue_inherit_wlh_from_target(dq, dq->do_targetq);
 	_dispatch_object_debug(dq, "%s", __func__);
 }
 
@@ -1813,18 +1677,16 @@
 	dispatch_queue_t otq = dq->do_targetq;
 
 	if (_dispatch_queue_atomic_flags(dq) & DQF_TARGETED) {
-#if DISPATCH_ALLOW_NON_LEAF_RETARGET
 		_dispatch_ktrace3(DISPATCH_PERF_non_leaf_retarget, dq, otq, tq);
 		_dispatch_bug_deprecated("Changing the target of a queue "
 				"already targeted by other dispatch objects");
-#else
-		DISPATCH_CLIENT_CRASH(0, "Cannot change the target of a queue "
-				"already targeted by other dispatch objects");
-#endif
 	}
 
 	_dispatch_queue_priority_inherit_from_target(dq, tq);
-	_dispatch_queue_inherit_wlh_from_target(dq, tq);
+	if (!dx_hastypeflag(tq, QUEUE_ROOT)) {
+		_dispatch_queue_atomic_flags_set(tq, DQF_TARGETED);
+	}
+
 #if HAVE_PTHREAD_WORKQUEUE_QOS
 	// see _dispatch_queue_class_wakeup()
 	_dispatch_queue_sidelock_lock(dq);
@@ -1856,33 +1718,22 @@
 		return dx_vtable(dq)->do_resume(dq, false);
 	}
 
-#if !DISPATCH_ALLOW_NON_LEAF_RETARGET
-	if (_dispatch_queue_atomic_flags(dq) & DQF_TARGETED) {
-		DISPATCH_CLIENT_CRASH(0, "Cannot change the target of a queue "
-				"already targeted by other dispatch objects");
-	}
-#endif
-
 	if (unlikely(!_dispatch_queue_is_legacy(dq))) {
-#if DISPATCH_ALLOW_NON_LEAF_RETARGET
 		if (_dispatch_queue_atomic_flags(dq) & DQF_TARGETED) {
-			DISPATCH_CLIENT_CRASH(0, "Cannot change the target of a queue "
+			DISPATCH_CLIENT_CRASH(dq, "Cannot change the target of a queue "
 					"already targeted by other dispatch objects");
 		}
-#endif
-		DISPATCH_CLIENT_CRASH(0, "Cannot change the target of this object "
+		DISPATCH_CLIENT_CRASH(dq, "Cannot change the target of this object "
 				"after it has been activated");
 	}
 
 	unsigned long type = dx_type(dq);
 	switch (type) {
 	case DISPATCH_QUEUE_LEGACY_TYPE:
-#if DISPATCH_ALLOW_NON_LEAF_RETARGET
 		if (_dispatch_queue_atomic_flags(dq) & DQF_TARGETED) {
 			_dispatch_bug_deprecated("Changing the target of a queue "
 					"already targeted by other dispatch objects");
 		}
-#endif
 		break;
 	case DISPATCH_SOURCE_KEVENT_TYPE:
 	case DISPATCH_MACH_CHANNEL_TYPE:
@@ -1920,6 +1771,7 @@
 	.do_ctxt = &_dispatch_mgr_root_queue_context,
 	.dq_label = "com.apple.root.libdispatch-manager",
 	.dq_atomic_flags = DQF_WIDTH(DISPATCH_QUEUE_WIDTH_POOL),
+	.dq_wlh = DISPATCH_WLH_GLOBAL,
 	.dq_priority = DISPATCH_PRIORITY_FLAG_MANAGER |
 			DISPATCH_PRIORITY_SATURATED_OVERRIDE,
 	.dq_serialnum = 3,
@@ -2143,7 +1995,7 @@
 
 	dqs = sizeof(struct dispatch_queue_s) - DISPATCH_QUEUE_CACHELINE_PAD;
 	dqs = roundup(dqs, _Alignof(struct dispatch_root_queue_context_s));
-	dq = _dispatch_object_alloc(DISPATCH_VTABLE(queue_root), dqs +
+	dq = _dispatch_alloc(DISPATCH_VTABLE(queue_root), dqs +
 			sizeof(struct dispatch_root_queue_context_s) +
 			sizeof(struct dispatch_pthread_root_queue_context_s));
 	qc = (void*)dq + dqs;
@@ -2158,11 +2010,13 @@
 		}
 	}
 
-	_dispatch_queue_init(dq, dqf, DISPATCH_QUEUE_WIDTH_POOL, 0);
+	_dispatch_queue_init(dq, dqf, DISPATCH_QUEUE_WIDTH_POOL, false);
 	dq->dq_label = label;
 	dq->dq_state = DISPATCH_ROOT_QUEUE_STATE_INIT_VALUE;
 	dq->do_ctxt = qc;
+	dq->do_targetq = NULL;
 	dq->dq_priority = DISPATCH_PRIORITY_SATURATED_OVERRIDE;
+	dq->dq_wlh = DISPATCH_WLH_GLOBAL;
 
 	pqc->dpq_thread_mediator.do_vtable = DISPATCH_VTABLE(semaphore);
 	qc->dgq_ctxt = pqc;
@@ -2231,7 +2085,7 @@
 #endif // DISPATCH_ENABLE_PTHREAD_ROOT_QUEUES
 
 void
-_dispatch_pthread_root_queue_dispose(dispatch_queue_t dq, bool *allow_free)
+_dispatch_pthread_root_queue_dispose(dispatch_queue_t dq)
 {
 	if (slowpath(dq->do_ref_cnt == DISPATCH_OBJECT_GLOBAL_REFCNT)) {
 		DISPATCH_INTERNAL_CRASH(dq, "Global root queue disposed");
@@ -2243,7 +2097,7 @@
 	dispatch_pthread_root_queue_context_t pqc = qc->dgq_ctxt;
 
 	pthread_attr_destroy(&pqc->dpq_thread_attr);
-	_dispatch_semaphore_dispose(&pqc->dpq_thread_mediator, NULL);
+	_dispatch_semaphore_dispose(&pqc->dpq_thread_mediator);
 	if (pqc->dpq_thread_configure) {
 		Block_release(pqc->dpq_thread_configure);
 	}
@@ -2252,7 +2106,7 @@
 	if (dq->dq_label && _dispatch_queue_label_needs_free(dq)) {
 		free((void*)dq->dq_label);
 	}
-	_dispatch_queue_destroy(dq, allow_free);
+	_dispatch_queue_destroy(dq);
 }
 
 #pragma mark -
@@ -2273,8 +2127,7 @@
 DISPATCH_DECL(dispatch_queue_specific);
 
 void
-_dispatch_queue_specific_queue_dispose(dispatch_queue_specific_queue_t dqsq,
-		bool *allow_free)
+_dispatch_queue_specific_queue_dispose(dispatch_queue_specific_queue_t dqsq)
 {
 	dispatch_queue_specific_t dqs, tmp;
 	dispatch_queue_t rq = _dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, false);
@@ -2285,7 +2138,7 @@
 		}
 		free(dqs);
 	}
-	_dispatch_queue_destroy(dqsq->_as_dq, allow_free);
+	_dispatch_queue_destroy(dqsq->_as_dq);
 }
 
 static void
@@ -2293,13 +2146,12 @@
 {
 	dispatch_queue_specific_queue_t dqsq;
 
-	dqsq = _dispatch_object_alloc(DISPATCH_VTABLE(queue_specific_queue),
+	dqsq = _dispatch_alloc(DISPATCH_VTABLE(queue_specific_queue),
 			sizeof(struct dispatch_queue_specific_queue_s));
-	_dispatch_queue_init(dqsq->_as_dq, DQF_NONE, DISPATCH_QUEUE_WIDTH_MAX,
-			DISPATCH_QUEUE_ROLE_BASE_ANON);
+	_dispatch_queue_init(dqsq->_as_dq, DQF_NONE,
+			DISPATCH_QUEUE_WIDTH_MAX, false);
 	dqsq->do_xref_cnt = -1;
-	dqsq->do_targetq = _dispatch_get_root_queue(
-			DISPATCH_QOS_USER_INITIATED, true);
+	dqsq->do_targetq = _dispatch_get_root_queue(DISPATCH_QOS_USER_INITIATED, true);
 	dqsq->dq_label = "queue-specific";
 	TAILQ_INIT(&dqsq->dqsq_contexts);
 	if (slowpath(!os_atomic_cmpxchg2o(dq, dq_specific_q, NULL,
@@ -2427,7 +2279,7 @@
 		DISPATCH_CLIENT_CRASH(dq->dq_width, "Invalid queue type");
 	}
 	uint64_t dq_state = os_atomic_load2o(dq, dq_state, relaxed);
-	return _dq_state_drain_locked_by_self(dq_state);
+	return _dq_state_drain_locked_by(dq_state, _dispatch_tid_self());
 }
 #endif
 
@@ -2439,13 +2291,12 @@
 {
 	size_t offset = 0;
 	dispatch_queue_t target = dq->do_targetq;
-	const char *tlabel = target && target->dq_label ? target->dq_label : "";
 	uint64_t dq_state = os_atomic_load2o(dq, dq_state, relaxed);
 
-	offset += dsnprintf(&buf[offset], bufsiz - offset, "sref = %d, "
+	offset += dsnprintf(&buf[offset], bufsiz - offset,
 			"target = %s[%p], width = 0x%x, state = 0x%016llx",
-			dq->dq_sref_cnt + 1, tlabel, target, dq->dq_width,
-			(unsigned long long)dq_state);
+			target && target->dq_label ? target->dq_label : "", target,
+			dq->dq_width, (unsigned long long)dq_state);
 	if (_dq_state_is_suspended(dq_state)) {
 		offset += dsnprintf(&buf[offset], bufsiz - offset, ", suspended = %d",
 			_dq_state_suspend_cnt(dq_state));
@@ -2510,15 +2361,11 @@
 #endif
 
 #if DISPATCH_PERF_MON
-
-#define DISPATCH_PERF_MON_BUCKETS 8
-
 static struct {
 	uint64_t volatile time_total;
 	uint64_t volatile count_total;
 	uint64_t volatile thread_total;
-} _dispatch_stats[DISPATCH_PERF_MON_BUCKETS];
-DISPATCH_USED static size_t _dispatch_stat_buckets = DISPATCH_PERF_MON_BUCKETS;
+} _dispatch_stats[65];
 
 void
 _dispatch_queue_merge_stats(uint64_t start, bool trace, perfmon_thread_type type)
@@ -2526,14 +2373,15 @@
 	uint64_t delta = _dispatch_absolute_time() - start;
 	unsigned long count;
 	int bucket = 0;
+
 	count = (unsigned long)_dispatch_thread_getspecific(dispatch_bcounter_key);
 	_dispatch_thread_setspecific(dispatch_bcounter_key, NULL);
+
 	if (count == 0) {
 		bucket = 0;
 		if (trace) _dispatch_ktrace1(DISPATCH_PERF_MON_worker_useless, type);
 	} else {
-		bucket = MIN(DISPATCH_PERF_MON_BUCKETS - 1,
-					 (int)sizeof(count) * CHAR_BIT - __builtin_clzl(count));
+		bucket = (int)sizeof(count) * CHAR_BIT - __builtin_clzl(count);
 		os_atomic_add(&_dispatch_stats[bucket].count_total, count, relaxed);
 	}
 	os_atomic_add(&_dispatch_stats[bucket].time_total, delta, relaxed);
@@ -2571,9 +2419,8 @@
 			if (likely(old_pri & ~_PTHREAD_PRIORITY_FLAGS_MASK)) {
 				pflags |= _PTHREAD_SET_SELF_QOS_FLAG;
 			}
-			uint64_t mgr_dq_state =
-					os_atomic_load2o(&_dispatch_mgr_q, dq_state, relaxed);
-			if (unlikely(_dq_state_drain_locked_by_self(mgr_dq_state))) {
+			if (unlikely(DISPATCH_QUEUE_DRAIN_OWNER(&_dispatch_mgr_q) ==
+					_dispatch_tid_self())) {
 				DISPATCH_INTERNAL_CRASH(pp,
 						"Changing the QoS while on the manager queue");
 			}
@@ -2617,6 +2464,9 @@
 			kv = _voucher_swap_and_get_mach_voucher(ov, v);
 		}
 	}
+#if !PTHREAD_WORKQUEUE_RESETS_VOUCHER_AND_PRIORITY_ON_PARK
+	flags &= ~(dispatch_thread_set_self_t)DISPATCH_THREAD_PARK;
+#endif
 	if (!(flags & DISPATCH_THREAD_PARK)) {
 		_dispatch_set_priority_and_mach_voucher_slow(priority, kv);
 	}
@@ -2915,7 +2765,7 @@
 	oq = os_atomic_xchg2o(dbpd, dbpd_queue, NULL, relaxed);
 	if (oq) {
 		// balances dispatch_{,barrier_,}sync
-		_os_object_release_internal_n(oq->_as_os_obj, 2);
+		_os_object_release_internal(oq->_as_os_obj);
 	}
 }
 
@@ -2941,7 +2791,7 @@
 	oq = os_atomic_xchg2o(dbpd, dbpd_queue, NULL, relaxed);
 	if (oq) {
 		// balances dispatch_{,barrier_,group_}async
-		_os_object_release_internal_n_inline(oq->_as_os_obj, 2);
+		_os_object_release_internal_inline(oq->_as_os_obj);
 	}
 	if (release) {
 		Block_release(b);
@@ -3014,7 +2864,8 @@
 		// that times out, subsequent waits will not boost the qos of the
 		// still-running block.
 		dx_wakeup(boost_oq, _dispatch_qos_from_pp(pp),
-				DISPATCH_WAKEUP_BLOCK_WAIT | DISPATCH_WAKEUP_CONSUME_2);
+				DISPATCH_WAKEUP_BLOCK_WAIT | DISPATCH_WAKEUP_OVERRIDING |
+				DISPATCH_WAKEUP_CONSUME);
 	}
 
 	mach_port_t boost_th = dbpd->dbpd_thread;
@@ -3078,7 +2929,7 @@
 
 	// balanced in d_block_async_invoke_and_release or d_block_wait
 	if (os_atomic_cmpxchg2o(dbpd, dbpd_queue, NULL, oq, relaxed)) {
-		_os_object_retain_internal_n_inline(oq->_as_os_obj, 2);
+		_os_object_retain_internal_inline(oq->_as_os_obj);
 	}
 
 	if (dc_flags & DISPATCH_OBJ_CONSUME_BIT) {
@@ -3235,12 +3086,17 @@
 
 	rq = dq->do_targetq;
 	while (slowpath(rq->do_targetq) && rq != old_dq) {
-		_dispatch_queue_non_barrier_complete(rq);
+		_dispatch_non_barrier_complete(rq);
 		rq = rq->do_targetq;
 	}
 
-	_dispatch_queue_non_barrier_complete(dq);
-	_dispatch_release_tailcall(dq); // pairs with _dispatch_async_redirect_wrap
+	_dispatch_non_barrier_complete(dq);
+
+	if (dic->dic_deferred) {
+		return _dispatch_queue_drain_deferred_invoke(dq, dic, flags, 0);
+	}
+
+	_dispatch_release_tailcall(dq);
 }
 
 DISPATCH_ALWAYS_INLINE
@@ -3257,7 +3113,7 @@
 	dc->dc_other = dou._do;
 	dc->dc_voucher = DISPATCH_NO_VOUCHER;
 	dc->dc_priority = DISPATCH_NO_PRIORITY;
-	_dispatch_retain(dq); // released in _dispatch_async_redirect_invoke
+	_dispatch_retain(dq);
 	return dc;
 }
 
@@ -3408,11 +3264,36 @@
 #pragma mark -
 #pragma mark _dispatch_sync_invoke / _dispatch_sync_complete
 
+DISPATCH_ALWAYS_INLINE
+static inline void
+_dispatch_barrier_complete_inline(dispatch_queue_t dq)
+{
+	uint64_t owned = DISPATCH_QUEUE_IN_BARRIER +
+			dq->dq_width * DISPATCH_QUEUE_WIDTH_INTERVAL;
+
+	if (unlikely(dq->dq_items_tail)) {
+		return _dispatch_try_lock_transfer_or_wakeup(dq);
+	}
+
+	if (unlikely(!_dispatch_queue_drain_try_unlock(dq, owned, true))) {
+		// someone enqueued a slow item at the head
+		// looping may be its last chance
+		return _dispatch_try_lock_transfer_or_wakeup(dq);
+	}
+}
+
 DISPATCH_NOINLINE
 static void
-_dispatch_queue_non_barrier_complete(dispatch_queue_t dq)
+_dispatch_barrier_complete(dispatch_queue_t dq)
 {
-	uint64_t old_state, new_state, owner_self = _dispatch_lock_value_for_self();
+	_dispatch_barrier_complete_inline(dq);
+}
+
+DISPATCH_NOINLINE
+static void
+_dispatch_non_barrier_complete(dispatch_queue_t dq)
+{
+	uint64_t old_state, new_state;
 
 	// see _dispatch_queue_resume()
 	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, relaxed, {
@@ -3435,7 +3316,7 @@
 					DISPATCH_QUEUE_WIDTH_FULL_BIT) {
 				new_state = full_width;
 				new_state &= ~DISPATCH_QUEUE_DIRTY;
-				new_state |= owner_self;
+				new_state ^= _dispatch_tid_self();
 			} else if (_dq_state_is_dirty(old_state)) {
 				new_state |= DISPATCH_QUEUE_ENQUEUED;
 			}
@@ -3443,19 +3324,11 @@
 	});
 
 	if ((old_state ^ new_state) & DISPATCH_QUEUE_IN_BARRIER) {
-		if (_dq_state_is_dirty(old_state)) {
-			// <rdar://problem/14637483>
-			// dependency ordering for dq state changes that were flushed
-			// and not acted upon
-			os_atomic_thread_fence(dependency);
-			dq = os_atomic_force_dependency_on(dq, old_state);
-		}
-		return _dispatch_queue_barrier_complete(dq, 0, 0);
+		return _dispatch_try_lock_transfer_or_wakeup(dq);
 	}
 
 	if ((old_state ^ new_state) & DISPATCH_QUEUE_ENQUEUED) {
-		_dispatch_retain_2(dq);
-		dispatch_assert(!_dq_state_is_base_wlh(new_state));
+		_dispatch_retain(dq);
 		return dx_push(dq->do_targetq, dq, _dq_state_max_qos(new_state));
 	}
 }
@@ -3490,9 +3363,9 @@
 	do {
 		if (dq == stop_dq) return;
 		if (barrier) {
-			_dispatch_queue_barrier_complete(dq, 0, 0);
+			_dispatch_barrier_complete(dq);
 		} else {
-			_dispatch_queue_non_barrier_complete(dq);
+			_dispatch_non_barrier_complete(dq);
 		}
 		dq = dq->do_targetq;
 		barrier = (dq->dq_width == 1);
@@ -3514,7 +3387,7 @@
 		dispatch_function_t func)
 {
 	_dispatch_sync_function_invoke_inline(dq, ctxt, func);
-	_dispatch_queue_non_barrier_complete(dq);
+	_dispatch_non_barrier_complete(dq);
 }
 
 DISPATCH_NOINLINE
@@ -3523,274 +3396,60 @@
 		dispatch_function_t func)
 {
 	_dispatch_sync_function_invoke_inline(dq, ctxt, func);
-	dx_wakeup(dq, 0, DISPATCH_WAKEUP_BARRIER_COMPLETE);
-}
-
-/*
- * This is an optimized version of _dispatch_barrier_sync_invoke_and_complete
- *
- * For queues we can cheat and inline the unlock code, which is invalid
- * for objects with a more complex state machine (sources or mach channels)
- */
-DISPATCH_NOINLINE
-static void
-_dispatch_queue_barrier_sync_invoke_and_complete(dispatch_queue_t dq,
-		void *ctxt, dispatch_function_t func)
-{
-	_dispatch_sync_function_invoke_inline(dq, ctxt, func);
-	if (unlikely(dq->dq_items_tail || dq->dq_width > 1)) {
-		return _dispatch_queue_barrier_complete(dq, 0, 0);
-	}
-
-	// Presence of any of these bits requires more work that only
-	// _dispatch_queue_barrier_complete() handles properly
-	//
-	// Note: testing for RECEIVED_OVERRIDE or RECEIVED_SYNC_WAIT without
-	// checking the role is sloppy, but is a super fast check, and neither of
-	// these bits should be set if the lock was never contended/discovered.
-	const uint64_t fail_unlock_mask = DISPATCH_QUEUE_SUSPEND_BITS_MASK |
-			DISPATCH_QUEUE_ENQUEUED | DISPATCH_QUEUE_DIRTY |
-			DISPATCH_QUEUE_RECEIVED_OVERRIDE | DISPATCH_QUEUE_SYNC_TRANSFER |
-			DISPATCH_QUEUE_RECEIVED_SYNC_WAIT;
-	uint64_t old_state, new_state;
-
-	// similar to _dispatch_queue_drain_try_unlock
-	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
-		new_state  = old_state - DISPATCH_QUEUE_SERIAL_DRAIN_OWNED;
-		new_state &= ~DISPATCH_QUEUE_DRAIN_UNLOCK_MASK;
-		new_state &= ~DISPATCH_QUEUE_MAX_QOS_MASK;
-		if (unlikely(old_state & fail_unlock_mask)) {
-			os_atomic_rmw_loop_give_up({
-				return _dispatch_queue_barrier_complete(dq, 0, 0);
-			});
-		}
-	});
-	if (_dq_state_is_base_wlh(old_state)) {
-		_dispatch_event_loop_assert_not_owned((dispatch_wlh_t)dq);
-	}
+	_dispatch_barrier_complete_inline(dq);
 }
 
 #pragma mark -
 #pragma mark _dispatch_sync_wait / _dispatch_sync_waiter_wake
 
-#define DISPATCH_SYNC_WAITER_NO_UNLOCK (~0ull)
-
 DISPATCH_NOINLINE
 static void
-_dispatch_sync_waiter_wake(dispatch_sync_context_t dsc,
-		dispatch_wlh_t wlh, uint64_t old_state, uint64_t new_state)
+_dispatch_sync_waiter_wake(OS_UNUSED dispatch_queue_t dq,
+		dispatch_sync_context_t dsc)
 {
-	dispatch_wlh_t waiter_wlh = dsc->dc_data;
-
-	if (_dq_state_in_sync_transfer(old_state) ||
-			_dq_state_in_sync_transfer(new_state) ||
-			(waiter_wlh != DISPATCH_WLH_ANON)) {
-		_dispatch_event_loop_wake_owner(dsc, wlh, old_state, new_state);
+	if (dsc->dsc_override_qos > dsc->dsc_override_qos_floor) {
+		_dispatch_wqthread_override_start((mach_port_t)&dsc->dc_data,
+				dsc->dsc_override_qos);
 	}
-	if (waiter_wlh == DISPATCH_WLH_ANON) {
-		if (dsc->dsc_override_qos > dsc->dsc_override_qos_floor) {
-			_dispatch_wqthread_override_start(dsc->dsc_waiter,
-					dsc->dsc_override_qos);
-		}
-		_dispatch_thread_event_signal(&dsc->dsc_event);
-	}
+	_dispatch_thread_event_signal(&dsc->dsc_event);
 	_dispatch_introspection_queue_item_complete(dsc->_as_dc);
 }
 
 DISPATCH_NOINLINE
 static void
-_dispatch_sync_waiter_redirect_or_wake(dispatch_queue_t dq, uint64_t owned,
+_dispatch_sync_waiter_redirect_or_wake(dispatch_queue_t dq,
 		dispatch_object_t dou)
 {
-	dispatch_sync_context_t dsc = (dispatch_sync_context_t)dou._dc;
-	uint64_t next_owner = 0, old_state, new_state;
-	dispatch_wlh_t wlh = NULL;
+	dispatch_sync_context_t dsc = (dispatch_sync_context_t )dou._dc;
+	uint32_t tid = (uint32_t)(uintptr_t)dsc->dc_data;
 
+	if (likely(dsc->dsc_override_qos)) {
+		uint64_t dq_state = os_atomic_load2o(dq, dq_state, relaxed);
+		if (dsc->dsc_override_qos < _dq_state_max_qos(dq_state)) {
+			dsc->dsc_override_qos = _dq_state_max_qos(dq_state);
+		}
+	}
 	_dispatch_trace_continuation_pop(dq, dsc->_as_dc);
 
-	if (owned == DISPATCH_SYNC_WAITER_NO_UNLOCK) {
-		dispatch_assert(!(dsc->dc_flags & DISPATCH_OBJ_BARRIER_BIT));
-		new_state = old_state = os_atomic_load2o(dq, dq_state, relaxed);
-	} else {
-		if (dsc->dc_flags & DISPATCH_OBJ_BARRIER_BIT) {
-			next_owner = _dispatch_lock_value_from_tid(dsc->dsc_waiter);
-		}
-		os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
-			new_state  = old_state - owned;
-			new_state &= ~DISPATCH_QUEUE_DRAIN_UNLOCK_MASK;
-			new_state &= ~DISPATCH_QUEUE_DIRTY;
-			new_state |= next_owner;
-			if (_dq_state_is_base_wlh(old_state)) {
-				new_state |= DISPATCH_QUEUE_SYNC_TRANSFER;
-			}
-		});
-		if (_dq_state_is_base_wlh(old_state)) {
-			wlh = (dispatch_wlh_t)dq;
-		} else if (_dq_state_received_override(old_state)) {
-			// Ensure that the root queue sees that this thread was overridden.
-			_dispatch_set_basepri_override_qos(_dq_state_max_qos(old_state));
-		}
-	}
-
-	if (dsc->dc_data == DISPATCH_WLH_ANON) {
-		if (dsc->dsc_override_qos < _dq_state_max_qos(old_state)) {
-			dsc->dsc_override_qos = _dq_state_max_qos(old_state);
-		}
-	}
-
-	if (unlikely(_dq_state_is_inner_queue(old_state))) {
-		dispatch_queue_t tq = dq->do_targetq;
-		if (likely(tq->dq_width == 1)) {
+	while (unlikely(dq->do_targetq->do_targetq)) {
+		dq = dq->do_targetq;
+		if (likely(dq->dq_width == 1)) {
 			dsc->dc_flags = DISPATCH_OBJ_BARRIER_BIT |
 					DISPATCH_OBJ_SYNC_WAITER_BIT;
+			if (unlikely(!_dispatch_queue_try_acquire_barrier_sync(dq, tid))) {
+				_dispatch_introspection_queue_item_complete(dsc->_as_dc);
+				return _dispatch_queue_push_sync_waiter(dq, dsc);
+			}
 		} else {
 			dsc->dc_flags = DISPATCH_OBJ_SYNC_WAITER_BIT;
-		}
-		_dispatch_introspection_queue_item_complete(dsc->_as_dc);
-		return _dispatch_queue_push_sync_waiter(tq, dsc, 0);
-	}
-
-	return _dispatch_sync_waiter_wake(dsc, wlh, old_state, new_state);
-}
-
-DISPATCH_NOINLINE
-static void
-_dispatch_queue_class_barrier_complete(dispatch_queue_t dq, dispatch_qos_t qos,
-		dispatch_wakeup_flags_t flags, dispatch_queue_wakeup_target_t target,
-		uint64_t owned)
-{
-	uint64_t old_state, new_state, enqueue;
-	dispatch_queue_t tq;
-
-	if (target == DISPATCH_QUEUE_WAKEUP_MGR) {
-		tq = &_dispatch_mgr_q;
-		enqueue = DISPATCH_QUEUE_ENQUEUED_ON_MGR;
-	} else if (target) {
-		tq = (target == DISPATCH_QUEUE_WAKEUP_TARGET) ? dq->do_targetq : target;
-		enqueue = DISPATCH_QUEUE_ENQUEUED;
-	} else {
-		tq = NULL;
-		enqueue = 0;
-	}
-
-	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
-		new_state  = _dq_state_merge_qos(old_state - owned, qos);
-		new_state &= ~DISPATCH_QUEUE_DRAIN_UNLOCK_MASK;
-		if (unlikely(_dq_state_is_suspended(old_state))) {
-			new_state |= DLOCK_OWNER_MASK;
-		} else if (enqueue) {
-			new_state |= enqueue;
-		} else if (unlikely(_dq_state_is_dirty(old_state))) {
-			os_atomic_rmw_loop_give_up({
-				// just renew the drain lock with an acquire barrier, to see
-				// what the enqueuer that set DIRTY has done.
-				// the xor generates better assembly as DISPATCH_QUEUE_DIRTY
-				// is already in a register
-				os_atomic_xor2o(dq, dq_state, DISPATCH_QUEUE_DIRTY, acquire);
-				flags |= DISPATCH_WAKEUP_BARRIER_COMPLETE;
-				return dx_wakeup(dq, qos, flags);
-			});
-		} else if (_dq_state_is_base_wlh(old_state)) {
-			new_state &= ~DISPATCH_QUEUE_MAX_QOS_MASK;
-			new_state &= ~DISPATCH_QUEUE_ENQUEUED;
-		} else {
-			new_state &= ~DISPATCH_QUEUE_MAX_QOS_MASK;
-		}
-	});
-	old_state -= owned;
-	dispatch_assert(_dq_state_drain_locked_by_self(old_state));
-	dispatch_assert(!_dq_state_is_enqueued_on_manager(old_state));
-
-
-	if (_dq_state_received_override(old_state)) {
-		// Ensure that the root queue sees that this thread was overridden.
-		_dispatch_set_basepri_override_qos(_dq_state_max_qos(old_state));
-	}
-
-	if (tq) {
-		if (likely((old_state ^ new_state) & enqueue)) {
-			dispatch_assert(_dq_state_is_enqueued(new_state));
-			dispatch_assert(flags & DISPATCH_WAKEUP_CONSUME_2);
-			return _dispatch_queue_push_queue(tq, dq, new_state);
-		}
-#if HAVE_PTHREAD_WORKQUEUE_QOS
-		// <rdar://problem/27694093> when doing sync to async handoff
-		// if the queue received an override we have to forecefully redrive
-		// the same override so that a new stealer is enqueued because
-		// the previous one may be gone already
-		if (_dq_state_should_override(new_state)) {
-			return _dispatch_queue_class_wakeup_with_override(dq, new_state,
-					flags);
-		}
-#endif
-	}
-	if (flags & DISPATCH_WAKEUP_CONSUME_2) {
-		return _dispatch_release_2_tailcall(dq);
-	}
-}
-
-DISPATCH_NOINLINE
-static void
-_dispatch_queue_barrier_complete(dispatch_queue_t dq, dispatch_qos_t qos,
-		dispatch_wakeup_flags_t flags)
-{
-	dispatch_continuation_t dc_tmp, dc_start = NULL, dc_end = NULL;
-	dispatch_queue_wakeup_target_t target = DISPATCH_QUEUE_WAKEUP_NONE;
-	struct dispatch_object_s *dc = NULL;
-	uint64_t owned = DISPATCH_QUEUE_IN_BARRIER +
-			dq->dq_width * DISPATCH_QUEUE_WIDTH_INTERVAL;
-	size_t count = 0;
-
-	dispatch_assert(dx_metatype(dq) == _DISPATCH_QUEUE_TYPE);
-
-	if (dq->dq_items_tail && !DISPATCH_QUEUE_IS_SUSPENDED(dq)) {
-		dc = _dispatch_queue_head(dq);
-		if (!_dispatch_object_is_sync_waiter(dc)) {
-			// not a slow item, needs to wake up
-		} else if (likely(dq->dq_width == 1) ||
-				_dispatch_object_is_barrier(dc)) {
-			// rdar://problem/8290662 "barrier/writer lock transfer"
-			dc_start = dc_end = (dispatch_continuation_t)dc;
-			owned = 0;
-			count = 1;
-			dc = _dispatch_queue_next(dq, dc);
-		} else {
-			// <rdar://problem/10164594> "reader lock transfer"
-			// we must not wake waiters immediately because our right
-			// for dequeuing is granted through holding the full "barrier" width
-			// which a signaled work item could relinquish out from our feet
-			dc_start = (dispatch_continuation_t)dc;
-			do {
-				// no check on width here because concurrent queues
-				// do not respect width for blocked readers, the thread
-				// is already spent anyway
-				dc_end = (dispatch_continuation_t)dc;
-				owned -= DISPATCH_QUEUE_WIDTH_INTERVAL;
-				count++;
-				dc = _dispatch_queue_next(dq, dc);
-			} while (dc && _dispatch_object_is_sync_waiter_non_barrier(dc));
-		}
-
-		if (count) {
-			do {
-				dc_tmp = dc_start;
-				dc_start = dc_start->do_next;
-				_dispatch_sync_waiter_redirect_or_wake(dq, owned, dc_tmp);
-				owned = DISPATCH_SYNC_WAITER_NO_UNLOCK;
-			} while (dc_tmp != dc_end);
-			if (flags & DISPATCH_WAKEUP_CONSUME_2) {
-				return _dispatch_release_2_tailcall(dq);
+			if (unlikely(!_dispatch_queue_try_reserve_sync_width(dq))) {
+				_dispatch_introspection_queue_item_complete(dsc->_as_dc);
+				return _dispatch_queue_push_sync_waiter(dq, dsc);
 			}
-			return;
 		}
-		if (!(flags & DISPATCH_WAKEUP_CONSUME_2)) {
-			_dispatch_retain_2(dq);
-			flags |= DISPATCH_WAKEUP_CONSUME_2;
-		}
-		target = DISPATCH_QUEUE_WAKEUP_TARGET;
 	}
 
-	return _dispatch_queue_class_barrier_complete(dq, qos, flags, target,owned);
+	return _dispatch_sync_waiter_wake(dq, dsc);
 }
 
 #if DISPATCH_COCOA_COMPAT
@@ -3818,90 +3477,27 @@
 }
 #endif
 
-DISPATCH_ALWAYS_INLINE
-static inline uint64_t
-_dispatch_sync_wait_prepare(dispatch_queue_t dq)
-{
-	uint64_t old_state, new_state;
-
-	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, relaxed, {
-		if (_dq_state_is_suspended(old_state) ||
-				!_dq_state_is_base_wlh(old_state)) {
-			os_atomic_rmw_loop_give_up(return old_state);
-		}
-		if (!_dq_state_drain_locked(old_state) ||
-				_dq_state_in_sync_transfer(old_state)) {
-			os_atomic_rmw_loop_give_up(return old_state);
-		}
-		new_state = old_state | DISPATCH_QUEUE_RECEIVED_SYNC_WAIT;
-	});
-	return new_state;
-}
-
-static void
-_dispatch_sync_waiter_compute_wlh(dispatch_queue_t dq,
-		dispatch_sync_context_t dsc)
-{
-	bool needs_locking = _dispatch_queue_is_legacy(dq);
-
-	if (needs_locking) {
-		dsc->dsc_release_storage = true;
-		_dispatch_queue_sidelock_lock(dq);
-	}
-
-	dispatch_queue_t tq = dq->do_targetq;
-	uint64_t dq_state = _dispatch_sync_wait_prepare(tq);
-
-	if (_dq_state_is_suspended(dq_state) ||
-			_dq_state_is_base_anon(dq_state)) {
-		dsc->dsc_release_storage = false;
-		dsc->dc_data = DISPATCH_WLH_ANON;
-	} else if (_dq_state_is_base_wlh(dq_state)) {
-		if (dsc->dsc_release_storage) {
-			_dispatch_queue_retain_storage(tq);
-		}
-		dsc->dc_data = (dispatch_wlh_t)tq;
-	} else {
-		_dispatch_sync_waiter_compute_wlh(tq, dsc);
-	}
-	if (needs_locking) _dispatch_queue_sidelock_unlock(dq);
-}
-
 DISPATCH_NOINLINE
 static void
 _dispatch_sync_wait(dispatch_queue_t top_dq, void *ctxt,
 		dispatch_function_t func, uintptr_t top_dc_flags,
 		dispatch_queue_t dq, uintptr_t dc_flags)
 {
+	uint32_t tid = _dispatch_tid_self();
+	dispatch_qos_t oq_floor = _dispatch_get_basepri_override_qos_floor();
 	pthread_priority_t pp = _dispatch_get_priority();
-	dispatch_tid tid = _dispatch_tid_self();
-	dispatch_qos_t qos;
-	uint64_t dq_state;
-
-	dq_state = _dispatch_sync_wait_prepare(dq);
-	if (unlikely(_dq_state_drain_locked_by(dq_state, tid))) {
-		DISPATCH_CLIENT_CRASH((uintptr_t)dq_state,
-				"dispatch_sync called on queue "
-				"already owned by current thread");
-	}
 
 	struct dispatch_sync_context_s dsc = {
 		.dc_flags    = dc_flags | DISPATCH_OBJ_SYNC_WAITER_BIT,
+		.dc_data     = (void *)(uintptr_t)tid,
 		.dc_other    = top_dq,
 		.dc_priority = pp | _PTHREAD_PRIORITY_ENFORCE_FLAG,
 		.dc_voucher  = DISPATCH_NO_VOUCHER,
 		.dsc_func    = func,
 		.dsc_ctxt    = ctxt,
-		.dsc_waiter  = tid,
+		.dsc_override_qos_floor = oq_floor,
+		.dsc_override_qos = oq_floor,
 	};
-	if (_dq_state_is_suspended(dq_state) ||
-			_dq_state_is_base_anon(dq_state)) {
-		dsc.dc_data = DISPATCH_WLH_ANON;
-	} else if (_dq_state_is_base_wlh(dq_state)) {
-		dsc.dc_data = (dispatch_wlh_t)dq;
-	} else {
-		_dispatch_sync_waiter_compute_wlh(dq, &dsc);
-	}
 #if DISPATCH_COCOA_COMPAT
 	// It's preferred to execute synchronous blocks on the current thread
 	// due to thread-local side effects, etc. However, blocks submitted
@@ -3919,26 +3515,22 @@
 	dsc.dc_ctxt = &dsc;
 #endif
 
-	if (dsc.dc_data == DISPATCH_WLH_ANON) {
-		dsc.dsc_override_qos_floor = dsc.dsc_override_qos =
-				_dispatch_get_basepri_override_qos_floor();
-		qos = _dispatch_qos_from_pp(pp);
-		_dispatch_thread_event_init(&dsc.dsc_event);
-	} else {
-		qos = 0;
+	uint64_t dq_state = os_atomic_load2o(dq, dq_state, relaxed);
+	if (unlikely(_dq_state_drain_locked_by(dq_state, tid))) {
+		DISPATCH_CLIENT_CRASH(dq, "dispatch_sync called on queue "
+				"already owned by current thread");
 	}
-	_dispatch_queue_push_sync_waiter(dq, &dsc, qos);
-	if (dsc.dc_data == DISPATCH_WLH_ANON) {
-		_dispatch_thread_event_wait(&dsc.dsc_event); // acquire
-		_dispatch_thread_event_destroy(&dsc.dsc_event);
-		// If _dispatch_sync_waiter_wake() gave this thread an override,
-		// ensure that the root queue sees it.
-		if (dsc.dsc_override_qos > dsc.dsc_override_qos_floor) {
-			_dispatch_set_basepri_override_qos(dsc.dsc_override_qos);
-		}
-	} else {
-		_dispatch_event_loop_wait_for_ownership(&dsc);
+
+	_dispatch_thread_event_init(&dsc.dsc_event);
+	_dispatch_queue_push_sync_waiter(dq, &dsc);
+	_dispatch_thread_event_wait(&dsc.dsc_event); // acquire
+	_dispatch_thread_event_destroy(&dsc.dsc_event);
+	if (dsc.dsc_override_qos > dsc.dsc_override_qos_floor) {
+		// If we received an override from _dispatch_sync_waiter_wake(),
+		// ensure that the root queue sees that this thread was overridden.
+		_dispatch_set_basepri_override_qos(dsc.dsc_override_qos);
 	}
+
 	_dispatch_introspection_sync_begin(top_dq);
 #if DISPATCH_COCOA_COMPAT
 	if (unlikely(dsc.dsc_func == NULL)) {
@@ -3970,7 +3562,7 @@
 _dispatch_sync_recurse(dispatch_queue_t dq, void *ctxt,
 		dispatch_function_t func, uintptr_t dc_flags)
 {
-	dispatch_tid tid = _dispatch_tid_self();
+	uint32_t tid = _dispatch_tid_self();
 	dispatch_queue_t tq = dq->do_targetq;
 
 	do {
@@ -3995,7 +3587,7 @@
 dispatch_barrier_sync_f(dispatch_queue_t dq, void *ctxt,
 		dispatch_function_t func)
 {
-	dispatch_tid tid = _dispatch_tid_self();
+	uint32_t tid = _dispatch_tid_self();
 
 	// The more correct thing to do would be to merge the qos of the thread
 	// that just acquired the barrier lock into the queue state.
@@ -4014,7 +3606,7 @@
 	if (unlikely(dq->do_targetq->do_targetq)) {
 		return _dispatch_sync_recurse(dq, ctxt, func, DISPATCH_OBJ_BARRIER_BIT);
 	}
-	_dispatch_queue_barrier_sync_invoke_and_complete(dq, ctxt, func);
+	_dispatch_barrier_sync_invoke_and_complete(dq, ctxt, func);
 }
 
 DISPATCH_NOINLINE
@@ -4056,7 +3648,7 @@
 	}
 	// balanced in d_block_sync_invoke or d_block_wait
 	if (os_atomic_cmpxchg2o(dbpd, dbpd_queue, NULL, dq->_as_oq, relaxed)) {
-		_dispatch_retain_2(dq);
+		_dispatch_retain(dq);
 	}
 	if (flags & DISPATCH_BLOCK_BARRIER) {
 		dispatch_barrier_sync_f(dq, work, _dispatch_block_sync_invoke);
@@ -4096,7 +3688,7 @@
 _dispatch_barrier_trysync_or_async_f(dispatch_queue_t dq, void *ctxt,
 		dispatch_function_t func)
 {
-	dispatch_tid tid = _dispatch_tid_self();
+	uint32_t tid = _dispatch_tid_self();
 	if (unlikely(!_dispatch_queue_try_acquire_barrier_sync(dq, tid))) {
 		return _dispatch_barrier_async_detached_f(dq, ctxt, func);
 	}
@@ -4108,7 +3700,7 @@
 _dispatch_trysync_recurse(dispatch_queue_t dq, void *ctxt,
 		dispatch_function_t f, uintptr_t dc_flags)
 {
-	dispatch_tid tid = _dispatch_tid_self();
+	uint32_t tid = _dispatch_tid_self();
 	dispatch_queue_t q, tq = dq->do_targetq;
 
 	for (;;) {
@@ -4143,7 +3735,7 @@
 _dispatch_barrier_trysync_f(dispatch_queue_t dq, void *ctxt,
 		dispatch_function_t f)
 {
-	dispatch_tid tid = _dispatch_tid_self();
+	uint32_t tid = _dispatch_tid_self();
 	if (unlikely(!dq->do_targetq)) {
 		DISPATCH_CLIENT_CRASH(dq, "_dispatch_trsync called on a root queue");
 	}
@@ -4185,13 +3777,16 @@
 {
 	dispatch_queue_wakeup_target_t target = DISPATCH_QUEUE_WAKEUP_NONE;
 
-	if (unlikely(flags & DISPATCH_WAKEUP_BARRIER_COMPLETE)) {
-		return _dispatch_queue_barrier_complete(dq, qos, flags);
-	}
 	if (_dispatch_queue_class_probe(dq)) {
 		target = DISPATCH_QUEUE_WAKEUP_TARGET;
 	}
-	return _dispatch_queue_class_wakeup(dq, qos, flags, target);
+	if (target) {
+		return _dispatch_queue_class_wakeup(dq, qos, flags, target);
+	} else if (qos) {
+		return _dispatch_queue_class_override_drainer(dq, qos, flags);
+	} else if (flags & DISPATCH_WAKEUP_CONSUME) {
+		return _dispatch_release_tailcall(dq);
+	}
 }
 
 #if DISPATCH_COCOA_COMPAT
@@ -4237,16 +3832,6 @@
 }
 #endif // DISPATCH_COCOA_COMPAT
 
-DISPATCH_ALWAYS_INLINE
-static inline dispatch_qos_t
-_dispatch_runloop_queue_reset_max_qos(dispatch_queue_class_t dqu)
-{
-	uint64_t old_state, clear_bits = DISPATCH_QUEUE_MAX_QOS_MASK |
-			DISPATCH_QUEUE_RECEIVED_OVERRIDE;
-	old_state = os_atomic_and_orig2o(dqu._dq, dq_state, ~clear_bits, relaxed);
-	return _dq_state_max_qos(old_state);
-}
-
 void
 _dispatch_runloop_queue_wakeup(dispatch_queue_t dq, dispatch_qos_t qos,
 		dispatch_wakeup_flags_t flags)
@@ -4257,14 +3842,14 @@
 		return _dispatch_queue_wakeup(dq, qos, flags);
 	}
 
-	if (flags & DISPATCH_WAKEUP_MAKE_DIRTY) {
+	if (flags & DISPATCH_WAKEUP_FLUSH) {
 		os_atomic_or2o(dq, dq_state, DISPATCH_QUEUE_DIRTY, release);
 	}
 	if (_dispatch_queue_class_probe(dq)) {
 		return _dispatch_runloop_queue_poke(dq, qos, flags);
 	}
 
-	qos = _dispatch_runloop_queue_reset_max_qos(dq);
+	qos = _dispatch_queue_reset_max_qos(dq);
 	if (qos) {
 		mach_port_t owner = DISPATCH_QUEUE_DRAIN_OWNER(dq);
 		if (_dispatch_queue_class_probe(dq)) {
@@ -4273,8 +3858,8 @@
 		_dispatch_thread_override_end(owner, dq);
 		return;
 	}
-	if (flags & DISPATCH_WAKEUP_CONSUME_2) {
-		return _dispatch_release_2_tailcall(dq);
+	if (flags & DISPATCH_WAKEUP_CONSUME) {
+		return _dispatch_release_tailcall(dq);
 	}
 #else
 	return _dispatch_queue_wakeup(dq, qos, flags);
@@ -4333,7 +3918,7 @@
 _dispatch_runloop_queue_poke(dispatch_queue_t dq, dispatch_qos_t qos,
 		dispatch_wakeup_flags_t flags)
 {
-	// it's not useful to handle WAKEUP_MAKE_DIRTY because mach_msg() will have
+	// it's not useful to handle WAKEUP_FLUSH because mach_msg() will have
 	// a release barrier and that when runloop queues stop being thread-bound
 	// they have a non optional wake-up to start being a "normal" queue
 	// either in _dispatch_runloop_queue_xref_dispose,
@@ -4363,8 +3948,8 @@
 	}
 no_change:
 	_dispatch_runloop_queue_class_poke(dq);
-	if (flags & DISPATCH_WAKEUP_CONSUME_2) {
-		return _dispatch_release_2_tailcall(dq);
+	if (flags & DISPATCH_WAKEUP_CONSUME) {
+		return _dispatch_release_tailcall(dq);
 	}
 }
 #endif
@@ -4459,7 +4044,7 @@
 	}
 #endif
 	do {
-		_dispatch_retain(dq); // released in _dispatch_worker_thread
+		_dispatch_retain(dq);
 		while ((r = pthread_create(pthr, attr, _dispatch_worker_thread, dq))) {
 			if (r != EAGAIN) {
 				(void)dispatch_assume_zero(r);
@@ -4513,44 +4098,15 @@
 static void
 _dispatch_return_to_kernel(void)
 {
-	if (unlikely(_dispatch_get_wlh() == DISPATCH_WLH_ANON)) {
+	if (unlikely(_dispatch_get_wlh() == DISPATCH_WLH_GLOBAL)) {
 		_dispatch_clear_return_to_kernel();
 	} else {
 		_dispatch_event_loop_drain(KEVENT_FLAG_IMMEDIATE);
 	}
 }
 
-void
-_dispatch_poll_for_events_4launchd(void)
-{
-#if DISPATCH_USE_KEVENT_WORKQUEUE
-	if (_dispatch_get_wlh()) {
-		dispatch_assert(_dispatch_deferred_items_get()->ddi_wlh_servicing);
-		_dispatch_event_loop_drain(KEVENT_FLAG_IMMEDIATE);
-	}
-#endif
-}
-
 #if HAVE_PTHREAD_WORKQUEUE_NARROWING
-static os_atomic(uint64_t) _dispatch_narrowing_deadlines[DISPATCH_QOS_MAX];
-#if !DISPATCH_TIME_UNIT_USES_NANOSECONDS
-static uint64_t _dispatch_narrow_check_interval_cache;
-#endif
-
-DISPATCH_ALWAYS_INLINE
-static inline uint64_t
-_dispatch_narrow_check_interval(void)
-{
-#if DISPATCH_TIME_UNIT_USES_NANOSECONDS
-	return 50 * NSEC_PER_MSEC;
-#else
-	if (_dispatch_narrow_check_interval_cache == 0) {
-		_dispatch_narrow_check_interval_cache =
-				_dispatch_time_nano2mach(50 * NSEC_PER_MSEC);
-	}
-	return _dispatch_narrow_check_interval_cache;
-#endif
-}
+static os_atomic(uint64_t) _dispatch_narrowing_deadlines[DISPATCH_QOS_MAX - 1];
 
 DISPATCH_ALWAYS_INLINE
 static inline void
@@ -4560,7 +4116,7 @@
 	if (_dispatch_priority_qos(pri) &&
 			!(pri & DISPATCH_PRIORITY_FLAG_OVERCOMMIT)) {
 		dic->dic_next_narrow_check = _dispatch_approximate_time() +
-				_dispatch_narrow_check_interval();
+				DISPATCH_NARROW_CHECK_INTERVAL;
 	}
 }
 
@@ -4571,13 +4127,9 @@
 {
 	if (dic->dic_next_narrow_check != DISPATCH_THREAD_IS_NARROWING) {
 		pthread_priority_t pp = _dispatch_get_priority();
-		dispatch_qos_t qos = _dispatch_qos_from_pp(pp);
-		if (unlikely(!qos || qos > countof(_dispatch_narrowing_deadlines))) {
-			DISPATCH_CLIENT_CRASH(pp, "Thread QoS corruption");
-		}
-		size_t idx = qos - 1; // no entry needed for DISPATCH_QOS_UNSPECIFIED
+		size_t idx = _dispatch_qos_from_pp(pp) - 1;
 		os_atomic(uint64_t) *deadline = &_dispatch_narrowing_deadlines[idx];
-		uint64_t oldval, newval = now + _dispatch_narrow_check_interval();
+		uint64_t oldval, newval = now + DISPATCH_NARROW_CHECK_INTERVAL;
 
 		dic->dic_next_narrow_check = newval;
 		os_atomic_rmw_loop(deadline, oldval, newval, relaxed, {
@@ -4657,8 +4209,6 @@
 		// but width can change while draining barrier work items, so we only
 		// convert to `dq->dq_width * WIDTH_INTERVAL` when we drop `IN_BARRIER`
 		owned = DISPATCH_QUEUE_IN_BARRIER;
-	} else {
-		owned &= DISPATCH_QUEUE_WIDTH_MASK;
 	}
 
 	dc = _dispatch_queue_head(dq);
@@ -4669,9 +4219,6 @@
 		if (unlikely(dic->dic_deferred)) {
 			goto out_with_deferred_compute_owned;
 		}
-		if (unlikely(_dispatch_needs_to_return_to_kernel())) {
-			_dispatch_return_to_kernel();
-		}
 		if (unlikely(!dc)) {
 			if (!dq->dq_items_tail) {
 				break;
@@ -4684,6 +4231,9 @@
 		if (unlikely(_dispatch_queue_drain_should_narrow(dic))) {
 			break;
 		}
+		if (unlikely(_dispatch_needs_to_return_to_kernel())) {
+			_dispatch_return_to_kernel();
+		}
 
 first_iteration:
 		dq_state = os_atomic_load(&dq->dq_state, relaxed);
@@ -4728,8 +4278,7 @@
 			next_dc = _dispatch_queue_next(dq, dc);
 			if (_dispatch_object_is_sync_waiter(dc)) {
 				owned -= DISPATCH_QUEUE_WIDTH_INTERVAL;
-				_dispatch_sync_waiter_redirect_or_wake(dq,
-						DISPATCH_SYNC_WAITER_NO_UNLOCK, dc);
+				_dispatch_sync_waiter_redirect_or_wake(dq, dc);
 				continue;
 			}
 
@@ -4750,13 +4299,12 @@
 	if (dc) {
 		owned = _dispatch_queue_adjust_owned(dq, owned, dc);
 	}
-	*owned_ptr &= DISPATCH_QUEUE_ENQUEUED | DISPATCH_QUEUE_ENQUEUED_ON_MGR;
-	*owned_ptr |= owned;
+	*owned_ptr = owned;
 	_dispatch_thread_frame_pop(&dtf);
 	return dc ? dq->do_targetq : NULL;
 
 out_with_no_width:
-	*owned_ptr &= DISPATCH_QUEUE_ENQUEUED | DISPATCH_QUEUE_ENQUEUED_ON_MGR;
+	*owned_ptr = 0;
 	_dispatch_thread_frame_pop(&dtf);
 	return DISPATCH_QUEUE_WAKEUP_WAIT_FOR_EVENT;
 
@@ -4773,8 +4321,7 @@
 		}
 	}
 out_with_deferred:
-	*owned_ptr &= DISPATCH_QUEUE_ENQUEUED | DISPATCH_QUEUE_ENQUEUED_ON_MGR;
-	*owned_ptr |= owned;
+	*owned_ptr = owned;
 	if (unlikely(flags & DISPATCH_INVOKE_DISALLOW_SYNC_WAITERS)) {
 		DISPATCH_INTERNAL_CRASH(dc,
 				"Deferred continuation on source, mach channel or mgr");
@@ -4852,10 +4399,9 @@
 		DISPATCH_CLIENT_CRASH(0, "_dispatch_main_queue_callback_4CF called"
 				" after dispatch_main()");
 	}
-	uint64_t dq_state = os_atomic_load2o(dq, dq_state, relaxed);
-	if (unlikely(!_dq_state_drain_locked_by_self(dq_state))) {
-		DISPATCH_CLIENT_CRASH((uintptr_t)dq_state,
-				"_dispatch_main_queue_callback_4CF called"
+	mach_port_t owner = DISPATCH_QUEUE_DRAIN_OWNER(dq);
+	if (slowpath(owner != _dispatch_tid_self())) {
+		DISPATCH_CLIENT_CRASH(owner, "_dispatch_main_queue_callback_4CF called"
 				" from the wrong thread");
 	}
 
@@ -4864,7 +4410,7 @@
 
 	// <rdar://problem/23256682> hide the frame chaining when CFRunLoop
 	// drains the main runloop, as this should not be observable that way
-	_dispatch_adopt_wlh_anon();
+	_dispatch_set_wlh(dq->dq_wlh);
 	_dispatch_thread_frame_push_and_rebase(&dtf, dq, NULL);
 
 	pthread_priority_t pp = _dispatch_get_priority();
@@ -4886,6 +4432,8 @@
 		_dispatch_continuation_pop_inline(dc, &dic, DISPATCH_INVOKE_NONE, dq);
 	} while ((dc = next_dc));
 
+	// runloop based queues use their port for the queue PUBLISH pattern
+	// so this raw call to dx_wakeup(0) is valid
 	dx_wakeup(dq, 0, 0);
 	_dispatch_voucher_debug("main queue restore", voucher);
 	_dispatch_reset_basepri(old_dbp);
@@ -4905,7 +4453,7 @@
 	}
 	_dispatch_perfmon_start_notrace();
 	dispatch_thread_frame_s dtf;
-	bool should_reset_wlh = _dispatch_adopt_wlh_anon_recurse();
+	_dispatch_set_wlh(dq->dq_wlh);
 	_dispatch_thread_frame_push(&dtf, dq);
 	pthread_priority_t pp = _dispatch_get_priority();
 	dispatch_priority_t pri = _dispatch_priority_from_pp(pp);
@@ -4920,6 +4468,8 @@
 	_dispatch_continuation_pop_inline(dc, &dic, DISPATCH_INVOKE_NONE, dq);
 
 	if (!next_dc) {
+		// runloop based queues use their port for the queue PUBLISH pattern
+		// so this raw call to dx_wakeup(0) is valid
 		dx_wakeup(dq, 0, 0);
 	}
 
@@ -4928,13 +4478,80 @@
 	_dispatch_reset_basepri_override();
 	_dispatch_reset_priority_and_voucher(pp, voucher);
 	_dispatch_thread_frame_pop(&dtf);
-	if (should_reset_wlh) _dispatch_reset_wlh();
+	_dispatch_reset_wlh();
 	_dispatch_force_cache_cleanup();
 	_dispatch_perfmon_end_notrace();
 	return next_dc;
 }
 #endif
 
+DISPATCH_NOINLINE
+void
+_dispatch_try_lock_transfer_or_wakeup(dispatch_queue_t dq)
+{
+	dispatch_continuation_t dc_tmp, dc_start = NULL, dc_end = NULL;
+	struct dispatch_object_s *dc = NULL;
+	uint64_t owned;
+	size_t count = 0;
+
+	owned  = DISPATCH_QUEUE_IN_BARRIER;
+	owned += dq->dq_width * DISPATCH_QUEUE_WIDTH_INTERVAL;
+attempt_running_slow_head:
+	if (dq->dq_items_tail && !DISPATCH_QUEUE_IS_SUSPENDED(dq)) {
+		dc = _dispatch_queue_head(dq);
+		if (!_dispatch_object_is_sync_waiter(dc)) {
+			// not a slow item, needs to wake up
+		} else if (likely(dq->dq_width == 1) ||
+				_dispatch_object_is_barrier(dc)) {
+			// rdar://problem/8290662 "barrier/writer lock transfer"
+			dc_start = dc_end = (dispatch_continuation_t)dc;
+			owned = 0;
+			count = 1;
+			dc = _dispatch_queue_next(dq, dc);
+		} else {
+			// <rdar://problem/10164594> "reader lock transfer"
+			// we must not wake waiters immediately because our right
+			// for dequeuing is granted through holding the full "barrier" width
+			// which a signaled work item could relinquish out from our feet
+			dc_start = (dispatch_continuation_t)dc;
+			do {
+				// no check on width here because concurrent queues
+				// do not respect width for blocked readers, the thread
+				// is already spent anyway
+				dc_end = (dispatch_continuation_t)dc;
+				owned -= DISPATCH_QUEUE_WIDTH_INTERVAL;
+				count++;
+				dc = _dispatch_queue_next(dq, dc);
+			} while (dc && _dispatch_object_is_sync_waiter_non_barrier(dc));
+		}
+
+		if (count) {
+			_dispatch_queue_drain_transfer_lock(dq, owned, dc_start);
+			do {
+				dc_tmp = dc_start;
+				dc_start = dc_start->do_next;
+				_dispatch_sync_waiter_redirect_or_wake(dq, dc_tmp);
+			} while (dc_tmp != dc_end);
+			return;
+		}
+	}
+
+	if (dc || dx_metatype(dq) != _DISPATCH_QUEUE_TYPE) {
+		// <rdar://problem/23336992> the following wakeup is needed for sources
+		// or mach channels: when ds_pending_data is set at the same time
+		// as a trysync_f happens, lock transfer code above doesn't know about
+		// ds_pending_data or the wakeup logic, but lock transfer is useless
+		// for sources and mach channels in the first place.
+		owned = _dispatch_queue_adjust_owned(dq, owned, dc);
+		_dispatch_queue_drain_unlock(dq, owned);
+		return dx_wakeup(dq, 0, DISPATCH_WAKEUP_WAITER_HANDOFF);
+	} else if (unlikely(!_dispatch_queue_drain_try_unlock(dq, owned, true))) {
+		// someone enqueued a slow item at the head
+		// looping may be its last chance
+		goto attempt_running_slow_head;
+	}
+}
+
 void
 _dispatch_mgr_queue_drain(void)
 {
@@ -4967,37 +4584,96 @@
 #pragma mark dispatch_queue_invoke
 
 void
-_dispatch_queue_drain_sync_waiter(dispatch_queue_t dq,
+_dispatch_queue_drain_deferred_invoke(dispatch_queue_t dq,
 		dispatch_invoke_context_t dic, dispatch_invoke_flags_t flags,
-		uint64_t owned)
+		uint64_t to_unlock)
 {
 	struct dispatch_object_s *dc = dic->dic_deferred;
-	dispatch_assert(_dispatch_object_is_sync_waiter(dc));
-	dic->dic_deferred = NULL;
-	if (flags & DISPATCH_INVOKE_WLH) {
-		// Leave the enqueued bit in place, completion of the last sync waiter
-		// in the handoff chain is responsible for dequeuing
-		//
-		// We currently have a +2 to consume, but we need to keep a +1
-		// for the thread request
-		dispatch_assert(_dq_state_is_enqueued_on_target(owned));
-		dispatch_assert(!_dq_state_is_enqueued_on_manager(owned));
-		owned &= ~DISPATCH_QUEUE_ENQUEUED;
-		_dispatch_release_no_dispose(dq);
-	} else {
-		// The sync waiter must own a reference
-		_dispatch_release_2_no_dispose(dq);
+	if (_dispatch_object_is_sync_waiter(dc)) {
+		dispatch_assert(to_unlock == 0);
+		dic->dic_deferred = NULL;
+		_dispatch_queue_drain_transfer_lock(dq, to_unlock, dc);
+		_dispatch_sync_waiter_redirect_or_wake(dq, dc);
+		return _dispatch_release_tailcall(dq);
 	}
-	return _dispatch_sync_waiter_redirect_or_wake(dq, owned, dc);
+
+	bool should_defer_again = false, should_pend_queue = true;
+	uint64_t old_state, new_state;
+
+	if (_dispatch_get_current_queue()->do_targetq) {
+		should_defer_again = true;
+		should_pend_queue = false;
+	}
+
+	if (dq->dq_width > 1) {
+		should_pend_queue = false;
+	} else if (should_pend_queue) {
+		dispatch_assert(to_unlock ==
+				DISPATCH_QUEUE_WIDTH_INTERVAL + DISPATCH_QUEUE_IN_BARRIER);
+		os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release,{
+			new_state = old_state;
+			if (_dq_state_has_waiters(old_state) ||
+					_dq_state_is_enqueued(old_state)) {
+				os_atomic_rmw_loop_give_up(break);
+			}
+			new_state += DISPATCH_QUEUE_DRAIN_PENDED;
+			new_state -= DISPATCH_QUEUE_IN_BARRIER;
+			new_state -= DISPATCH_QUEUE_WIDTH_INTERVAL;
+		});
+		should_pend_queue = (new_state & DISPATCH_QUEUE_DRAIN_PENDED);
+	}
+
+	if (!should_pend_queue) {
+		if (to_unlock & DISPATCH_QUEUE_IN_BARRIER) {
+			_dispatch_try_lock_transfer_or_wakeup(dq);
+			_dispatch_release(dq);
+		} else if (to_unlock) {
+			_dispatch_queue_drain_unlock(dq, to_unlock);
+			dx_wakeup(dq, 0, DISPATCH_WAKEUP_CONSUME);
+		} else {
+			_dispatch_release(dq);
+		}
+		dq = NULL;
+	}
+
+	if (!should_defer_again) {
+		dic->dic_deferred = NULL;
+		return dx_invoke(dc, dic, flags & _DISPATCH_INVOKE_PROPAGATE_MASK);
+	}
+
+	if (dq) {
+		uint32_t self = _dispatch_tid_self();
+		os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release,{
+			new_state = old_state;
+			if (!_dq_state_drain_pended(old_state) ||
+					_dq_state_drain_owner(old_state) != self) {
+				os_atomic_rmw_loop_give_up({
+					// We may have been overridden, so inform the root queue
+					_dispatch_set_basepri_override_qos(
+							_dq_state_max_qos(old_state));
+					return _dispatch_release_tailcall(dq);
+				});
+			}
+			new_state = DISPATCH_QUEUE_DRAIN_UNLOCK(new_state);
+		});
+		if (_dq_state_received_override(old_state)) {
+			// Ensure that the root queue sees that this thread was overridden.
+			_dispatch_set_basepri_override_qos(_dq_state_max_qos(old_state));
+		}
+		return dx_invoke(dq, dic, flags | DISPATCH_INVOKE_STEALING);
+	}
 }
 
 void
-_dispatch_queue_finalize_activation(dispatch_queue_t dq,
-		DISPATCH_UNUSED bool *allow_resume)
+_dispatch_queue_finalize_activation(dispatch_queue_t dq)
 {
 	dispatch_queue_t tq = dq->do_targetq;
 	_dispatch_queue_priority_inherit_from_target(dq, tq);
-	_dispatch_queue_inherit_wlh_from_target(dq, tq);
+	_dispatch_queue_atomic_flags_set(tq, DQF_TARGETED);
+	if (!dq->dq_wlh) {
+		dispatch_wlh_t wlh = _dispatch_queue_class_compute_wlh(dq);
+		if (wlh) _dispatch_queue_class_record_wlh_hierarchy(dq, wlh);
+	}
 }
 
 DISPATCH_ALWAYS_INLINE
@@ -5024,7 +4700,7 @@
 _dispatch_queue_invoke(dispatch_queue_t dq, dispatch_invoke_context_t dic,
 		dispatch_invoke_flags_t flags)
 {
-	_dispatch_queue_class_invoke(dq, dic, flags, 0, dispatch_queue_invoke2);
+	_dispatch_queue_class_invoke(dq, dic, flags, dispatch_queue_invoke2);
 }
 
 #pragma mark -
@@ -5043,6 +4719,7 @@
 
 	dou._do = dc->dc_data;
 	old_dp = _dispatch_root_queue_identity_assume(assumed_rq);
+	flags |= DISPATCH_INVOKE_OVERRIDING;
 	if (dc_type(dc) == DISPATCH_CONTINUATION_TYPE(OVERRIDE_STEALING)) {
 		flags |= DISPATCH_INVOKE_STEALING;
 	} else {
@@ -5061,6 +4738,19 @@
 	_dispatch_queue_set_current(old_rq);
 }
 
+#if DISPATCH_USE_KEVENT_WORKQUEUE
+DISPATCH_ALWAYS_INLINE
+static inline dispatch_qos_t
+_dispatch_qos_root_queue_push_wlh(dispatch_queue_t rq, dispatch_qos_t qos)
+{
+	// for root queues, the override is the guaranteed minimum override level
+	if (qos > _dispatch_priority_override_qos(rq->dq_priority)) {
+		return qos;
+	}
+	return _dispatch_priority_qos(rq->dq_priority);
+}
+#endif // DISPATCH_USE_KEVENT_WORKQUEUE
+
 DISPATCH_ALWAYS_INLINE
 static inline bool
 _dispatch_root_queue_push_needs_override(dispatch_queue_t rq,
@@ -5120,7 +4810,7 @@
 	dispatch_continuation_t dc = _dispatch_continuation_alloc();
 
 	dc->do_vtable = DC_VTABLE(OVERRIDE_STEALING);
-	_dispatch_retain_2(dq);
+	_dispatch_retain(dq);
 	dc->dc_func = NULL;
 	dc->dc_ctxt = dc;
 	dc->dc_other = orig_rq;
@@ -5131,19 +4821,27 @@
 }
 
 DISPATCH_NOINLINE
-static void
-_dispatch_queue_class_wakeup_with_override_slow(dispatch_queue_t dq,
-		uint64_t dq_state, dispatch_wakeup_flags_t flags)
+void
+_dispatch_queue_class_wakeup_with_override(dispatch_queue_t dq,
+		dispatch_qos_t qos, dispatch_wakeup_flags_t flags, uint64_t dq_state)
 {
-	dispatch_qos_t oqos, qos = _dq_state_max_qos(dq_state);
+	mach_port_t owner = _dq_state_drain_owner(dq_state);
 	dispatch_queue_t tq;
+	dispatch_qos_t oqos;
 	bool locked;
 
-	if (_dq_state_is_base_anon(dq_state)) {
-		mach_port_t owner = _dq_state_drain_owner(dq_state);
-		if (owner) {
-			(void)_dispatch_wqthread_override_start_check_owner(owner, qos,
+	if (_dq_state_is_suspended(dq_state)) {
+		goto out;
+	}
+
+	if (owner) {
+		int rc = _dispatch_wqthread_override_start_check_owner(owner, qos,
 				&dq->dq_state_lock);
+		// EPERM means the target of the override is not a work queue thread
+		// and could be a thread-bound queue such as the main queue.
+		// When that happens we must get to that queue and wake it up if we
+		// want the override to be appplied and take effect.
+		if (rc != EPERM) {
 			goto out;
 		}
 	}
@@ -5205,10 +4903,12 @@
 apply_again:
 	if (dx_type(tq) == DISPATCH_QUEUE_GLOBAL_ROOT_TYPE) {
 		if (_dispatch_root_queue_push_queue_override_needed(tq, qos)) {
-			_dispatch_root_queue_push_override_stealer(tq, dq, qos);
+			_dispatch_root_queue_push_queue_override(tq, dq, qos);
 		}
+	} else if (flags & DISPATCH_WAKEUP_WAITER_HANDOFF) {
+		dx_wakeup(tq, qos, flags);
 	} else if (_dispatch_queue_need_override(tq, qos)) {
-		dx_wakeup(tq, qos, 0);
+		dx_wakeup(tq, qos, DISPATCH_WAKEUP_OVERRIDING);
 	}
 	while (unlikely(locked && !_dispatch_queue_sidelock_tryunlock(dq))) {
 		// rdar://problem/24081326
@@ -5228,62 +4928,145 @@
 	}
 
 out:
-	if (flags & DISPATCH_WAKEUP_CONSUME_2) {
-		return _dispatch_release_2_tailcall(dq);
+	if (flags & DISPATCH_WAKEUP_CONSUME) {
+		return _dispatch_release_tailcall(dq);
 	}
 }
-
-
-DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_queue_class_wakeup_with_override(dispatch_queue_t dq,
-		uint64_t dq_state, dispatch_wakeup_flags_t flags)
-{
-	dispatch_assert(_dq_state_should_override(dq_state));
-
-	return _dispatch_queue_class_wakeup_with_override_slow(dq, dq_state, flags);
-}
 #endif // HAVE_PTHREAD_WORKQUEUE_QOS
 
 DISPATCH_NOINLINE
 void
-_dispatch_root_queue_push(dispatch_queue_t rq, dispatch_object_t dou,
+_dispatch_queue_class_override_drainer(dispatch_queue_t dq,
+		dispatch_qos_t qos, dispatch_wakeup_flags_t flags)
+{
+#if HAVE_PTHREAD_WORKQUEUE_QOS
+	uint64_t old_state, new_state;
+
+	//
+	// Someone is trying to override the last work item of the queue.
+	//
+	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, relaxed, {
+		if (!_dq_state_drain_locked(old_state) &&
+				!_dq_state_is_dirty(old_state)) {
+			os_atomic_rmw_loop_give_up(goto done);
+		}
+		new_state = _dq_state_merge_qos(old_state, qos);
+		if (new_state == old_state) {
+			os_atomic_rmw_loop_give_up(goto done);
+		}
+	});
+	if (_dq_state_drain_locked(new_state)) {
+		return _dispatch_queue_class_wakeup_with_override(dq, qos,
+				flags, new_state);
+	}
+
+done:
+#else
+	(void)qos;
+#endif // HAVE_PTHREAD_WORKQUEUE_QOS
+	if (flags & DISPATCH_WAKEUP_CONSUME) {
+		return _dispatch_release_tailcall(dq);
+	}
+}
+
+#if HAVE_PTHREAD_WORKQUEUE_QOS
+DISPATCH_NOINLINE
+static void
+_dispatch_root_queue_push_queue_override(dispatch_queue_t rq,
+		dispatch_queue_class_t dqu, dispatch_qos_t qos)
+{
+	// thread bound queues always have an owner set, so should never reach
+	// this codepath (see _dispatch_queue_class_wakeup_with_override).
+	dispatch_assert(!_dispatch_queue_is_thread_bound(dqu._dq));
+	_dispatch_root_queue_push_override_stealer(rq, dqu._dq, qos);
+}
+#endif // HAVE_PTHREAD_WORKQUEUE_QOS
+
+#if DISPATCH_USE_KEVENT_WORKQUEUE
+DISPATCH_ALWAYS_INLINE
+static inline void
+_dispatch_root_queue_push_queue(dispatch_queue_t rq, dispatch_queue_class_t dqu,
+		dispatch_qos_t qos)
+{
+	// thread bound queues aren't woken up on root queues
+	dispatch_assert(!_dispatch_queue_is_thread_bound(dqu._dq));
+	if (likely(_dispatch_root_queue_allows_wlh_for_queue(rq, dqu._dq))) {
+		dispatch_qos_t wlh_qos;
+		wlh_qos = _dispatch_qos_root_queue_push_wlh(rq, qos);
+	}
+#if HAVE_PTHREAD_WORKQUEUE_QOS
+	if (_dispatch_root_queue_push_needs_override(rq, qos)) {
+		return _dispatch_root_queue_push_override(rq, dqu._dq->_as_do, qos);
+	}
+#endif
+	_dispatch_root_queue_push_inline(rq, dqu._dq, dqu._dq, 1);
+}
+
+DISPATCH_NOINLINE
+static void
+_dispatch_root_queue_push_try_stash(dispatch_queue_t rq,
+		dispatch_queue_class_t dqu, dispatch_qos_t qos,
+		dispatch_deferred_items_t ddi)
+{
+	dispatch_wlh_t cur_wlh = _dispatch_get_wlh();
+	dispatch_wlh_t wlh = _dispatch_root_queue_wlh_for_queue(rq, dqu);
+	dispatch_queue_t old_dq = ddi->ddi_stashed_dq;
+	dispatch_priority_t rq_overcommit;
+	rq_overcommit = rq->dq_priority & DISPATCH_PRIORITY_FLAG_OVERCOMMIT;
+
+	if (cur_wlh != DISPATCH_WLH_GLOBAL) {
+		if (cur_wlh != (dispatch_wlh_t)dqu._dq) {
+			goto out;
+		}
+		dispatch_assert(old_dq == NULL);
+	}
+
+	if (likely(!old_dq || rq_overcommit)) {
+		dispatch_queue_t old_rq = ddi->ddi_stashed_rq;
+		dispatch_priority_t old_pri = ddi->ddi_stashed_pri;
+		ddi->ddi_stashed_rq = rq;
+		ddi->ddi_stashed_dq = dqu._dq;
+		ddi->ddi_stashed_pri = _dispatch_priority_make(qos, 0) | rq_overcommit;
+		_dispatch_debug("wlh[%p]: deferring item %p, rq %p, pri 0x%x",
+				cur_wlh, dqu._dq, rq, ddi->ddi_stashed_pri);
+		if (likely(!old_dq)) {
+			return;
+		}
+		// push the previously stashed item
+		qos = _dispatch_priority_qos(old_pri);
+		rq = old_rq;
+		dqu._dq = old_dq;
+	}
+
+out:
+	if (cur_wlh != DISPATCH_WLH_GLOBAL) {
+		_dispatch_debug("wlh[%p]: not deferring item %p with wlh %p, rq %p",
+				cur_wlh, dqu._dq, wlh, rq);
+	}
+	_dispatch_root_queue_push_queue(rq, dqu, qos);
+}
+#endif // DISPATCH_USE_KEVENT_WORKQUEUE
+
+DISPATCH_NOINLINE
+void
+_dispatch_root_queue_push(dispatch_queue_t dq, dispatch_object_t dou,
 		dispatch_qos_t qos)
 {
 #if DISPATCH_USE_KEVENT_WORKQUEUE
-	dispatch_deferred_items_t ddi = _dispatch_deferred_items_get();
-	if (unlikely(ddi && ddi->ddi_can_stash)) {
-		dispatch_object_t old_dou = ddi->ddi_stashed_dou;
-		dispatch_priority_t rq_overcommit;
-		rq_overcommit = rq->dq_priority & DISPATCH_PRIORITY_FLAG_OVERCOMMIT;
-
-		if (likely(!old_dou._do || rq_overcommit)) {
-			dispatch_queue_t old_rq = ddi->ddi_stashed_rq;
-			dispatch_qos_t old_qos = ddi->ddi_stashed_qos;
-			ddi->ddi_stashed_rq = rq;
-			ddi->ddi_stashed_dou = dou;
-			ddi->ddi_stashed_qos = qos;
-			_dispatch_debug("deferring item %p, rq %p, qos %d",
-					dou._do, rq, qos);
-			if (rq_overcommit) {
-				ddi->ddi_can_stash = false;
-			}
-			if (likely(!old_dou._do)) {
-				return;
-			}
-			// push the previously stashed item
-			qos = old_qos;
-			rq = old_rq;
-			dou = old_dou;
+	if (_dispatch_object_has_vtable(dou) && dx_vtable(dou._do)->do_push) {
+		dispatch_deferred_items_t ddi = _dispatch_deferred_items_get();
+		if (unlikely(ddi && ddi->ddi_stashed_pri != DISPATCH_PRIORITY_NOSTASH)){
+			return _dispatch_root_queue_push_try_stash(dq, dou._dq, qos, ddi);
 		}
+		return _dispatch_root_queue_push_queue(dq, dou._dq, qos);
 	}
 #endif
 #if HAVE_PTHREAD_WORKQUEUE_QOS
-	if (_dispatch_root_queue_push_needs_override(rq, qos)) {
-		return _dispatch_root_queue_push_override(rq, dou, qos);
+	if (_dispatch_root_queue_push_needs_override(dq, qos)) {
+		return _dispatch_root_queue_push_override(dq, dou, qos);
 	}
 #endif
-	_dispatch_root_queue_push_inline(rq, dou, dou, 1);
+	_dispatch_root_queue_push_inline(dq, dou, dou, 1);
 }
 
 void
@@ -5292,10 +5075,10 @@
 {
 	if (!(flags & DISPATCH_WAKEUP_BLOCK_WAIT)) {
 		DISPATCH_INTERNAL_CRASH(dq->dq_priority,
-				"Don't try to wake up or override a root queue");
+				"Trying to wake up or override a root queue");
 	}
-	if (flags & DISPATCH_WAKEUP_CONSUME_2) {
-		return _dispatch_release_2_tailcall(dq);
+	if (flags & DISPATCH_WAKEUP_CONSUME) {
+		return _dispatch_release_tailcall(dq);
 	}
 }
 
@@ -5309,179 +5092,150 @@
 
 DISPATCH_NOINLINE
 void
+_dispatch_queue_class_wakeup_enqueue(dispatch_queue_t dq, dispatch_qos_t qos,
+		dispatch_wakeup_flags_t flags, dispatch_queue_wakeup_target_t target)
+{
+	dispatch_queue_t tq;
+
+	if (!(flags & DISPATCH_WAKEUP_CONSUME)) {
+		_dispatch_retain(dq);
+	}
+	if (target == DISPATCH_QUEUE_WAKEUP_TARGET) {
+		// try_become_enqueuer has no acquire barrier, as the last block
+		// of a queue asyncing to that queue is not an uncommon pattern
+		// and in that case the acquire is completely useless
+		//
+		// so instead use depdendency ordering to read the targetq pointer.
+		os_atomic_thread_fence(dependency);
+		tq = os_atomic_load_with_dependency_on2o(dq, do_targetq, (long)qos);
+	} else {
+		tq = target;
+	}
+	return dx_push(tq, dq, qos);
+}
+
+DISPATCH_ALWAYS_INLINE
+static void
+_dispatch_queue_class_wakeup_finish(dispatch_queue_t dq, dispatch_qos_t qos,
+		dispatch_wakeup_flags_t flags, dispatch_queue_wakeup_target_t target,
+		uint64_t old_state, uint64_t new_state)
+{
+	dispatch_assert(target != DISPATCH_QUEUE_WAKEUP_NONE);
+	dispatch_assert(target != DISPATCH_QUEUE_WAKEUP_WAIT_FOR_EVENT);
+
+	if ((old_state ^ new_state) & DISPATCH_QUEUE_MAX_QOS_MASK) {
+		flags |= DISPATCH_WAKEUP_OVERRIDING;
+	} else {
+		flags &= ~(dispatch_wakeup_flags_t)DISPATCH_WAKEUP_OVERRIDING;
+		qos = _dq_state_max_qos(new_state);
+	}
+	if ((old_state ^ new_state) & DISPATCH_QUEUE_ENQUEUED) {
+		return _dispatch_queue_class_wakeup_enqueue(dq, qos, flags, target);
+	}
+
+#if HAVE_PTHREAD_WORKQUEUE_QOS
+	if ((flags & (DISPATCH_WAKEUP_OVERRIDING | DISPATCH_WAKEUP_WAITER_HANDOFF))
+			&& target != DISPATCH_QUEUE_WAKEUP_MGR) {
+		return _dispatch_queue_class_wakeup_with_override(dq, qos,
+				flags, new_state);
+	}
+#endif
+
+	if (flags & DISPATCH_WAKEUP_CONSUME) {
+		return _dispatch_release_tailcall(dq);
+	}
+}
+
+DISPATCH_NOINLINE
+void
 _dispatch_queue_class_wakeup(dispatch_queue_t dq, dispatch_qos_t qos,
 		dispatch_wakeup_flags_t flags, dispatch_queue_wakeup_target_t target)
 {
-	dispatch_assert(target != DISPATCH_QUEUE_WAKEUP_WAIT_FOR_EVENT);
+	uint64_t old_state, new_state;
 
-	if (target && !(flags & DISPATCH_WAKEUP_CONSUME_2)) {
-		_dispatch_retain_2(dq);
-		flags |= DISPATCH_WAKEUP_CONSUME_2;
-	}
+	qos = _dispatch_queue_override_qos(dq, qos);
+	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
+		new_state = _dq_state_merge_qos(old_state, qos);
+		if (likely(_dq_state_should_wakeup(old_state))) {
+			new_state |= DISPATCH_QUEUE_ENQUEUED;
+		}
+		if (flags & DISPATCH_WAKEUP_FLUSH) {
+			new_state |= DISPATCH_QUEUE_DIRTY;
+		} else if (new_state == old_state) {
+			os_atomic_rmw_loop_give_up(break);
+		}
+	});
 
-	if (unlikely(flags & DISPATCH_WAKEUP_BARRIER_COMPLETE)) {
-		//
-		// _dispatch_queue_class_barrier_complete() is about what both regular
-		// queues and sources needs to evaluate, but the former can have sync
-		// handoffs to perform which _dispatch_queue_class_barrier_complete()
-		// doesn't handle, only _dispatch_queue_barrier_complete() does.
-		//
-		// _dispatch_queue_wakeup() is the one for plain queues that calls
-		// _dispatch_queue_barrier_complete(), and this is only taken for non
-		// queue types.
-		//
-		dispatch_assert(dx_metatype(dq) != _DISPATCH_QUEUE_TYPE);
-		return _dispatch_queue_class_barrier_complete(dq, qos, flags, target,
-				DISPATCH_QUEUE_SERIAL_DRAIN_OWNED);
-	}
-
-	if (target) {
-		uint64_t old_state, new_state, enqueue = DISPATCH_QUEUE_ENQUEUED;
-		if (target == DISPATCH_QUEUE_WAKEUP_MGR) {
-			enqueue = DISPATCH_QUEUE_ENQUEUED_ON_MGR;
-		}
-		qos = _dispatch_queue_override_qos(dq, qos);
-		os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
-			new_state = _dq_state_merge_qos(old_state, qos);
-			if (likely(!_dq_state_is_suspended(old_state) &&
-					!_dq_state_is_enqueued(old_state) &&
-					(!_dq_state_drain_locked(old_state) ||
-					(enqueue != DISPATCH_QUEUE_ENQUEUED_ON_MGR &&
-					_dq_state_is_base_wlh(old_state))))) {
-				new_state |= enqueue;
-			}
-			if (flags & DISPATCH_WAKEUP_MAKE_DIRTY) {
-				new_state |= DISPATCH_QUEUE_DIRTY;
-			} else if (new_state == old_state) {
-				os_atomic_rmw_loop_give_up(goto done);
-			}
-		});
-
-		if (likely((old_state ^ new_state) & enqueue)) {
-			dispatch_queue_t tq;
-			if (target == DISPATCH_QUEUE_WAKEUP_TARGET) {
-				// the rmw_loop above has no acquire barrier, as the last block
-				// of a queue asyncing to that queue is not an uncommon pattern
-				// and in that case the acquire would be completely useless
-				//
-				// so instead use depdendency ordering to read
-				// the targetq pointer.
-				os_atomic_thread_fence(dependency);
-				tq = os_atomic_load_with_dependency_on2o(dq, do_targetq,
-						(long)new_state);
-			} else {
-				tq = target;
-			}
-			dispatch_assert(_dq_state_is_enqueued(new_state));
-			return _dispatch_queue_push_queue(tq, dq, new_state);
-		}
-#if HAVE_PTHREAD_WORKQUEUE_QOS
-		if (unlikely((old_state ^ new_state) & DISPATCH_QUEUE_MAX_QOS_MASK)) {
-			if (_dq_state_should_override(new_state)) {
-				return _dispatch_queue_class_wakeup_with_override(dq, new_state,
-						flags);
-			}
-		}
-	} else if (qos) {
-		//
-		// Someone is trying to override the last work item of the queue.
-		//
-		uint64_t old_state, new_state;
-		os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, relaxed, {
-			if (!_dq_state_drain_locked(old_state) ||
-					!_dq_state_is_enqueued(old_state)) {
-				os_atomic_rmw_loop_give_up(goto done);
-			}
-			new_state = _dq_state_merge_qos(old_state, qos);
-			if (new_state == old_state) {
-				os_atomic_rmw_loop_give_up(goto done);
-			}
-		});
-		if (_dq_state_should_override(new_state)) {
-			return _dispatch_queue_class_wakeup_with_override(dq, new_state,
-					flags);
-		}
-#endif // HAVE_PTHREAD_WORKQUEUE_QOS
-	}
-done:
-	if (likely(flags & DISPATCH_WAKEUP_CONSUME_2)) {
-		return _dispatch_release_2_tailcall(dq);
-	}
+	return _dispatch_queue_class_wakeup_finish(dq, qos, flags, target,
+			old_state, new_state);
 }
 
 DISPATCH_NOINLINE
 static void
 _dispatch_queue_push_sync_waiter(dispatch_queue_t dq,
-		dispatch_sync_context_t dsc, dispatch_qos_t qos)
+		dispatch_sync_context_t dsc)
 {
+	uint64_t pending_barrier_width =
+			(dq->dq_width - 1) * DISPATCH_QUEUE_WIDTH_INTERVAL;
+	uint64_t xor_owner_and_set_full_width_and_in_barrier =
+			_dispatch_tid_self() | DISPATCH_QUEUE_WIDTH_FULL_BIT |
+			DISPATCH_QUEUE_IN_BARRIER;
+	dispatch_qos_t qos = _dispatch_continuation_override_qos(dq, dsc->_as_dc);
 	uint64_t old_state, new_state;
-
-	if (unlikely(dx_type(dq) == DISPATCH_QUEUE_NETWORK_EVENT_TYPE)) {
-		DISPATCH_CLIENT_CRASH(0,
-				"dispatch_sync onto a network event queue");
-	}
+	dispatch_wakeup_flags_t flags = 0;
 
 	_dispatch_trace_continuation_push(dq, dsc->_as_dc);
-
 	if (unlikely(_dispatch_queue_push_update_tail(dq, dsc->_as_do))) {
 		// for slow waiters, we borrow the reference of the caller
 		// so we don't need to protect the wakeup with a temporary retain
 		_dispatch_queue_push_update_head(dq, dsc->_as_do);
+		flags = DISPATCH_WAKEUP_FLUSH;
 		if (unlikely(_dispatch_queue_is_thread_bound(dq))) {
-			return dx_wakeup(dq, qos, DISPATCH_WAKEUP_MAKE_DIRTY);
+			return dx_wakeup(dq, qos, flags);
 		}
-
-		uint64_t pending_barrier_width =
-				(dq->dq_width - 1) * DISPATCH_QUEUE_WIDTH_INTERVAL;
-		uint64_t set_owner_and_set_full_width_and_in_barrier =
-				_dispatch_lock_value_for_self() |
-				DISPATCH_QUEUE_WIDTH_FULL_BIT | DISPATCH_QUEUE_IN_BARRIER;
-		// similar to _dispatch_queue_drain_try_unlock()
-		os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
-			new_state  = _dq_state_merge_qos(old_state, qos);
-			new_state |= DISPATCH_QUEUE_DIRTY;
-			if (unlikely(_dq_state_drain_locked(old_state) ||
-					!_dq_state_is_runnable(old_state))) {
-				// not runnable, so we should just handle overrides
-			} else if (_dq_state_is_base_wlh(old_state) &&
-					_dq_state_is_enqueued(old_state)) {
-				// 32123779 let the event thread redrive since it's out already
-			} else if (_dq_state_has_pending_barrier(old_state) ||
-					new_state + pending_barrier_width <
-					DISPATCH_QUEUE_WIDTH_FULL_BIT) {
-				// see _dispatch_queue_drain_try_lock
-				new_state &= DISPATCH_QUEUE_DRAIN_PRESERVED_BITS_MASK;
-				new_state |= set_owner_and_set_full_width_and_in_barrier;
-			}
-		});
-
-		if (_dq_state_is_base_wlh(old_state) &&
-				(dsc->dsc_waiter == _dispatch_tid_self())) {
-			dsc->dsc_wlh_was_first = true;
-		}
-
-		if ((old_state ^ new_state) & DISPATCH_QUEUE_IN_BARRIER) {
-			return _dispatch_queue_barrier_complete(dq, qos, 0);
-		}
-#if HAVE_PTHREAD_WORKQUEUE_QOS
-		if (unlikely((old_state ^ new_state) & DISPATCH_QUEUE_MAX_QOS_MASK)) {
-			if (_dq_state_should_override(new_state)) {
-				return _dispatch_queue_class_wakeup_with_override(dq,
-						new_state, 0);
-			}
-		}
-	} else if (unlikely(qos)) {
-		os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, relaxed, {
-			new_state = _dq_state_merge_qos(old_state, qos);
-			if (old_state == new_state) {
-				os_atomic_rmw_loop_give_up(return);
-			}
-		});
-		if (_dq_state_should_override(new_state)) {
-			return _dispatch_queue_class_wakeup_with_override(dq, new_state, 0);
-		}
-#endif // HAVE_PTHREAD_WORKQUEUE_QOS
 	}
+
+	os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, release, {
+		new_state = _dq_state_merge_qos(old_state, qos);
+#ifdef DLOCK_NOWAITERS_BIT
+		new_state |= DLOCK_NOWAITERS_BIT;
+#else
+		new_state |= DLOCK_WAITERS_BIT;
+#endif
+		if (flags & DISPATCH_WAKEUP_FLUSH) {
+			new_state |= DISPATCH_QUEUE_DIRTY;
+		}
+		if (_dq_state_drain_pended(old_state)) {
+			// same as DISPATCH_QUEUE_DRAIN_UNLOCK
+			// but we want to be more efficient wrt the WAITERS_BIT
+			new_state &= ~DISPATCH_QUEUE_DRAIN_OWNER_MASK;
+			new_state &= ~DISPATCH_QUEUE_DRAIN_PENDED;
+		}
+		if (unlikely(_dq_state_drain_locked(new_state))) {
+#ifdef DLOCK_NOWAITERS_BIT
+			new_state &= ~(uint64_t)DLOCK_NOWAITERS_BIT;
+#endif
+		} else if (unlikely(!_dq_state_is_runnable(new_state) ||
+				!(flags & DISPATCH_WAKEUP_FLUSH))) {
+			// either not runnable, or was not for the first item (26700358)
+			// so we should not try to lock and handle overrides instead
+		} else if (_dq_state_has_pending_barrier(old_state) ||
+				new_state + pending_barrier_width <
+				DISPATCH_QUEUE_WIDTH_FULL_BIT) {
+			// see _dispatch_queue_drain_try_lock
+			new_state &= DISPATCH_QUEUE_DRAIN_PRESERVED_BITS_MASK;
+			new_state ^= xor_owner_and_set_full_width_and_in_barrier;
+		} else {
+			new_state |= DISPATCH_QUEUE_ENQUEUED;
+		}
+	});
+
+	if ((old_state ^ new_state) & DISPATCH_QUEUE_IN_BARRIER) {
+		return _dispatch_try_lock_transfer_or_wakeup(dq);
+	}
+
+	return _dispatch_queue_class_wakeup_finish(dq, qos, flags,
+			DISPATCH_QUEUE_WAKEUP_TARGET, old_state, new_state);
 }
 
 #pragma mark -
@@ -5597,87 +5351,36 @@
 	return head;
 }
 
-#if DISPATCH_USE_KEVENT_WORKQUEUE
 void
-_dispatch_root_queue_drain_deferred_wlh(dispatch_deferred_items_t ddi
-		DISPATCH_PERF_MON_ARGS_PROTO)
+_dispatch_root_queue_drain_deferred_item(dispatch_queue_t rq,
+		dispatch_queue_t dq DISPATCH_PERF_MON_ARGS_PROTO)
 {
-	dispatch_queue_t rq = ddi->ddi_stashed_rq;
-	dispatch_queue_t dq = ddi->ddi_stashed_dou._dq;
-	_dispatch_queue_set_current(rq);
-	dispatch_priority_t old_pri = _dispatch_set_basepri_wlh(rq->dq_priority);
-	dispatch_invoke_context_s dic = { };
-	dispatch_invoke_flags_t flags = DISPATCH_INVOKE_WORKER_DRAIN |
-			DISPATCH_INVOKE_REDIRECTING_DRAIN | DISPATCH_INVOKE_WLH;
-	_dispatch_queue_drain_init_narrowing_check_deadline(&dic, rq->dq_priority);
-	uint64_t dq_state;
+	// fake that we queued `dq` on `rq` for introspection purposes
+	_dispatch_trace_continuation_push(rq, dq);
 
-	ddi->ddi_wlh_servicing = true;
-	if (unlikely(_dispatch_needs_to_return_to_kernel())) {
-		_dispatch_return_to_kernel();
-	}
-retry:
-	dispatch_assert(ddi->ddi_wlh_needs_delete);
-	_dispatch_trace_continuation_pop(rq, dq);
-
-	if (_dispatch_queue_drain_try_lock_wlh(dq, &dq_state)) {
-		dx_invoke(dq, &dic, flags);
-		if (!ddi->ddi_wlh_needs_delete) {
-			goto park;
-		}
-		dq_state = os_atomic_load2o(dq, dq_state, relaxed);
-		if (unlikely(_dq_state_is_enqueued_on_target(dq_state))) {
-			_dispatch_retain(dq);
-			_dispatch_trace_continuation_push(dq->do_targetq, dq);
-			goto retry;
-		}
-	} else {
-		_dispatch_release_no_dispose(dq);
-	}
-
-	_dispatch_event_loop_leave_deferred((dispatch_wlh_t)dq, dq_state);
-
-park:
-	// event thread that could steal
-	_dispatch_perfmon_end(perfmon_thread_event_steal);
-	_dispatch_reset_basepri(old_pri);
-	_dispatch_reset_basepri_override();
-	_dispatch_queue_set_current(NULL);
-
-	_dispatch_voucher_debug("root queue clear", NULL);
-	_dispatch_reset_voucher(NULL, DISPATCH_THREAD_PARK);
-}
-
-void
-_dispatch_root_queue_drain_deferred_item(dispatch_deferred_items_t ddi
-		DISPATCH_PERF_MON_ARGS_PROTO)
-{
-	dispatch_queue_t rq = ddi->ddi_stashed_rq;
 	_dispatch_queue_set_current(rq);
 	dispatch_priority_t old_pri = _dispatch_set_basepri(rq->dq_priority);
+#if DISPATCH_COCOA_COMPAT
+	void *pool = _dispatch_last_resort_autorelease_pool_push();
+#endif // DISPATCH_COCOA_COMPAT
 
 	dispatch_invoke_context_s dic = { };
 	dispatch_invoke_flags_t flags = DISPATCH_INVOKE_WORKER_DRAIN |
 			DISPATCH_INVOKE_REDIRECTING_DRAIN;
-#if DISPATCH_COCOA_COMPAT
-	_dispatch_last_resort_autorelease_pool_push(&dic);
-#endif // DISPATCH_COCOA_COMPAT
 	_dispatch_queue_drain_init_narrowing_check_deadline(&dic, rq->dq_priority);
-	_dispatch_continuation_pop_inline(ddi->ddi_stashed_dou, &dic, flags, rq);
-
+	_dispatch_continuation_pop_inline(dq, &dic, flags, rq);
 	// event thread that could steal
 	_dispatch_perfmon_end(perfmon_thread_event_steal);
+
 #if DISPATCH_COCOA_COMPAT
-	_dispatch_last_resort_autorelease_pool_pop(&dic);
+	_dispatch_last_resort_autorelease_pool_pop(pool);
 #endif // DISPATCH_COCOA_COMPAT
 	_dispatch_reset_basepri(old_pri);
-	_dispatch_reset_basepri_override();
 	_dispatch_queue_set_current(NULL);
 
 	_dispatch_voucher_debug("root queue clear", NULL);
 	_dispatch_reset_voucher(NULL, DISPATCH_THREAD_PARK);
 }
-#endif
 
 DISPATCH_NOT_TAIL_CALLED // prevent tailcall (for Instrument DTrace probe)
 static void
@@ -5693,14 +5396,14 @@
 	dispatch_priority_t pri = dq->dq_priority;
 	if (!pri) pri = _dispatch_priority_from_pp(pp);
 	dispatch_priority_t old_dbp = _dispatch_set_basepri(pri);
-	_dispatch_adopt_wlh_anon();
+	_dispatch_set_wlh(DISPATCH_WLH_GLOBAL);
+#if DISPATCH_COCOA_COMPAT
+	void *pool = _dispatch_last_resort_autorelease_pool_push();
+#endif // DISPATCH_COCOA_COMPAT
 
 	struct dispatch_object_s *item;
 	bool reset = false;
 	dispatch_invoke_context_s dic = { };
-#if DISPATCH_COCOA_COMPAT
-	_dispatch_last_resort_autorelease_pool_push(&dic);
-#endif // DISPATCH_COCOA_COMPAT
 	dispatch_invoke_flags_t flags = DISPATCH_INVOKE_WORKER_DRAIN |
 			DISPATCH_INVOKE_REDIRECTING_DRAIN;
 	_dispatch_queue_drain_init_narrowing_check_deadline(&dic, pri);
@@ -5722,11 +5425,10 @@
 	}
 
 #if DISPATCH_COCOA_COMPAT
-	_dispatch_last_resort_autorelease_pool_pop(&dic);
+	_dispatch_last_resort_autorelease_pool_pop(pool);
 #endif // DISPATCH_COCOA_COMPAT
 	_dispatch_reset_wlh();
 	_dispatch_reset_basepri(old_dbp);
-	_dispatch_reset_basepri_override();
 	_dispatch_queue_set_current(NULL);
 }
 
@@ -5828,25 +5530,13 @@
 #endif
 	(void)os_atomic_inc2o(qc, dgq_thread_pool_size, release);
 	_dispatch_global_queue_poke(dq, 1, 0);
-	_dispatch_release(dq); // retained in _dispatch_global_queue_poke_slow
+	_dispatch_release(dq);
+
 	return NULL;
 }
 #endif // DISPATCH_USE_PTHREAD_POOL
 
 #pragma mark -
-#pragma mark dispatch_network_root_queue
-#if TARGET_OS_MAC
-
-dispatch_queue_t
-_dispatch_network_root_queue_create_4NW(const char *label,
-		const pthread_attr_t *attrs, dispatch_block_t configure)
-{
-	unsigned long flags = dispatch_pthread_root_queue_flags_pool_size(1);
-	return dispatch_pthread_root_queue_create(label, flags, attrs, configure);
-}
-
-#endif // TARGET_OS_MAC
-#pragma mark -
 #pragma mark dispatch_runloop_queue
 
 static bool _dispatch_program_is_probably_callback_driven;
@@ -5863,11 +5553,11 @@
 		return DISPATCH_BAD_INPUT;
 	}
 	dqs = sizeof(struct dispatch_queue_s) - DISPATCH_QUEUE_CACHELINE_PAD;
-	dq = _dispatch_object_alloc(DISPATCH_VTABLE(queue_runloop), dqs);
-	_dispatch_queue_init(dq, DQF_THREAD_BOUND | DQF_CANNOT_TRYSYNC, 1,
-			DISPATCH_QUEUE_ROLE_BASE_ANON);
+	dq = _dispatch_alloc(DISPATCH_VTABLE(queue_runloop), dqs);
+	_dispatch_queue_init(dq, DQF_THREAD_BOUND | DQF_CANNOT_TRYSYNC, 1, false);
 	dq->do_targetq = _dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, true);
 	dq->dq_label = label ? label : "runloop-queue"; // no-copy contract
+	dq->dq_wlh = DISPATCH_WLH_GLOBAL;
 	_dispatch_runloop_queue_handle_init(dq);
 	_dispatch_queue_set_bound_thread(dq);
 	_dispatch_object_debug(dq, "%s", __func__);
@@ -5879,19 +5569,19 @@
 {
 	_dispatch_object_debug(dq, "%s", __func__);
 
-	dispatch_qos_t qos = _dispatch_runloop_queue_reset_max_qos(dq);
+	dispatch_qos_t qos = _dispatch_queue_reset_max_qos(dq);
 	_dispatch_queue_clear_bound_thread(dq);
-	dx_wakeup(dq, qos, DISPATCH_WAKEUP_MAKE_DIRTY);
+	dx_wakeup(dq, qos, DISPATCH_WAKEUP_FLUSH);
 	if (qos) _dispatch_thread_override_end(DISPATCH_QUEUE_DRAIN_OWNER(dq), dq);
 }
 
 void
-_dispatch_runloop_queue_dispose(dispatch_queue_t dq, bool *allow_free)
+_dispatch_runloop_queue_dispose(dispatch_queue_t dq)
 {
 	_dispatch_object_debug(dq, "%s", __func__);
 	_dispatch_introspection_queue_dispose(dq);
 	_dispatch_runloop_queue_handle_dispose(dq);
-	_dispatch_queue_destroy(dq, allow_free);
+	_dispatch_queue_destroy(dq);
 }
 
 bool
@@ -6126,7 +5816,7 @@
 		new_state += DISPATCH_QUEUE_IN_BARRIER;
 	});
 	_dispatch_queue_atomic_flags_clear(dq, DQF_THREAD_BOUND|DQF_CANNOT_TRYSYNC);
-	_dispatch_queue_barrier_complete(dq, 0, 0);
+	_dispatch_try_lock_transfer_or_wakeup(dq);
 
 	// overload the "probably" variable to mean that dispatch_main() or
 	// similar non-POSIX API was called
@@ -6158,13 +5848,12 @@
 			"Premature thread exit while a dispatch queue is running");
 }
 
+DISPATCH_NORETURN
 static void
 _dispatch_wlh_cleanup(void *ctxt)
 {
 	// POSIX defines that destructors are only called if 'ctxt' is non-null
-	dispatch_queue_t wlh;
-	wlh = (dispatch_queue_t)((uintptr_t)ctxt & ~DISPATCH_WLH_STORAGE_REF);
-	_dispatch_queue_release_storage(wlh);
+	DISPATCH_INTERNAL_CRASH(ctxt, "Premature thread exit with active wlh");
 }
 
 DISPATCH_NORETURN
diff --git a/src/queue_internal.h b/src/queue_internal.h
index c1d0f6e..91a3186 100644
--- a/src/queue_internal.h
+++ b/src/queue_internal.h
@@ -44,9 +44,6 @@
 #define DISPATCH_CACHELINE_ALIGN \
 		__attribute__((__aligned__(DISPATCH_CACHELINE_SIZE)))
 
-#define DISPATCH_CACHELINE_PAD_SIZE(type) \
-		(roundup(sizeof(type), DISPATCH_CACHELINE_SIZE) - sizeof(type))
-
 
 #pragma mark -
 #pragma mark dispatch_queue_t
@@ -63,6 +60,7 @@
 	DQF_CANNOT_TRYSYNC      = 0x00400000,
 	DQF_RELEASED            = 0x00800000, // xref_cnt == -1
 	DQF_LEGACY              = 0x01000000,
+	DQF_WLH_CHANGED         = 0x02000000, // queue wlh changed from initial value
 
 	// only applies to sources
 	//
@@ -101,7 +99,6 @@
 	//    `a` cannot do a cleared -> set transition anymore
 	//    (see _dispatch_source_try_set_armed).
 	//
-	DSF_WLH_CHANGED         = 0x04000000,
 	DSF_CANCEL_WAITER       = 0x08000000, // synchronous waiters for cancel
 	DSF_CANCELED            = 0x10000000, // cancellation has been requested
 	DSF_ARMED               = 0x20000000, // source is armed
@@ -118,6 +115,10 @@
 	struct os_mpsc_queue_s _as_oq[0]; \
 	DISPATCH_OBJECT_HEADER(x); \
 	_OS_MPSC_QUEUE_FIELDS(dq, dq_state); \
+	DISPATCH_UNION_LE(uint32_t volatile dq_atomic_flags, \
+		const uint16_t dq_width, \
+		const uint16_t __dq_opaque \
+	); \
 	uint32_t dq_side_suspend_cnt; \
 	dispatch_unfair_lock_s dq_sidelock; \
 	union { \
@@ -126,26 +127,27 @@
 		struct dispatch_timer_source_refs_s *ds_timer_refs; \
 		struct dispatch_mach_recv_refs_s *dm_recv_refs; \
 	}; \
-	DISPATCH_UNION_LE(uint32_t volatile dq_atomic_flags, \
-		const uint16_t dq_width, \
-		const uint16_t __dq_opaque \
-	); \
 	DISPATCH_INTROSPECTION_QUEUE_HEADER
-	/* LP64: 32bit hole */
 
 #define DISPATCH_QUEUE_HEADER(x) \
 	struct dispatch_queue_s _as_dq[0]; \
 	_DISPATCH_QUEUE_HEADER(x)
 
-struct _dispatch_unpadded_queue_s {
-	_DISPATCH_QUEUE_HEADER(dummy);
-};
-
-#define DISPATCH_QUEUE_CACHELINE_PAD \
-		DISPATCH_CACHELINE_PAD_SIZE(struct _dispatch_unpadded_queue_s)
-
 #define DISPATCH_QUEUE_CACHELINE_PADDING \
 		char _dq_pad[DISPATCH_QUEUE_CACHELINE_PAD]
+#ifdef __LP64__
+#define DISPATCH_QUEUE_CACHELINE_PAD (( \
+		(sizeof(uint32_t) - DISPATCH_INTROSPECTION_QUEUE_HEADER_SIZE) \
+		+ DISPATCH_CACHELINE_SIZE) % DISPATCH_CACHELINE_SIZE)
+#elif OS_OBJECT_HAVE_OBJC1
+#define DISPATCH_QUEUE_CACHELINE_PAD (( \
+		(11*sizeof(void*) - DISPATCH_INTROSPECTION_QUEUE_HEADER_SIZE) \
+		+ DISPATCH_CACHELINE_SIZE) % DISPATCH_CACHELINE_SIZE)
+#else
+#define DISPATCH_QUEUE_CACHELINE_PAD (( \
+		(12*sizeof(void*) - DISPATCH_INTROSPECTION_QUEUE_HEADER_SIZE) \
+		+ DISPATCH_CACHELINE_SIZE) % DISPATCH_CACHELINE_SIZE)
+#endif
 
 /*
  * dispatch queues `dq_state` demystified
@@ -155,27 +157,27 @@
  * Most Significant 32 bit Word
  * ----------------------------
  *
- * sc: suspend count (bits 63 - 58)
+ * sc: suspend count (bits 63 - 57)
  *    The suspend count unsurprisingly holds the suspend count of the queue
  *    Only 7 bits are stored inline. Extra counts are transfered in a side
  *    suspend count and when that has happened, the ssc: bit is set.
  */
-#define DISPATCH_QUEUE_SUSPEND_INTERVAL		0x0400000000000000ull
-#define DISPATCH_QUEUE_SUSPEND_HALF			0x20u
+#define DISPATCH_QUEUE_SUSPEND_INTERVAL		0x0200000000000000ull
+#define DISPATCH_QUEUE_SUSPEND_HALF			0x40u
 /*
- * ssc: side suspend count (bit 57)
+ * ssc: side suspend count (bit 56)
  *    This bit means that the total suspend count didn't fit in the inline
  *    suspend count, and that there are additional suspend counts stored in the
  *    `dq_side_suspend_cnt` field.
  */
-#define DISPATCH_QUEUE_HAS_SIDE_SUSPEND_CNT	0x0200000000000000ull
+#define DISPATCH_QUEUE_HAS_SIDE_SUSPEND_CNT	0x0100000000000000ull
 /*
- * i: inactive bit (bit 56)
+ * i: inactive bit (bit 55)
  *    This bit means that the object is inactive (see dispatch_activate)
  */
-#define DISPATCH_QUEUE_INACTIVE				0x0100000000000000ull
+#define DISPATCH_QUEUE_INACTIVE				0x0080000000000000ull
 /*
- * na: needs activation (bit 55)
+ * na: needs activation (bit 54)
  *    This bit is set if the object is created inactive. It tells
  *    dispatch_queue_wakeup to perform various tasks at first wakeup.
  *
@@ -183,24 +185,24 @@
  *    the object from being woken up (because _dq_state_should_wakeup will say
  *    no), except in the dispatch_activate/dispatch_resume codepath.
  */
-#define DISPATCH_QUEUE_NEEDS_ACTIVATION		0x0080000000000000ull
+#define DISPATCH_QUEUE_NEEDS_ACTIVATION		0x0040000000000000ull
 /*
  * This mask covers the suspend count (sc), side suspend count bit (ssc),
  * inactive (i) and needs activation (na) bits
  */
-#define DISPATCH_QUEUE_SUSPEND_BITS_MASK	0xff80000000000000ull
+#define DISPATCH_QUEUE_SUSPEND_BITS_MASK	0xffc0000000000000ull
 /*
- * ib: in barrier (bit 54)
+ * ib: in barrier (bit 53)
  *    This bit is set when the queue is currently executing a barrier
  */
-#define DISPATCH_QUEUE_IN_BARRIER			0x0040000000000000ull
+#define DISPATCH_QUEUE_IN_BARRIER			0x0020000000000000ull
 /*
- * qf: queue full (bit 53)
+ * qf: queue full (bit 52)
  *    This bit is a subtle hack that allows to check for any queue width whether
  *    the full width of the queue is used or reserved (depending on the context)
  *    In other words that the queue has reached or overflown its capacity.
  */
-#define DISPATCH_QUEUE_WIDTH_FULL_BIT		0x0020000000000000ull
+#define DISPATCH_QUEUE_WIDTH_FULL_BIT		0x0010000000000000ull
 #define DISPATCH_QUEUE_WIDTH_FULL			0x1000ull
 #define DISPATCH_QUEUE_WIDTH_POOL (DISPATCH_QUEUE_WIDTH_FULL - 1)
 #define DISPATCH_QUEUE_WIDTH_MAX  (DISPATCH_QUEUE_WIDTH_FULL - 2)
@@ -208,7 +210,7 @@
 		({ uint16_t _width = (width); \
 		_width > 1 && _width < DISPATCH_QUEUE_WIDTH_POOL; })
 /*
- * w:  width (bits 52 - 41)
+ * w:  width (bits 51 - 40)
  *    This encodes how many work items are in flight. Barriers hold `dq_width`
  *    of them while they run. This is encoded as a signed offset with respect,
  *    to full use, where the negative values represent how many available slots
@@ -217,19 +219,29 @@
  *
  *    When this value is positive, then `wo` is always set to 1.
  */
-#define DISPATCH_QUEUE_WIDTH_INTERVAL		0x0000020000000000ull
-#define DISPATCH_QUEUE_WIDTH_MASK			0x003ffe0000000000ull
-#define DISPATCH_QUEUE_WIDTH_SHIFT			41
+#define DISPATCH_QUEUE_WIDTH_INTERVAL		0x0000010000000000ull
+#define DISPATCH_QUEUE_WIDTH_MASK			0x001fff0000000000ull
+#define DISPATCH_QUEUE_WIDTH_SHIFT			40
 /*
- * pb: pending barrier (bit 40)
+ * pb: pending barrier (bit 39)
  *    Drainers set this bit when they couldn't run the next work item and it is
  *    a barrier. When this bit is set, `dq_width - 1` work item slots are
  *    reserved so that no wakeup happens until the last work item in flight
  *    completes.
  */
-#define DISPATCH_QUEUE_PENDING_BARRIER		0x0000010000000000ull
+#define DISPATCH_QUEUE_PENDING_BARRIER		0x0000008000000000ull
 /*
- * d: dirty bit (bit 39)
+ * p: pended bit (bit 38)
+ *    Set when a drain lock has been pended. When this bit is set,
+ *    the drain lock is taken and ENQUEUED is never set.
+ *
+ *    This bit marks a queue that needs further processing but was kept pended
+ *    by an async drainer (not reenqueued) in the hope of being able to drain
+ *    it further later.
+ */
+#define DISPATCH_QUEUE_DRAIN_PENDED			0x0000004000000000ull
+/*
+ * d: dirty bit (bit 37)
  *    This bit is set when a queue transitions from empty to not empty.
  *    This bit is set before dq_items_head is set, with appropriate barriers.
  *    Any thread looking at a queue head is responsible for unblocking any
@@ -341,40 +353,18 @@
  *
  *    So on the async "acquire" side, there is no subtlety at all.
  */
-#define DISPATCH_QUEUE_DIRTY				0x0000008000000000ull
+#define DISPATCH_QUEUE_DIRTY				0x0000002000000000ull
 /*
- * md: enqueued/draining on manager (bit 38)
- *    Set when enqueued and draining on the manager hierarchy.
- *
- *    Unlike the ENQUEUED bit, it is kept until the queue is unlocked from its
- *    invoke call on the manager. This is used to prevent stealing, and
- *    overrides to be applied down the target queue chain.
+ * e: enqueued bit (bit 36)
+ *    Set when a queue is enqueued on its target queue
  */
-#define DISPATCH_QUEUE_ENQUEUED_ON_MGR		0x0000004000000000ull
+#define DISPATCH_QUEUE_ENQUEUED				0x0000001000000000ull
 /*
- * r: queue graph role (bits 37 - 36)
- *    Queue role in the target queue graph
- *
- *    11: unused
- *    10: WLH base
- *    01: non wlh base
- *    00: inner queue
- */
-#define DISPATCH_QUEUE_ROLE_MASK			0x0000003000000000ull
-#define DISPATCH_QUEUE_ROLE_BASE_WLH		0x0000002000000000ull
-#define DISPATCH_QUEUE_ROLE_BASE_ANON		0x0000001000000000ull
-#define DISPATCH_QUEUE_ROLE_INNER			0x0000000000000000ull
-/*
- * o: has override (bit 35, if role is DISPATCH_QUEUE_ROLE_BASE_ANON)
+ * o: has override (bits 34)
  *    Set when a queue has received a QOS override and needs to reset it.
  *    This bit is only cleared when the final drain_try_unlock() succeeds.
- *
- * sw: has received sync wait (bit 35, if role DISPATCH_QUEUE_ROLE_BASE_WLH)
- *    Set when a queue owner has been exposed to the kernel because of
- *    dispatch_sync() contention.
  */
 #define DISPATCH_QUEUE_RECEIVED_OVERRIDE	0x0000000800000000ull
-#define DISPATCH_QUEUE_RECEIVED_SYNC_WAIT	0x0000000800000000ull
 /*
  * max_qos: max qos (bits 34 - 32)
  *   This is the maximum qos that has been enqueued on the queue
@@ -386,25 +376,27 @@
  *    This is used by the normal drain to drain exlusively relative to other
  *    drain stealers (like the QoS Override codepath). It holds the identity
  *    (thread port) of the current drainer.
- *
- * st: sync transfer (bit 1 or 30)
- *    Set when a dispatch_sync() is transferred to
- *
- * e: enqueued bit (bit 0 or 31)
- *    Set when a queue is enqueued on its target queue
  */
-#define DISPATCH_QUEUE_DRAIN_OWNER_MASK		((uint64_t)DLOCK_OWNER_MASK)
-#define DISPATCH_QUEUE_SYNC_TRANSFER		((uint64_t)DLOCK_FAILED_TRYLOCK_BIT)
-#define DISPATCH_QUEUE_ENQUEUED				((uint64_t)DLOCK_WAITERS_BIT)
-
+#define DISPATCH_QUEUE_DRAIN_UNLOCK_MASK	(DISPATCH_QUEUE_DRAIN_PENDED | ~0u)
+#ifdef DLOCK_NOWAITERS_BIT
+#define DISPATCH_QUEUE_DRAIN_OWNER_MASK \
+		((uint64_t)(DLOCK_OWNER_MASK | DLOCK_NOFAILED_TRYLOCK_BIT))
+#define DISPATCH_QUEUE_DRAIN_UNLOCK(v) \
+		(((v) & ~(DISPATCH_QUEUE_DIRTY | DISPATCH_QUEUE_DRAIN_PENDED \
+				| DISPATCH_QUEUE_DRAIN_OWNER_MASK)) ^ DLOCK_NOWAITERS_BIT)
 #define DISPATCH_QUEUE_DRAIN_PRESERVED_BITS_MASK \
-		(DISPATCH_QUEUE_ENQUEUED_ON_MGR | DISPATCH_QUEUE_ENQUEUED | \
-		DISPATCH_QUEUE_ROLE_MASK | DISPATCH_QUEUE_MAX_QOS_MASK)
-
-#define DISPATCH_QUEUE_DRAIN_UNLOCK_MASK \
-		(DISPATCH_QUEUE_DRAIN_OWNER_MASK | DISPATCH_QUEUE_RECEIVED_OVERRIDE | \
-		DISPATCH_QUEUE_RECEIVED_SYNC_WAIT | DISPATCH_QUEUE_SYNC_TRANSFER)
-
+		(DISPATCH_QUEUE_ENQUEUED | DISPATCH_QUEUE_MAX_QOS_MASK | \
+				DLOCK_NOWAITERS_BIT)
+#else
+#define DISPATCH_QUEUE_DRAIN_OWNER_MASK \
+		((uint64_t)(DLOCK_OWNER_MASK | DLOCK_FAILED_TRYLOCK_BIT))
+#define DISPATCH_QUEUE_DRAIN_UNLOCK(v) \
+		((v) & ~(DISPATCH_QUEUE_DIRTY | DISPATCH_QUEUE_DRAIN_PENDED | \
+				DISPATCH_QUEUE_DRAIN_OWNER_MASK))
+#define DISPATCH_QUEUE_DRAIN_PRESERVED_BITS_MASK \
+		(DISPATCH_QUEUE_ENQUEUED | DISPATCH_QUEUE_MAX_QOS_MASK | \
+				DLOCK_WAITERS_BIT)
+#endif
 /*
  *******************************************************************************
  *
@@ -426,6 +418,8 @@
  * that right. To do so, prior to taking any decision, they also try to own
  * the full "barrier" width on the given queue.
  *
+ * see _dispatch_try_lock_transfer_or_wakeup
+ *
  *******************************************************************************
  *
  * Enqueuing and wakeup rules
@@ -496,16 +490,11 @@
 		(DISPATCH_QUEUE_IN_BARRIER | DISPATCH_QUEUE_WIDTH_INTERVAL)
 
 DISPATCH_CLASS_DECL(queue);
-
 #if !defined(__cplusplus) || !DISPATCH_INTROSPECTION
 struct dispatch_queue_s {
 	_DISPATCH_QUEUE_HEADER(queue);
 	DISPATCH_QUEUE_CACHELINE_PADDING; // for static queues only
 } DISPATCH_ATOMIC64_ALIGN;
-
-#if __has_feature(c_static_assert) && !DISPATCH_INTROSPECTION
-_Static_assert(sizeof(struct dispatch_queue_s) <= 128, "dispatch queue size");
-#endif
 #endif // !defined(__cplusplus) || !DISPATCH_INTROSPECTION
 
 DISPATCH_INTERNAL_SUBCLASS_DECL(queue_serial, queue);
@@ -556,51 +545,51 @@
 #define DISPATCH_QUEUE_WAKEUP_MGR            (&_dispatch_mgr_q)
 #define DISPATCH_QUEUE_WAKEUP_WAIT_FOR_EVENT ((dispatch_queue_wakeup_target_t)-1)
 
+void _dispatch_queue_class_wakeup_with_override(dispatch_queue_t dq,
+		dispatch_qos_t qos, dispatch_wakeup_flags_t flags, uint64_t dq_state);
+void _dispatch_queue_class_override_drainer(dispatch_queue_t dqu,
+		dispatch_qos_t qos, dispatch_wakeup_flags_t flags);
+void _dispatch_queue_class_wakeup_enqueue(dispatch_queue_t dq,
+		dispatch_qos_t qos, dispatch_wakeup_flags_t flags,
+		dispatch_queue_wakeup_target_t target);
 void _dispatch_queue_class_wakeup(dispatch_queue_t dqu, dispatch_qos_t qos,
 		dispatch_wakeup_flags_t flags, dispatch_queue_wakeup_target_t target);
-dispatch_priority_t _dispatch_queue_compute_priority_and_wlh(
-		dispatch_queue_t dq, dispatch_wlh_t *wlh_out);
-void _dispatch_queue_destroy(dispatch_queue_t dq, bool *allow_free);
-void _dispatch_queue_dispose(dispatch_queue_t dq, bool *allow_free);
-void _dispatch_queue_xref_dispose(struct dispatch_queue_s *dq);
+
+void _dispatch_queue_destroy(dispatch_queue_t dq);
+void _dispatch_queue_dispose(dispatch_queue_t dq);
 void _dispatch_queue_set_target_queue(dispatch_queue_t dq, dispatch_queue_t tq);
 void _dispatch_queue_suspend(dispatch_queue_t dq);
 void _dispatch_queue_resume(dispatch_queue_t dq, bool activate);
-void _dispatch_queue_finalize_activation(dispatch_queue_t dq,
-		bool *allow_resume);
+void _dispatch_queue_finalize_activation(dispatch_queue_t dq);
 void _dispatch_queue_invoke(dispatch_queue_t dq,
 		dispatch_invoke_context_t dic, dispatch_invoke_flags_t flags);
 void _dispatch_global_queue_poke(dispatch_queue_t dq, int n, int floor);
 void _dispatch_queue_push(dispatch_queue_t dq, dispatch_object_t dou,
 		dispatch_qos_t qos);
+void _dispatch_try_lock_transfer_or_wakeup(dispatch_queue_t dq);
 void _dispatch_queue_wakeup(dispatch_queue_t dq, dispatch_qos_t qos,
 		dispatch_wakeup_flags_t flags);
 dispatch_queue_wakeup_target_t _dispatch_queue_serial_drain(dispatch_queue_t dq,
 		dispatch_invoke_context_t dic, dispatch_invoke_flags_t flags,
 		uint64_t *owned);
-void _dispatch_queue_drain_sync_waiter(dispatch_queue_t dq,
+void _dispatch_queue_drain_deferred_invoke(dispatch_queue_t dq,
 		dispatch_invoke_context_t dic, dispatch_invoke_flags_t flags,
-		uint64_t owned);
-void _dispatch_queue_specific_queue_dispose(
-		dispatch_queue_specific_queue_t dqsq, bool *allow_free);
+		uint64_t to_unlock);
+void _dispatch_queue_specific_queue_dispose(dispatch_queue_specific_queue_t
+		dqsq);
 void _dispatch_root_queue_wakeup(dispatch_queue_t dq, dispatch_qos_t qos,
 		dispatch_wakeup_flags_t flags);
 void _dispatch_root_queue_push(dispatch_queue_t dq, dispatch_object_t dou,
 		dispatch_qos_t qos);
-#if DISPATCH_USE_KEVENT_WORKQUEUE
-void _dispatch_root_queue_drain_deferred_item(dispatch_deferred_items_t ddi
-		DISPATCH_PERF_MON_ARGS_PROTO);
-void _dispatch_root_queue_drain_deferred_wlh(dispatch_deferred_items_t ddi
-		DISPATCH_PERF_MON_ARGS_PROTO);
-#endif
-void _dispatch_pthread_root_queue_dispose(dispatch_queue_t dq,
-		bool *allow_free);
+void _dispatch_root_queue_drain_deferred_item(dispatch_queue_t rq,
+		dispatch_queue_t dq DISPATCH_PERF_MON_ARGS_PROTO);
+void _dispatch_pthread_root_queue_dispose(dispatch_queue_t dq);
 void _dispatch_main_queue_wakeup(dispatch_queue_t dq, dispatch_qos_t qos,
 		dispatch_wakeup_flags_t flags);
 void _dispatch_runloop_queue_wakeup(dispatch_queue_t dq, dispatch_qos_t qos,
 		dispatch_wakeup_flags_t flags);
 void _dispatch_runloop_queue_xref_dispose(dispatch_queue_t dq);
-void _dispatch_runloop_queue_dispose(dispatch_queue_t dq, bool *allow_free);
+void _dispatch_runloop_queue_dispose(dispatch_queue_t dq);
 void _dispatch_mgr_queue_drain(void);
 #if DISPATCH_USE_MGR_THREAD && DISPATCH_ENABLE_PTHREAD_ROOT_QUEUES
 void _dispatch_mgr_priority_init(void);
@@ -651,13 +640,6 @@
 	_DISPATCH_ROOT_QUEUE_IDX_COUNT,
 };
 
-// skip zero
-// 1 - main_q
-// 2 - mgr_q
-// 3 - mgr_root_q
-// 4,5,6,7,8,9,10,11,12,13,14,15 - global queues
-// we use 'xadd' on Intel, so the initial value == next assigned
-#define DISPATCH_QUEUE_SERIAL_NUMBER_INIT 16
 extern unsigned long volatile _dispatch_queue_serial_numbers;
 extern struct dispatch_queue_s _dispatch_root_queues[];
 extern struct dispatch_queue_s _dispatch_mgr_q;
@@ -848,11 +830,8 @@
 	dispatch_thread_frame_s dsc_dtf;
 #endif
 	dispatch_thread_event_s dsc_event;
-	dispatch_tid dsc_waiter;
 	dispatch_qos_t dsc_override_qos_floor;
 	dispatch_qos_t dsc_override_qos;
-	bool dsc_wlh_was_first;
-	bool dsc_release_storage;
 } *dispatch_sync_context_t;
 
 typedef struct dispatch_continuation_vtable_s {
diff --git a/src/semaphore.c b/src/semaphore.c
index 3fe94c6..fa6d21a 100644
--- a/src/semaphore.c
+++ b/src/semaphore.c
@@ -52,16 +52,15 @@
 		return DISPATCH_BAD_INPUT;
 	}
 
-	dsema = (dispatch_semaphore_t)_dispatch_object_alloc(
-			DISPATCH_VTABLE(semaphore), sizeof(struct dispatch_semaphore_s));
+	dsema = (dispatch_semaphore_t)_dispatch_alloc(DISPATCH_VTABLE(semaphore),
+			sizeof(struct dispatch_semaphore_s));
 	_dispatch_semaphore_class_init(value, dsema);
 	dsema->dsema_orig = value;
 	return dsema;
 }
 
 void
-_dispatch_semaphore_dispose(dispatch_object_t dou,
-		DISPATCH_UNUSED bool *allow_free)
+_dispatch_semaphore_dispose(dispatch_object_t dou)
 {
 	dispatch_semaphore_t dsema = dou._dsema;
 
@@ -163,7 +162,7 @@
 static inline dispatch_group_t
 _dispatch_group_create_with_count(long count)
 {
-	dispatch_group_t dg = (dispatch_group_t)_dispatch_object_alloc(
+	dispatch_group_t dg = (dispatch_group_t)_dispatch_alloc(
 			DISPATCH_VTABLE(group), sizeof(struct dispatch_group_s));
 	_dispatch_semaphore_class_init(count, dg);
 	if (count) {
@@ -217,7 +216,6 @@
 		_dispatch_sema4_create(&dg->dg_sema, _DSEMA4_POLICY_FIFO);
 		_dispatch_sema4_signal(&dg->dg_sema, rval);
 	}
-	uint16_t refs = needs_release ? 1 : 0; // <rdar://problem/22318411>
 	if (head) {
 		// async group notify blocks
 		do {
@@ -226,9 +224,11 @@
 			_dispatch_continuation_async(dsn_queue, head);
 			_dispatch_release(dsn_queue);
 		} while ((head = next));
-		refs++;
+		_dispatch_release(dg);
 	}
-	if (refs) _dispatch_release_n(dg, refs);
+	if (needs_release) {
+		_dispatch_release(dg); // <rdar://problem/22318411>
+	}
 	return 0;
 }
 
@@ -246,7 +246,7 @@
 }
 
 void
-_dispatch_group_dispose(dispatch_object_t dou, DISPATCH_UNUSED bool *allow_free)
+_dispatch_group_dispose(dispatch_object_t dou)
 {
 	dispatch_group_t dg = dou._dg;
 
diff --git a/src/semaphore_internal.h b/src/semaphore_internal.h
index f9d0983..3a4ef6d 100644
--- a/src/semaphore_internal.h
+++ b/src/semaphore_internal.h
@@ -63,11 +63,11 @@
 } dispatch_semaphore_class_t DISPATCH_TRANSPARENT_UNION;
 
 dispatch_group_t _dispatch_group_create_and_enter(void);
-void _dispatch_group_dispose(dispatch_object_t dou, bool *allow_free);
+void _dispatch_group_dispose(dispatch_object_t dou);
 size_t _dispatch_group_debug(dispatch_object_t dou, char *buf,
 		size_t bufsiz);
 
-void _dispatch_semaphore_dispose(dispatch_object_t dou, bool *allow_free);
+void _dispatch_semaphore_dispose(dispatch_object_t dou);
 size_t _dispatch_semaphore_debug(dispatch_object_t dou, char *buf,
 		size_t bufsiz);
 
diff --git a/src/shims/lock.c b/src/shims/lock.c
index 617fa01..de90d60 100644
--- a/src/shims/lock.c
+++ b/src/shims/lock.c
@@ -34,7 +34,6 @@
 _Static_assert(DLOCK_LOCK_DATA_CONTENTION == ULF_WAIT_WORKQ_DATA_CONTENTION,
 		"values should be the same");
 
-#if !HAVE_UL_UNFAIR_LOCK
 DISPATCH_ALWAYS_INLINE
 static inline void
 _dispatch_thread_switch(dispatch_lock value, dispatch_lock_options_t flags,
@@ -48,7 +47,6 @@
 	}
 	thread_switch(_dispatch_lock_owner(value), option, timeout);
 }
-#endif // HAVE_UL_UNFAIR_LOCK
 #endif
 
 #pragma mark - semaphores
@@ -317,13 +315,12 @@
 _dispatch_ulock_wait(uint32_t *uaddr, uint32_t val, uint32_t timeout,
 		uint32_t flags)
 {
+	dispatch_assert(!DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK);
 	int rc;
 	_dlock_syscall_switch(err,
 		rc = __ulock_wait(UL_COMPARE_AND_WAIT | flags, uaddr, val, timeout),
 		case 0: return rc > 0 ? ENOTEMPTY : 0;
 		case ETIMEDOUT: case EFAULT: return err;
-		case EOWNERDEAD: DISPATCH_CLIENT_CRASH(*uaddr,
-				"corruption of lock owner");
 		default: DISPATCH_INTERNAL_CRASH(err, "ulock_wait() failed");
 	);
 }
@@ -331,6 +328,7 @@
 static void
 _dispatch_ulock_wake(uint32_t *uaddr, uint32_t flags)
 {
+	dispatch_assert(!DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK);
 	_dlock_syscall_switch(err,
 		__ulock_wake(UL_COMPARE_AND_WAIT | flags, uaddr, 0),
 		case 0: case ENOENT: break;
@@ -346,13 +344,17 @@
 _dispatch_unfair_lock_wait(uint32_t *uaddr, uint32_t val, uint32_t timeout,
 		dispatch_lock_options_t flags)
 {
+	if (DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK) {
+		// <rdar://problem/25075359>
+		timeout =  timeout < 1000 ? 1 : timeout / 1000;
+		_dispatch_thread_switch(val, flags, timeout);
+		return 0;
+	}
 	int rc;
 	_dlock_syscall_switch(err,
 		rc = __ulock_wait(UL_UNFAIR_LOCK | flags, uaddr, val, timeout),
 		case 0: return rc > 0 ? ENOTEMPTY : 0;
 		case ETIMEDOUT: case EFAULT: return err;
-		case EOWNERDEAD: DISPATCH_CLIENT_CRASH(*uaddr,
-				"corruption of lock owner");
 		default: DISPATCH_INTERNAL_CRASH(err, "ulock_wait() failed");
 	);
 }
@@ -360,6 +362,10 @@
 static void
 _dispatch_unfair_lock_wake(uint32_t *uaddr, uint32_t flags)
 {
+	if (DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK) {
+		// <rdar://problem/25075359>
+		return;
+	}
 	_dlock_syscall_switch(err, __ulock_wake(UL_UNFAIR_LOCK | flags, uaddr, 0),
 		case 0: case ENOENT: break;
 		default: DISPATCH_INTERNAL_CRASH(err, "ulock_wake() failed");
@@ -466,6 +472,13 @@
 void
 _dispatch_thread_event_signal_slow(dispatch_thread_event_t dte)
 {
+#if DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK
+	if (DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK) {
+		kern_return_t kr = semaphore_signal(dte->dte_sema);
+		DISPATCH_SEMAPHORE_VERIFY_KR(kr);
+		return;
+	}
+#endif
 #if HAVE_UL_COMPARE_AND_WAIT
 	_dispatch_ulock_wake(&dte->dte_value, 0);
 #elif HAVE_FUTEX
@@ -478,6 +491,16 @@
 void
 _dispatch_thread_event_wait_slow(dispatch_thread_event_t dte)
 {
+#if DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK
+	if (DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK) {
+		kern_return_t kr;
+		do {
+			kr = semaphore_wait(dte->dte_sema);
+		} while (unlikely(kr == KERN_ABORTED));
+		DISPATCH_SEMAPHORE_VERIFY_KR(kr);
+		return;
+	}
+#endif
 #if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
 	for (;;) {
 		uint32_t value = os_atomic_load(&dte->dte_value, acquire);
@@ -505,30 +528,30 @@
 _dispatch_unfair_lock_lock_slow(dispatch_unfair_lock_t dul,
 		dispatch_lock_options_t flags)
 {
-	dispatch_lock value_self = _dispatch_lock_value_for_self();
-	dispatch_lock old_value, new_value, next = value_self;
+	dispatch_lock tid_self = _dispatch_tid_self(), next = tid_self;
+	dispatch_lock tid_old, tid_new;
 	int rc;
 
 	for (;;) {
-		os_atomic_rmw_loop(&dul->dul_lock, old_value, new_value, acquire, {
-			if (likely(!_dispatch_lock_is_locked(old_value))) {
-				new_value = next;
+		os_atomic_rmw_loop(&dul->dul_lock, tid_old, tid_new, acquire, {
+			if (likely(!_dispatch_lock_is_locked(tid_old))) {
+				tid_new = next;
 			} else {
-				new_value = old_value | DLOCK_WAITERS_BIT;
-				if (new_value == old_value) os_atomic_rmw_loop_give_up(break);
+				tid_new = tid_old & ~DLOCK_NOWAITERS_BIT;
+				if (tid_new == tid_old) os_atomic_rmw_loop_give_up(break);
 			}
 		});
-		if (unlikely(_dispatch_lock_is_locked_by(old_value, value_self))) {
+		if (unlikely(_dispatch_lock_is_locked_by(tid_old, tid_self))) {
 			DISPATCH_CLIENT_CRASH(0, "trying to lock recursively");
 		}
-		if (new_value == next) {
+		if (tid_new == next) {
 			return;
 		}
-		rc = _dispatch_unfair_lock_wait(&dul->dul_lock, new_value, 0, flags);
+		rc = _dispatch_unfair_lock_wait(&dul->dul_lock, tid_new, 0, flags);
 		if (rc == ENOTEMPTY) {
-			next = value_self | DLOCK_WAITERS_BIT;
+			next = tid_self & ~DLOCK_NOWAITERS_BIT;
 		} else {
-			next = value_self;
+			next = tid_self;
 		}
 	}
 }
@@ -545,28 +568,30 @@
 _dispatch_unfair_lock_lock_slow(dispatch_unfair_lock_t dul,
 		dispatch_lock_options_t flags)
 {
-	dispatch_lock cur, value_self = _dispatch_lock_value_for_self();
+	dispatch_lock tid_cur, tid_self = _dispatch_tid_self();
 	uint32_t timeout = 1;
 
 	while (unlikely(!os_atomic_cmpxchgv(&dul->dul_lock,
-			DLOCK_OWNER_NULL, value_self, &cur, acquire))) {
-		if (unlikely(_dispatch_lock_is_locked_by(cur, self))) {
+			DLOCK_OWNER_NULL, tid_self, &tid_cur, acquire))) {
+		if (unlikely(_dispatch_lock_is_locked_by(tid_cur, tid_self))) {
 			DISPATCH_CLIENT_CRASH(0, "trying to lock recursively");
 		}
-		_dispatch_thread_switch(cur, flags, timeout++);
+		_dispatch_thread_switch(tid_cur, flags, timeout++);
 	}
 }
 #endif
 
 void
-_dispatch_unfair_lock_unlock_slow(dispatch_unfair_lock_t dul, dispatch_lock cur)
+_dispatch_unfair_lock_unlock_slow(dispatch_unfair_lock_t dul,
+		dispatch_lock tid_cur)
 {
-	if (unlikely(!_dispatch_lock_is_locked_by_self(cur))) {
-		DISPATCH_CLIENT_CRASH(cur, "lock not owned by current thread");
+	dispatch_lock_owner tid_self = _dispatch_tid_self();
+	if (unlikely(!_dispatch_lock_is_locked_by(tid_cur, tid_self))) {
+		DISPATCH_CLIENT_CRASH(tid_cur, "lock not owned by current thread");
 	}
 
 #if HAVE_UL_UNFAIR_LOCK
-	if (_dispatch_lock_has_waiters(cur)) {
+	if (!(tid_cur & DLOCK_NOWAITERS_BIT)) {
 		_dispatch_unfair_lock_wake(&dul->dul_lock, 0);
 	}
 #elif HAVE_FUTEX
@@ -583,37 +608,41 @@
 _dispatch_gate_wait_slow(dispatch_gate_t dgl, dispatch_lock value,
 		dispatch_lock_options_t flags)
 {
-	dispatch_lock self = _dispatch_lock_value_for_self();
-	dispatch_lock old_value, new_value;
+	dispatch_lock tid_self = _dispatch_tid_self(), tid_old, tid_new;
 	uint32_t timeout = 1;
 
 	for (;;) {
-		os_atomic_rmw_loop(&dgl->dgl_lock, old_value, new_value, acquire, {
-			if (likely(old_value == value)) {
+		os_atomic_rmw_loop(&dgl->dgl_lock, tid_old, tid_new, acquire, {
+			if (likely(tid_old == value)) {
 				os_atomic_rmw_loop_give_up_with_fence(acquire, return);
 			}
-			new_value = old_value | DLOCK_WAITERS_BIT;
-			if (new_value == old_value) os_atomic_rmw_loop_give_up(break);
+#ifdef DLOCK_NOWAITERS_BIT
+			tid_new = tid_old & ~DLOCK_NOWAITERS_BIT;
+#else
+			tid_new = tid_old | DLOCK_WAITERS_BIT;
+#endif
+			if (tid_new == tid_old) os_atomic_rmw_loop_give_up(break);
 		});
-		if (unlikely(_dispatch_lock_is_locked_by(old_value, self))) {
+		if (unlikely(_dispatch_lock_is_locked_by(tid_old, tid_self))) {
 			DISPATCH_CLIENT_CRASH(0, "trying to lock recursively");
 		}
 #if HAVE_UL_UNFAIR_LOCK
-		_dispatch_unfair_lock_wait(&dgl->dgl_lock, new_value, 0, flags);
+		_dispatch_unfair_lock_wait(&dgl->dgl_lock, tid_new, 0, flags);
 #elif HAVE_FUTEX
-		_dispatch_futex_wait(&dgl->dgl_lock, new_value, NULL, FUTEX_PRIVATE_FLAG);
+		_dispatch_futex_wait(&dgl->dgl_lock, tid_new, NULL, FUTEX_PRIVATE_FLAG);
 #else
-		_dispatch_thread_switch(new_value, flags, timeout++);
+		_dispatch_thread_switch(tid_new, flags, timeout++);
 #endif
 		(void)timeout;
 	}
 }
 
 void
-_dispatch_gate_broadcast_slow(dispatch_gate_t dgl, dispatch_lock cur)
+_dispatch_gate_broadcast_slow(dispatch_gate_t dgl, dispatch_lock tid_cur)
 {
-	if (unlikely(!_dispatch_lock_is_locked_by_self(cur))) {
-		DISPATCH_CLIENT_CRASH(cur, "lock not owned by current thread");
+	dispatch_lock_owner tid_self = _dispatch_tid_self();
+	if (unlikely(!_dispatch_lock_is_locked_by(tid_cur, tid_self))) {
+		DISPATCH_CLIENT_CRASH(tid_cur, "lock not owned by current thread");
 	}
 
 #if HAVE_UL_UNFAIR_LOCK
diff --git a/src/shims/lock.h b/src/shims/lock.h
index 99c5563..4bbbb42 100644
--- a/src/shims/lock.h
+++ b/src/shims/lock.h
@@ -30,87 +30,43 @@
 #pragma mark - platform macros
 
 DISPATCH_ENUM(dispatch_lock_options, uint32_t,
-	DLOCK_LOCK_NONE				= 0x00000000,
-	DLOCK_LOCK_DATA_CONTENTION  = 0x00010000,
+		DLOCK_LOCK_NONE				= 0x00000000,
+		DLOCK_LOCK_DATA_CONTENTION  = 0x00010000,
 );
 
 #if TARGET_OS_MAC
 
-typedef mach_port_t dispatch_tid;
+typedef mach_port_t dispatch_lock_owner;
 typedef uint32_t dispatch_lock;
 
+#define DLOCK_OWNER_NULL			((dispatch_lock_owner)MACH_PORT_NULL)
 #define DLOCK_OWNER_MASK			((dispatch_lock)0xfffffffc)
-#define DLOCK_WAITERS_BIT			((dispatch_lock)0x00000001)
-#define DLOCK_FAILED_TRYLOCK_BIT	((dispatch_lock)0x00000002)
-
-#define DLOCK_OWNER_NULL			((dispatch_tid)MACH_PORT_NULL)
-#define _dispatch_tid_self()		((dispatch_tid)_dispatch_thread_port())
-
-DISPATCH_ALWAYS_INLINE
-static inline dispatch_tid
-_dispatch_lock_owner(dispatch_lock lock_value)
-{
-	if (lock_value & DLOCK_OWNER_MASK) {
-		return lock_value | DLOCK_WAITERS_BIT | DLOCK_FAILED_TRYLOCK_BIT;
-	}
-	return DLOCK_OWNER_NULL;
-}
-
-#elif defined(__linux__)
-
-#include <linux/futex.h>
-#if !defined(__x86_64__) && !defined(__i386__) && !defined(__s390x__)
-#include <linux/membarrier.h>
-#endif
-#include <unistd.h>
-#include <sys/syscall.h>   /* For SYS_xxx definitions */
-
-typedef pid_t dispatch_tid;
-typedef uint32_t dispatch_lock;
-
-#define DLOCK_OWNER_MASK			((dispatch_lock)FUTEX_TID_MASK)
-#define DLOCK_WAITERS_BIT			((dispatch_lock)FUTEX_WAITERS)
-#define DLOCK_FAILED_TRYLOCK_BIT	((dispatch_lock)FUTEX_OWNER_DIED)
-
-#define DLOCK_OWNER_NULL			((dispatch_tid)0)
-#define _dispatch_tid_self()        ((dispatch_tid)(_dispatch_get_tsd_base()->tid))
-
-DISPATCH_ALWAYS_INLINE
-static inline dispatch_tid
-_dispatch_lock_owner(dispatch_lock lock_value)
-{
-	return lock_value & DLOCK_OWNER_MASK;
-}
-
-#else
-#  error define _dispatch_lock encoding scheme for your platform here
-#endif
-
-DISPATCH_ALWAYS_INLINE
-static inline dispatch_lock
-_dispatch_lock_value_from_tid(dispatch_tid tid)
-{
-	return tid & DLOCK_OWNER_MASK;
-}
-
-DISPATCH_ALWAYS_INLINE
-static inline dispatch_lock
-_dispatch_lock_value_for_self(void)
-{
-	return _dispatch_lock_value_from_tid(_dispatch_tid_self());
-}
+#define DLOCK_OWNER_INVALID			((dispatch_lock)0xffffffff)
+#define DLOCK_NOWAITERS_BIT			((dispatch_lock)0x00000001)
+#define DLOCK_NOFAILED_TRYLOCK_BIT	((dispatch_lock)0x00000002)
+#define _dispatch_tid_self()		((dispatch_lock_owner)_dispatch_thread_port())
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
 _dispatch_lock_is_locked(dispatch_lock lock_value)
 {
-	// equivalent to _dispatch_lock_owner(lock_value) == 0
 	return (lock_value & DLOCK_OWNER_MASK) != 0;
 }
 
 DISPATCH_ALWAYS_INLINE
+static inline dispatch_lock_owner
+_dispatch_lock_owner(dispatch_lock lock_value)
+{
+	lock_value &= DLOCK_OWNER_MASK;
+	if (lock_value) {
+		lock_value |= DLOCK_NOWAITERS_BIT | DLOCK_NOFAILED_TRYLOCK_BIT;
+	}
+	return lock_value;
+}
+
+DISPATCH_ALWAYS_INLINE
 static inline bool
-_dispatch_lock_is_locked_by(dispatch_lock lock_value, dispatch_tid tid)
+_dispatch_lock_is_locked_by(dispatch_lock lock_value, dispatch_lock_owner tid)
 {
 	// equivalent to _dispatch_lock_owner(lock_value) == tid
 	return ((lock_value ^ tid) & DLOCK_OWNER_MASK) == 0;
@@ -118,10 +74,57 @@
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
-_dispatch_lock_is_locked_by_self(dispatch_lock lock_value)
+_dispatch_lock_has_waiters(dispatch_lock lock_value)
 {
-	// equivalent to _dispatch_lock_owner(lock_value) == tid
-	return ((lock_value ^ _dispatch_tid_self()) & DLOCK_OWNER_MASK) == 0;
+	bool nowaiters_bit = (lock_value & DLOCK_NOWAITERS_BIT);
+	return _dispatch_lock_is_locked(lock_value) != nowaiters_bit;
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline bool
+_dispatch_lock_has_failed_trylock(dispatch_lock lock_value)
+{
+	return !(lock_value & DLOCK_NOFAILED_TRYLOCK_BIT);
+}
+
+#elif defined(__linux__)
+#include <linux/futex.h>
+#if !defined(__x86_64__) && !defined(__i386__) && !defined(__s390x__)
+#include <linux/membarrier.h>
+#endif
+#include <unistd.h>
+#include <sys/syscall.h>   /* For SYS_xxx definitions */
+
+typedef uint32_t dispatch_lock;
+typedef pid_t dispatch_lock_owner;
+
+#define DLOCK_OWNER_NULL			((dispatch_lock_owner)0)
+#define DLOCK_OWNER_MASK			((dispatch_lock)FUTEX_TID_MASK)
+#define DLOCK_OWNER_INVALID			((dispatch_lock)DLOCK_OWNER_MASK)
+#define DLOCK_WAITERS_BIT			((dispatch_lock)FUTEX_WAITERS)
+#define DLOCK_FAILED_TRYLOCK_BIT	((dispatch_lock)FUTEX_OWNER_DIED)
+#define _dispatch_tid_self() \
+		((dispatch_lock_owner)(_dispatch_get_tsd_base()->tid))
+
+DISPATCH_ALWAYS_INLINE
+static inline bool
+_dispatch_lock_is_locked(dispatch_lock lock_value)
+{
+	return (lock_value & DLOCK_OWNER_MASK) != 0;
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline dispatch_lock_owner
+_dispatch_lock_owner(dispatch_lock lock_value)
+{
+	return (lock_value & DLOCK_OWNER_MASK);
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline bool
+_dispatch_lock_is_locked_by(dispatch_lock lock_value, dispatch_lock_owner tid)
+{
+	return _dispatch_lock_owner(lock_value) == tid;
 }
 
 DISPATCH_ALWAYS_INLINE
@@ -135,18 +138,32 @@
 static inline bool
 _dispatch_lock_has_failed_trylock(dispatch_lock lock_value)
 {
-	return (lock_value & DLOCK_FAILED_TRYLOCK_BIT);
+	return !(lock_value & DLOCK_FAILED_TRYLOCK_BIT);
 }
 
+#else
+#  error define _dispatch_lock encoding scheme for your platform here
+#endif
+
 #if __has_include(<sys/ulock.h>)
 #include <sys/ulock.h>
-#ifdef UL_COMPARE_AND_WAIT
-#define HAVE_UL_COMPARE_AND_WAIT 1
 #endif
-#ifdef UL_UNFAIR_LOCK
-#define HAVE_UL_UNFAIR_LOCK 1
+
+#ifndef HAVE_UL_COMPARE_AND_WAIT
+#if defined(UL_COMPARE_AND_WAIT) && DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
+#  define HAVE_UL_COMPARE_AND_WAIT 1
+#else
+#  define HAVE_UL_COMPARE_AND_WAIT 0
 #endif
+#endif // HAVE_UL_COMPARE_AND_WAIT
+
+#ifndef HAVE_UL_UNFAIR_LOCK
+#if defined(UL_UNFAIR_LOCK) && DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
+#  define HAVE_UL_UNFAIR_LOCK 1
+#else
+#  define HAVE_UL_UNFAIR_LOCK 0
 #endif
+#endif // HAVE_UL_UNFAIR_LOCK
 
 #ifndef HAVE_FUTEX
 #ifdef __linux__
@@ -158,6 +175,14 @@
 
 #pragma mark - semaphores
 
+#ifndef DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK
+#if TARGET_OS_MAC
+#define DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK (!HAVE_UL_COMPARE_AND_WAIT)
+#else
+#define DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK 0
+#endif
+#endif
+
 #if USE_MACH_SEM
 
 typedef semaphore_t _dispatch_sema4_t;
@@ -245,7 +270,12 @@
  * This locking primitive has no notion of ownership
  */
 typedef struct dispatch_thread_event_s {
-#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
+#if DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK
+	union {
+		_dispatch_sema4_t dte_sema;
+		uint32_t dte_value;
+	};
+#elif HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
 	// 1 means signalled but not waited on yet
 	// UINT32_MAX means waited on, but not signalled yet
 	// 0 is the initial and final state
@@ -263,6 +293,13 @@
 static inline void
 _dispatch_thread_event_init(dispatch_thread_event_t dte)
 {
+#if DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK
+	if (DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK) {
+		_dispatch_sema4_init(&dte->dte_sema, _DSEMA4_POLICY_FIFO);
+		_dispatch_sema4_create(&dte->dte_sema, _DSEMA4_POLICY_FIFO);
+		return;
+	}
+#endif
 #if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
 	dte->dte_value = 0;
 #else
@@ -274,6 +311,12 @@
 static inline void
 _dispatch_thread_event_signal(dispatch_thread_event_t dte)
 {
+#if DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK
+	if (DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK) {
+		_dispatch_thread_event_signal_slow(dte);
+		return;
+	}
+#endif
 #if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
 	if (os_atomic_inc_orig(&dte->dte_value, release) == 0) {
 		// 0 -> 1 transition doesn't need a signal
@@ -292,6 +335,12 @@
 static inline void
 _dispatch_thread_event_wait(dispatch_thread_event_t dte)
 {
+#if DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK
+	if (DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK) {
+		_dispatch_thread_event_wait_slow(dte);
+		return;
+	}
+#endif
 #if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
 	if (os_atomic_dec(&dte->dte_value, acquire) == 0) {
 		// 1 -> 0 is always a valid transition, so we can return
@@ -308,6 +357,12 @@
 static inline void
 _dispatch_thread_event_destroy(dispatch_thread_event_t dte)
 {
+#if DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK
+	if (DISPATCH_LOCK_USE_SEMAPHORE_FALLBACK) {
+		_dispatch_sema4_dispose(&dte->dte_sema, _DSEMA4_POLICY_FIFO);
+		return;
+	}
+#endif
 #if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
 	// nothing to do
 	dispatch_assert(dte->dte_value == 0);
@@ -332,9 +387,9 @@
 static inline void
 _dispatch_unfair_lock_lock(dispatch_unfair_lock_t l)
 {
-	dispatch_lock value_self = _dispatch_lock_value_for_self();
+	dispatch_lock tid_self = _dispatch_tid_self();
 	if (likely(os_atomic_cmpxchg(&l->dul_lock,
-			DLOCK_OWNER_NULL, value_self, acquire))) {
+			DLOCK_OWNER_NULL, tid_self, acquire))) {
 		return;
 	}
 	return _dispatch_unfair_lock_lock_slow(l, DLOCK_LOCK_NONE);
@@ -342,42 +397,54 @@
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
-_dispatch_unfair_lock_trylock(dispatch_unfair_lock_t l, dispatch_tid *owner)
+_dispatch_unfair_lock_trylock(dispatch_unfair_lock_t l,
+		dispatch_lock_owner *owner)
 {
-	dispatch_lock value_self = _dispatch_lock_value_for_self();
-	dispatch_lock old_value, new_value;
+	dispatch_lock tid_old, tid_new, tid_self = _dispatch_tid_self();
 
-	os_atomic_rmw_loop(&l->dul_lock, old_value, new_value, acquire, {
-		if (likely(!_dispatch_lock_is_locked(old_value))) {
-			new_value = value_self;
+	os_atomic_rmw_loop(&l->dul_lock, tid_old, tid_new, acquire, {
+		if (likely(!_dispatch_lock_is_locked(tid_old))) {
+			tid_new = tid_self;
 		} else {
-			new_value = old_value | DLOCK_FAILED_TRYLOCK_BIT;
+#ifdef DLOCK_NOFAILED_TRYLOCK_BIT
+			tid_new = tid_old & ~DLOCK_NOFAILED_TRYLOCK_BIT;
+#else
+			tid_new = tid_old | DLOCK_FAILED_TRYLOCK_BIT;
+#endif
 		}
 	});
-	if (owner) *owner = _dispatch_lock_owner(new_value);
-	return !_dispatch_lock_is_locked(old_value);
+	if (owner) *owner = _dispatch_lock_owner(tid_new);
+	return !_dispatch_lock_is_locked(tid_old);
 }
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
 _dispatch_unfair_lock_tryunlock(dispatch_unfair_lock_t l)
 {
-	dispatch_lock old_value, new_value;
+	dispatch_lock tid_old, tid_new;
 
-	os_atomic_rmw_loop(&l->dul_lock, old_value, new_value, release, {
-		if (unlikely(old_value & DLOCK_FAILED_TRYLOCK_BIT)) {
-			new_value = old_value ^ DLOCK_FAILED_TRYLOCK_BIT;
+	os_atomic_rmw_loop(&l->dul_lock, tid_old, tid_new, release, {
+#ifdef DLOCK_NOFAILED_TRYLOCK_BIT
+		if (likely(tid_old & DLOCK_NOFAILED_TRYLOCK_BIT)) {
+			tid_new = DLOCK_OWNER_NULL;
 		} else {
-			new_value = DLOCK_OWNER_NULL;
+			tid_new = tid_old | DLOCK_NOFAILED_TRYLOCK_BIT;
 		}
+#else
+		if (likely(!(tid_old & DLOCK_FAILED_TRYLOCK_BIT))) {
+			tid_new = DLOCK_OWNER_NULL;
+		} else {
+			tid_new = tid_old & ~DLOCK_FAILED_TRYLOCK_BIT;
+		}
+#endif
 	});
-	if (unlikely(new_value)) {
+	if (unlikely(tid_new)) {
 		// unlock failed, renew the lock, which needs an acquire barrier
 		os_atomic_thread_fence(acquire);
 		return false;
 	}
-	if (unlikely(_dispatch_lock_has_waiters(old_value))) {
-		_dispatch_unfair_lock_unlock_slow(l, old_value);
+	if (unlikely(_dispatch_lock_has_waiters(tid_old))) {
+		_dispatch_unfair_lock_unlock_slow(l, tid_old);
 	}
 	return true;
 }
@@ -386,18 +453,18 @@
 static inline bool
 _dispatch_unfair_lock_unlock_had_failed_trylock(dispatch_unfair_lock_t l)
 {
-	dispatch_lock cur, value_self = _dispatch_lock_value_for_self();
+	dispatch_lock tid_cur, tid_self = _dispatch_tid_self();
 #if HAVE_FUTEX
 	if (likely(os_atomic_cmpxchgv(&l->dul_lock,
-			value_self, DLOCK_OWNER_NULL, &cur, release))) {
+			tid_self, DLOCK_OWNER_NULL, &tid_cur, release))) {
 		return false;
 	}
 #else
-	cur = os_atomic_xchg(&l->dul_lock, DLOCK_OWNER_NULL, release);
-	if (likely(cur == value_self)) return false;
+	tid_cur = os_atomic_xchg(&l->dul_lock, DLOCK_OWNER_NULL, release);
+	if (likely(tid_cur == tid_self)) return false;
 #endif
-	_dispatch_unfair_lock_unlock_slow(l, cur);
-	return _dispatch_lock_has_failed_trylock(cur);
+	_dispatch_unfair_lock_unlock_slow(l, tid_cur);
+	return _dispatch_lock_has_failed_trylock(tid_cur);
 }
 
 DISPATCH_ALWAYS_INLINE
@@ -440,8 +507,9 @@
 static inline bool
 _dispatch_gate_tryenter(dispatch_gate_t l)
 {
-	return os_atomic_cmpxchg(&l->dgl_lock, DLOCK_GATE_UNLOCKED,
-			_dispatch_lock_value_for_self(), acquire);
+	dispatch_lock tid_self = _dispatch_tid_self();
+	return likely(os_atomic_cmpxchg(&l->dgl_lock,
+			DLOCK_GATE_UNLOCKED, tid_self, acquire));
 }
 
 #define _dispatch_gate_wait(l, flags) \
@@ -451,18 +519,19 @@
 static inline void
 _dispatch_gate_broadcast(dispatch_gate_t l)
 {
-	dispatch_lock cur, value_self = _dispatch_lock_value_for_self();
-	cur = os_atomic_xchg(&l->dgl_lock, DLOCK_GATE_UNLOCKED, release);
-	if (likely(cur == value_self)) return;
-	_dispatch_gate_broadcast_slow(l, cur);
+	dispatch_lock tid_cur, tid_self = _dispatch_tid_self();
+	tid_cur = os_atomic_xchg(&l->dgl_lock, DLOCK_GATE_UNLOCKED, release);
+	if (likely(tid_cur == tid_self)) return;
+	_dispatch_gate_broadcast_slow(l, tid_cur);
 }
 
 DISPATCH_ALWAYS_INLINE
 static inline bool
 _dispatch_once_gate_tryenter(dispatch_once_gate_t l)
 {
-	return os_atomic_cmpxchg(&l->dgo_once, DLOCK_ONCE_UNLOCKED,
-			(dispatch_once_t)_dispatch_lock_value_for_self(), acquire);
+	dispatch_once_t tid_self = (dispatch_once_t)_dispatch_tid_self();
+	return likely(os_atomic_cmpxchg(&l->dgo_once,
+			DLOCK_ONCE_UNLOCKED, tid_self, acquire));
 }
 
 #define _dispatch_once_gate_wait(l) \
@@ -501,10 +570,11 @@
 static inline void
 _dispatch_once_gate_broadcast(dispatch_once_gate_t l)
 {
-	dispatch_lock value_self = _dispatch_lock_value_for_self();
-	dispatch_once_t cur = _dispatch_once_xchg_done(&l->dgo_once);
-	if (likely(cur == (dispatch_once_t)value_self)) return;
-	_dispatch_gate_broadcast_slow(&l->dgo_gate, (dispatch_lock)cur);
+	dispatch_once_t tid_cur, tid_self = (dispatch_once_t)_dispatch_tid_self();
+
+	tid_cur = _dispatch_once_xchg_done(&l->dgo_once);
+	if (likely(tid_cur == tid_self)) return;
+	_dispatch_gate_broadcast_slow(&l->dgo_gate, (dispatch_lock)tid_cur);
 }
 
 #endif // __DISPATCH_SHIMS_LOCK__
diff --git a/src/shims/perfmon.h b/src/shims/perfmon.h
index be9327b..fe23a1d 100644
--- a/src/shims/perfmon.h
+++ b/src/shims/perfmon.h
@@ -63,7 +63,6 @@
 #define DISPATCH_PERF_MON_ARGS_PROTO  , uint64_t perfmon_start
 #define DISPATCH_PERF_MON_ARGS        , perfmon_start
 #define DISPATCH_PERF_MON_VAR         uint64_t perfmon_start;
-#define DISPATCH_PERF_MON_VAR_INIT    uint64_t perfmon_start = 0;
 
 #define _dispatch_perfmon_start_impl(trace) ({ \
 		if (trace) _dispatch_ktrace0(DISPATCH_PERF_MON_worker_thread_start); \
@@ -85,7 +84,6 @@
 #define DISPATCH_PERF_MON_ARGS_PROTO
 #define DISPATCH_PERF_MON_ARGS
 #define DISPATCH_PERF_MON_VAR
-#define DISPATCH_PERF_MON_VAR_INIT
 #define _dispatch_perfmon_workitem_inc()
 #define _dispatch_perfmon_workitem_dec()
 #define _dispatch_perfmon_start_impl(trace)
diff --git a/src/shims/time.h b/src/shims/time.h
index 0b8e926..3010f08 100644
--- a/src/shims/time.h
+++ b/src/shims/time.h
@@ -46,15 +46,7 @@
 #define DISPATCH_CLOCK_COUNT  (DISPATCH_CLOCK_MACH + 1)
 } dispatch_clock_t;
 
-void _dispatch_time_init(void);
-
 #if defined(__i386__) || defined(__x86_64__) || !HAVE_MACH_ABSOLUTE_TIME
-#define DISPATCH_TIME_UNIT_USES_NANOSECONDS 1
-#else
-#define DISPATCH_TIME_UNIT_USES_NANOSECONDS 0
-#endif
-
-#if DISPATCH_TIME_UNIT_USES_NANOSECONDS
 // x86 currently implements mach time in nanoseconds
 // this is NOT likely to change
 DISPATCH_ALWAYS_INLINE
@@ -71,21 +63,52 @@
 	return nsec;
 }
 #else
-#define DISPATCH_USE_HOST_TIME 1
-extern uint64_t (*_dispatch_host_time_mach2nano)(uint64_t machtime);
-extern uint64_t (*_dispatch_host_time_nano2mach)(uint64_t nsec);
+typedef struct _dispatch_host_time_data_s {
+	dispatch_once_t pred;
+	long double frac;
+	bool ratio_1_to_1;
+} _dispatch_host_time_data_s;
+extern _dispatch_host_time_data_s _dispatch_host_time_data;
+void _dispatch_get_host_time_init(void *context);
+
 static inline uint64_t
 _dispatch_time_mach2nano(uint64_t machtime)
 {
-	return _dispatch_host_time_mach2nano(machtime);
+	_dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
+	dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init);
+
+	if (unlikely(!machtime || data->ratio_1_to_1)) {
+		return machtime;
+	}
+	if (machtime >= INT64_MAX) {
+		return INT64_MAX;
+	}
+	long double big_tmp = ((long double)machtime * data->frac) + .5L;
+	if (unlikely(big_tmp >= INT64_MAX)) {
+		return INT64_MAX;
+	}
+	return (uint64_t)big_tmp;
 }
 
 static inline uint64_t
 _dispatch_time_nano2mach(uint64_t nsec)
 {
-	return _dispatch_host_time_nano2mach(nsec);
+	_dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
+	dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init);
+
+	if (unlikely(!nsec || data->ratio_1_to_1)) {
+		return nsec;
+	}
+	if (nsec >= INT64_MAX) {
+		return INT64_MAX;
+	}
+	long double big_tmp = ((long double)nsec / data->frac) + .5L;
+	if (unlikely(big_tmp >= INT64_MAX)) {
+		return INT64_MAX;
+	}
+	return (uint64_t)big_tmp;
 }
-#endif // DISPATCH_USE_HOST_TIME
+#endif
 
 /* XXXRW: Some kind of overflow detection needed? */
 #define _dispatch_timespec_to_nano(ts) \
@@ -100,7 +123,7 @@
 	dispatch_static_assert(sizeof(NSEC_PER_SEC) == 8);
 	dispatch_static_assert(sizeof(USEC_PER_SEC) == 8);
 
-#if TARGET_OS_MAC
+#if TARGET_OS_MAC && DISPATCH_MIN_REQUIRED_OSX_AT_LEAST(101200)
 	return clock_gettime_nsec_np(CLOCK_REALTIME);
 #elif HAVE_DECL_CLOCK_REALTIME
 	struct timespec ts;
diff --git a/src/shims/tsd.h b/src/shims/tsd.h
index c119e4f..f3d3cea 100644
--- a/src/shims/tsd.h
+++ b/src/shims/tsd.h
@@ -65,9 +65,6 @@
 #ifndef __TSD_RETURN_TO_KERNEL
 #define __TSD_RETURN_TO_KERNEL 5
 #endif
-#ifndef __TSD_MACH_SPECIAL_REPLY
-#define __TSD_MACH_SPECIAL_REPLY 8
-#endif
 
 static const unsigned long dispatch_priority_key	= __TSD_THREAD_QOS_CLASS;
 static const unsigned long dispatch_r2k_key			= __TSD_RETURN_TO_KERNEL;
@@ -313,11 +310,6 @@
 #define _dispatch_set_thread_mig_reply_port(p) ( \
 		_dispatch_thread_setspecific(_PTHREAD_TSD_SLOT_MIG_REPLY, \
 		(void*)(uintptr_t)(p)))
-#define _dispatch_get_thread_special_reply_port() ((mach_port_t)(uintptr_t) \
-		_dispatch_thread_getspecific(__TSD_MACH_SPECIAL_REPLY))
-#define _dispatch_set_thread_special_reply_port(p) ( \
-		_dispatch_thread_setspecific(__TSD_MACH_SPECIAL_REPLY, \
-		(void*)(uintptr_t)(p)))
 #endif
 
 DISPATCH_TSD_INLINE DISPATCH_CONST
diff --git a/src/source.c b/src/source.c
index fd337a9..7c85c74 100644
--- a/src/source.c
+++ b/src/source.c
@@ -23,9 +23,7 @@
 static void _dispatch_source_handler_free(dispatch_source_t ds, long kind);
 static void _dispatch_source_set_interval(dispatch_source_t ds, uint64_t interval);
 
-#define DISPATCH_TIMERS_UNREGISTER 0x1
-#define DISPATCH_TIMERS_RETAIN_2 0x2
-static void _dispatch_timers_update(dispatch_unote_t du, uint32_t flags);
+static void _dispatch_timers_update(dispatch_unote_t du);
 static void _dispatch_timers_unregister(dispatch_timer_source_refs_t dt);
 
 static void _dispatch_source_timer_configure(dispatch_source_t ds);
@@ -42,16 +40,18 @@
 	dispatch_source_refs_t dr;
 	dispatch_source_t ds;
 
+	// ensure _dispatch_evfilt_machport_direct_enabled is initialized
+	_dispatch_root_queues_init();
+
 	dr = dux_create(dst, handle, mask)._dr;
 	if (unlikely(!dr)) {
 		return DISPATCH_BAD_INPUT;
 	}
 
-	ds = _dispatch_object_alloc(DISPATCH_VTABLE(source),
+	ds = _dispatch_alloc(DISPATCH_VTABLE(source),
 			sizeof(struct dispatch_source_s));
 	// Initialize as a queue first, then override some settings below.
-	_dispatch_queue_init(ds->_as_dq, DQF_LEGACY, 1,
-			DISPATCH_QUEUE_INACTIVE | DISPATCH_QUEUE_ROLE_INNER);
+	_dispatch_queue_init(ds->_as_dq, DQF_LEGACY, 1, true);
 	ds->dq_label = "source";
 	ds->do_ref_cnt++; // the reference the manager queue holds
 	ds->ds_refs = dr;
@@ -71,7 +71,7 @@
 }
 
 void
-_dispatch_source_dispose(dispatch_source_t ds, bool *allow_free)
+_dispatch_source_dispose(dispatch_source_t ds)
 {
 	_dispatch_object_debug(ds, "%s", __func__);
 	_dispatch_source_handler_free(ds, DS_REGISTN_HANDLER);
@@ -79,7 +79,7 @@
 	_dispatch_source_handler_free(ds, DS_CANCEL_HANDLER);
 	_dispatch_unote_dispose(ds->ds_refs);
 	ds->ds_refs = NULL;
-	_dispatch_queue_destroy(ds->_as_dq, allow_free);
+	_dispatch_queue_destroy(ds->_as_dq);
 }
 
 void
@@ -90,7 +90,7 @@
 		DISPATCH_CLIENT_CRASH(ds, "Release of a source that has not been "
 				"cancelled, but has a mandatory cancel handler");
 	}
-	dx_wakeup(ds, 0, DISPATCH_WAKEUP_MAKE_DIRTY);
+	dx_wakeup(ds, 0, DISPATCH_WAKEUP_FLUSH);
 }
 
 long
@@ -210,7 +210,7 @@
 		DISPATCH_CLIENT_CRASH(filter, "Invalid source type");
 	}
 
-	dx_wakeup(ds, _dispatch_qos_from_pp(pp), DISPATCH_WAKEUP_MAKE_DIRTY);
+	dx_wakeup(ds, _dispatch_qos_from_pp(pp), DISPATCH_WAKEUP_FLUSH);
 }
 
 void
@@ -534,7 +534,6 @@
 		// to tell the truth, it may not have happened yet
 		if (dqf & DSF_ARMED) {
 			_dispatch_timers_unregister(ds->ds_timer_refs);
-			_dispatch_release_2(ds);
 		}
 		dr->du_ident = DISPATCH_TIMER_IDENT_CANCELED;
 	} else {
@@ -556,7 +555,7 @@
 	}
 	ds->ds_is_installed = true;
 	_dispatch_debug("kevent-source[%p]: disarmed kevent[%p]", ds, dr);
-	_dispatch_release_tailcall(ds); // the retain is done at creation time
+	_dispatch_release(ds); // the retain is done at creation time
 }
 
 DISPATCH_ALWAYS_INLINE
@@ -580,7 +579,7 @@
 {
 	dispatch_source_refs_t dr = ds->ds_refs;
 	if (dr->du_is_timer) {
-		_dispatch_timers_update(dr, 0);
+		_dispatch_timers_update(dr);
 		return true;
 	}
 	if (unlikely(!_dispatch_source_tryarm(ds))) {
@@ -592,17 +591,14 @@
 }
 
 void
-_dispatch_source_refs_register(dispatch_source_t ds, dispatch_wlh_t wlh,
-		dispatch_priority_t pri)
+_dispatch_source_refs_register(dispatch_source_t ds, dispatch_priority_t pri)
 {
 	dispatch_source_refs_t dr = ds->ds_refs;
-	dispatch_priority_t kbp;
 
 	dispatch_assert(!ds->ds_is_installed);
 
 	if (dr->du_is_timer) {
-		dispatch_queue_t dq = ds->_as_dq;
-		kbp = _dispatch_queue_compute_priority_and_wlh(dq, NULL);
+		dispatch_priority_t kbp = _dispatch_source_compute_kevent_priority(ds);
 		// aggressively coalesce background/maintenance QoS timers
 		// <rdar://problem/12200216&27342536>
 		if (_dispatch_qos_is_background(_dispatch_priority_qos(kbp))) {
@@ -613,12 +609,12 @@
 				dr->du_ident = _dispatch_source_timer_idx(dr);
 			}
 		}
-		_dispatch_timers_update(dr, 0);
+		_dispatch_timers_update(dr);
 		return;
 	}
 
 	if (unlikely(!_dispatch_source_tryarm(ds) ||
-			!_dispatch_unote_register(dr, wlh, pri))) {
+			!_dispatch_unote_register(dr, ds->dq_wlh, pri))) {
 		_dispatch_queue_atomic_flags_set_and_clear(ds->_as_dq, DSF_DELETED,
 				DSF_ARMED | DSF_DEFERRED_DELETE);
 	} else {
@@ -638,22 +634,65 @@
 	}
 }
 
-DISPATCH_ALWAYS_INLINE
-static inline void
-_dispatch_source_install(dispatch_source_t ds, dispatch_wlh_t wlh,
-		dispatch_priority_t pri)
+dispatch_priority_t
+_dispatch_source_compute_kevent_priority(dispatch_source_t ds)
 {
-	_dispatch_source_refs_register(ds, wlh, pri);
+	dispatch_priority_t p = ds->dq_priority & DISPATCH_PRIORITY_REQUESTED_MASK;
+	dispatch_queue_t tq = ds->do_targetq;
+	dispatch_priority_t tqp = tq->dq_priority & DISPATCH_PRIORITY_REQUESTED_MASK;
+
+	while (unlikely(!dx_hastypeflag(tq, QUEUE_ROOT))) {
+		if (unlikely(tq == &_dispatch_mgr_q)) {
+			return DISPATCH_PRIORITY_FLAG_MANAGER;
+		}
+		if (unlikely(_dispatch_queue_is_thread_bound(tq))) {
+			// thread-bound hierarchies are weird, we need to install
+			// from the context of the thread this hierarchy is bound to
+			return 0;
+		}
+		if (unlikely(DISPATCH_QUEUE_IS_SUSPENDED(tq))) {
+			// this queue may not be activated yet, so the queue graph may not
+			// have stabilized yet
+			_dispatch_ktrace1(DISPATCH_PERF_delayed_registration, ds);
+			return 0;
+		}
+		if (unlikely(_dispatch_queue_is_legacy(tq))) {
+			if (!_dispatch_is_in_root_queues_array(tq->do_targetq)) {
+				// we're not allowed to dereference tq->do_targetq
+				_dispatch_ktrace1(DISPATCH_PERF_delayed_registration, ds);
+				return 0;
+			}
+		}
+		if (!(tq->dq_priority & DISPATCH_PRIORITY_FLAG_INHERIT)) {
+			if (p < tqp) p = tqp;
+		}
+		tq = tq->do_targetq;
+		tqp = tq->dq_priority & DISPATCH_PRIORITY_REQUESTED_MASK;
+	}
+
+	if (unlikely(!tqp)) {
+		// pthread root queues opt out of QoS
+		return 0;
+	}
+	return _dispatch_priority_inherit_from_root_queue(p, tq);
+}
+
+static void
+_dispatch_source_install(dispatch_source_t ds, dispatch_priority_t pri,
+		dispatch_wlh_t wlh)
+{
+	if (!ds->dq_wlh && wlh) {
+		_dispatch_queue_class_record_wlh_hierarchy(ds, wlh);
+	}
+	_dispatch_source_refs_register(ds, pri);
 	ds->ds_is_installed = true;
 }
 
 void
-_dispatch_source_finalize_activation(dispatch_source_t ds, bool *allow_resume)
+_dispatch_source_finalize_activation(dispatch_source_t ds)
 {
 	dispatch_continuation_t dc;
 	dispatch_source_refs_t dr = ds->ds_refs;
-	dispatch_priority_t pri;
-	dispatch_wlh_t wlh;
 
 	if (unlikely(dr->du_is_direct &&
 			(_dispatch_queue_atomic_flags(ds->_as_dq) & DSF_CANCELED))) {
@@ -673,12 +712,15 @@
 	}
 
 	// call "super"
-	_dispatch_queue_finalize_activation(ds->_as_dq, allow_resume);
+	_dispatch_queue_finalize_activation(ds->_as_dq);
 
 	if (dr->du_is_direct && !ds->ds_is_installed) {
-		dispatch_queue_t dq = ds->_as_dq;
-		pri = _dispatch_queue_compute_priority_and_wlh(dq, &wlh);
-		if (pri) _dispatch_source_install(ds, wlh, pri);
+		dispatch_priority_t pri = _dispatch_source_compute_kevent_priority(ds);
+		if (pri) {
+			dispatch_wlh_t wlh = ds->dq_wlh;
+			if (!wlh) wlh = _dispatch_queue_class_compute_wlh(ds);
+			_dispatch_source_install(ds, pri, wlh);
+		}
 	}
 }
 
@@ -690,18 +732,8 @@
 	dispatch_source_t ds = dou._ds;
 	dispatch_queue_wakeup_target_t retq = DISPATCH_QUEUE_WAKEUP_NONE;
 	dispatch_queue_t dq = _dispatch_queue_get_current();
-	dispatch_source_refs_t dr = ds->ds_refs;
-	dispatch_queue_flags_t dqf;
 
-	if (!(flags & DISPATCH_INVOKE_MANAGER_DRAIN) &&
-			_dispatch_unote_wlh_changed(dr, _dispatch_get_wlh())) {
-		dqf = _dispatch_queue_atomic_flags_set_orig(ds->_as_dq,
-				DSF_WLH_CHANGED);
-		if (!(dqf & DSF_WLH_CHANGED)) {
-			_dispatch_bug_deprecated("Changing target queue "
-					"hierarchy after source was activated");
-		}
-	}
+	flags |= DISPATCH_INVOKE_DISALLOW_SYNC_WAITERS;
 
 	if (_dispatch_queue_class_probe(ds)) {
 		// Intentionally always drain even when on the manager queue
@@ -719,7 +751,9 @@
 
 	// The order of tests here in invoke and in wakeup should be consistent.
 
+	dispatch_source_refs_t dr = ds->ds_refs;
 	dispatch_queue_t dkq = &_dispatch_mgr_q;
+	dispatch_queue_flags_t dqf;
 	bool prevent_starvation = false;
 
 	if (dr->du_is_direct) {
@@ -743,8 +777,8 @@
 		if (dq != dkq) {
 			return dkq;
 		}
-		_dispatch_source_install(ds, _dispatch_get_wlh(),
-				_dispatch_get_basepri());
+		_dispatch_source_install(ds, _dispatch_get_basepri(),
+				_dispatch_get_wlh());
 	}
 
 	if (unlikely(DISPATCH_QUEUE_IS_SUSPENDED(ds))) {
@@ -851,7 +885,7 @@
 			// from the source handler
 			return ds->do_targetq;
 		}
-		if (prevent_starvation && dr->du_wlh == DISPATCH_WLH_ANON) {
+		if (prevent_starvation && dr->du_wlh == DISPATCH_WLH_GLOBAL) {
 			// keep the old behavior to force re-enqueue to our target queue
 			// for the rearm.
 			//
@@ -863,7 +897,7 @@
 		if (unlikely(!_dispatch_source_refs_resume(ds))) {
 			goto unregister_event;
 		}
-		if (!prevent_starvation && _dispatch_wlh_should_poll_unote(dr)) {
+		if (!prevent_starvation && dr->du_wlh != DISPATCH_WLH_GLOBAL) {
 			// try to redrive the drain from under the lock for sources
 			// targeting an overcommit root queue to avoid parking
 			// when the next event has already fired
@@ -879,8 +913,7 @@
 _dispatch_source_invoke(dispatch_source_t ds, dispatch_invoke_context_t dic,
 		dispatch_invoke_flags_t flags)
 {
-	_dispatch_queue_class_invoke(ds, dic, flags,
-			DISPATCH_INVOKE_DISALLOW_SYNC_WAITERS, _dispatch_source_invoke2);
+	_dispatch_queue_class_invoke(ds, dic, flags, _dispatch_source_invoke2);
 }
 
 void
@@ -945,12 +978,13 @@
 		tq = DISPATCH_QUEUE_WAKEUP_TARGET;
 	}
 
-	if ((tq == DISPATCH_QUEUE_WAKEUP_TARGET) &&
-			ds->do_targetq == &_dispatch_mgr_q) {
-		tq = DISPATCH_QUEUE_WAKEUP_MGR;
+	if (tq) {
+		return _dispatch_queue_class_wakeup(ds->_as_dq, qos, flags, tq);
+	} else if (qos) {
+		return _dispatch_queue_class_override_drainer(ds->_as_dq, qos, flags);
+	} else if (flags & DISPATCH_WAKEUP_CONSUME) {
+		return _dispatch_release_tailcall(ds);
 	}
-
-	return _dispatch_queue_class_wakeup(ds->_as_dq, qos, flags, tq);
 }
 
 void
@@ -961,13 +995,13 @@
 	// could potentially invoke the source, do the cancellation,
 	// unregister the source, and deallocate it. We would
 	// need to therefore retain/release before setting the bit
-	_dispatch_retain_2(ds);
+	_dispatch_retain(ds);
 
 	dispatch_queue_t q = ds->_as_dq;
 	if (_dispatch_queue_atomic_flags_set_orig(q, DSF_CANCELED) & DSF_CANCELED) {
-		_dispatch_release_2_tailcall(ds);
+		_dispatch_release_tailcall(ds);
 	} else {
-		dx_wakeup(ds, 0, DISPATCH_WAKEUP_MAKE_DIRTY | DISPATCH_WAKEUP_CONSUME_2);
+		dx_wakeup(ds, 0, DISPATCH_WAKEUP_FLUSH | DISPATCH_WAKEUP_CONSUME);
 	}
 }
 
@@ -1002,12 +1036,13 @@
 		return;
 	}
 	if (dqf & DSF_CANCEL_WAITER) {
-		goto wakeup;
+		goto override;
 	}
 
 	// simplified version of _dispatch_queue_drain_try_lock
 	// that also sets the DIRTY bit on failure to lock
-	uint64_t set_owner_and_set_full_width = _dispatch_lock_value_for_self() |
+	dispatch_lock_owner tid_self = _dispatch_tid_self();
+	uint64_t xor_owner_and_set_full_width = tid_self |
 			DISPATCH_QUEUE_WIDTH_FULL_BIT | DISPATCH_QUEUE_IN_BARRIER;
 	uint64_t old_state, new_state;
 
@@ -1016,7 +1051,7 @@
 		if (likely(_dq_state_is_runnable(old_state) &&
 				!_dq_state_drain_locked(old_state))) {
 			new_state &= DISPATCH_QUEUE_DRAIN_PRESERVED_BITS_MASK;
-			new_state |= set_owner_and_set_full_width;
+			new_state ^= xor_owner_and_set_full_width;
 		} else if (old_dqf & DSF_CANCELED) {
 			os_atomic_rmw_loop_give_up(break);
 		} else {
@@ -1046,15 +1081,15 @@
 				_dispatch_source_cancel_callout(ds, NULL, DISPATCH_INVOKE_NONE);
 			}
 		}
-		dx_wakeup(ds, 0, DISPATCH_WAKEUP_BARRIER_COMPLETE);
-	} else if (unlikely(_dq_state_drain_locked_by_self(old_state))) {
+		_dispatch_try_lock_transfer_or_wakeup(ds->_as_dq);
+	} else if (unlikely(_dq_state_drain_locked_by(old_state, tid_self))) {
 		DISPATCH_CLIENT_CRASH(ds, "dispatch_source_cancel_and_wait "
 				"called from a source handler");
 	} else {
 		dispatch_qos_t qos;
-wakeup:
+override:
 		qos = _dispatch_qos_from_pp(_dispatch_get_priority());
-		dx_wakeup(ds, qos, DISPATCH_WAKEUP_MAKE_DIRTY);
+		dx_wakeup(ds, qos, DISPATCH_WAKEUP_OVERRIDING | DISPATCH_WAKEUP_FLUSH);
 		dispatch_activate(ds);
 	}
 
@@ -1086,8 +1121,8 @@
 		// threads running _dispatch_source_invoke2 to dispose of the source,
 		// so we can't safely borrow the reference we get from the muxnote udata
 		// anymore, and need our own
-		wflags = DISPATCH_WAKEUP_CONSUME_2;
-		_dispatch_retain_2(ds); // rdar://20382435
+		wflags = DISPATCH_WAKEUP_CONSUME;
+		_dispatch_retain(ds); // rdar://20382435
 	}
 
 	if ((flags & EV_UDATA_SPECIFIC) && (flags & EV_ONESHOT) &&
@@ -1153,7 +1188,7 @@
 
 done:
 	_dispatch_object_debug(ds, "%s", __func__);
-	dx_wakeup(ds, _dispatch_qos_from_pp(pp), wflags | DISPATCH_WAKEUP_MAKE_DIRTY);
+	dx_wakeup(ds, _dispatch_qos_from_pp(pp), wflags | DISPATCH_WAKEUP_FLUSH);
 }
 
 #pragma mark -
@@ -1232,7 +1267,7 @@
 		// Clear any pending data that might have accumulated on
 		// older timer params <rdar://problem/8574886>
 		os_atomic_store2o(ds, ds_pending_data, 0, relaxed);
-		_dispatch_timers_update(dt, 0);
+		_dispatch_timers_update(dt);
 	}
 }
 
@@ -1308,7 +1343,7 @@
 	_dispatch_source_timer_telemetry(ds, dtc->dtc_clock, &dtc->dtc_timer);
 	dtc = os_atomic_xchg2o(dt, dt_pending_config, dtc, release);
 	if (dtc) free(dtc);
-	dx_wakeup(ds, 0, DISPATCH_WAKEUP_MAKE_DIRTY);
+	dx_wakeup(ds, 0, DISPATCH_WAKEUP_FLUSH);
 }
 
 static void
@@ -1761,9 +1796,6 @@
 {
 	uint32_t idx = (dth->dth_count += DTH_ID_COUNT) - DTH_ID_COUNT;
 
-	dispatch_assert(dt->dt_heap_entry[DTH_TARGET_ID] == DTH_INVALID_ID);
-	dispatch_assert(dt->dt_heap_entry[DTH_DEADLINE_ID] == DTH_INVALID_ID);
-
 	if (idx == 0) {
 		dt->dt_heap_entry[DTH_TARGET_ID] = DTH_TARGET_ID;
 		dt->dt_heap_entry[DTH_DEADLINE_ID] = DTH_DEADLINE_ID;
@@ -1782,36 +1814,27 @@
 DISPATCH_NOINLINE
 static void
 _dispatch_timer_heap_remove(dispatch_timer_heap_t dth,
-		dispatch_timer_source_refs_t dt)
+		dispatch_timer_source_refs_t removed_dt)
 {
 	uint32_t idx = (dth->dth_count -= DTH_ID_COUNT);
 
-	dispatch_assert(dt->dt_heap_entry[DTH_TARGET_ID] != DTH_INVALID_ID);
-	dispatch_assert(dt->dt_heap_entry[DTH_DEADLINE_ID] != DTH_INVALID_ID);
-
 	if (idx == 0) {
-		dispatch_assert(dth->dth_min[DTH_TARGET_ID] == dt);
-		dispatch_assert(dth->dth_min[DTH_DEADLINE_ID] == dt);
 		dth->dth_min[DTH_TARGET_ID] = dth->dth_min[DTH_DEADLINE_ID] = NULL;
-		goto clear_heap_entry;
+		return;
 	}
 
 	for (uint32_t heap_id = 0; heap_id < DTH_ID_COUNT; heap_id++) {
-		dispatch_timer_source_refs_t *slot, last_dt;
+		dispatch_timer_source_refs_t *slot, dt;
 		slot = _dispatch_timer_heap_get_slot(dth, idx + heap_id);
-		last_dt = *slot; *slot = NULL;
-		if (last_dt != dt) {
-			uint32_t removed_idx = dt->dt_heap_entry[heap_id];
-			_dispatch_timer_heap_resift(dth, last_dt, removed_idx);
+		dt = *slot; *slot = NULL;
+		if (dt != removed_dt) {
+			uint32_t removed_idx = removed_dt->dt_heap_entry[heap_id];
+			_dispatch_timer_heap_resift(dth, dt, removed_idx);
 		}
 	}
 	if (unlikely(idx <= _dispatch_timer_heap_capacity(dth->dth_segments - 1))) {
 		_dispatch_timer_heap_shrink(dth);
 	}
-
-clear_heap_entry:
-	dt->dt_heap_entry[DTH_TARGET_ID] = DTH_INVALID_ID;
-	dt->dt_heap_entry[DTH_DEADLINE_ID] = DTH_INVALID_ID;
 }
 
 DISPATCH_ALWAYS_INLINE
@@ -1819,9 +1842,6 @@
 _dispatch_timer_heap_update(dispatch_timer_heap_t dth,
 		dispatch_timer_source_refs_t dt)
 {
-	dispatch_assert(dt->dt_heap_entry[DTH_TARGET_ID] != DTH_INVALID_ID);
-	dispatch_assert(dt->dt_heap_entry[DTH_DEADLINE_ID] != DTH_INVALID_ID);
-
 	_dispatch_timer_heap_resift(dth, dt, dt->dt_heap_entry[DTH_TARGET_ID]);
 	_dispatch_timer_heap_resift(dth, dt, dt->dt_heap_entry[DTH_DEADLINE_ID]);
 }
@@ -1866,7 +1886,6 @@
 	_dispatch_timer_heap_remove(heap, dt);
 	_dispatch_timers_reconfigure = true;
 	_dispatch_timers_processing_mask |= 1 << tidx;
-	dispatch_assert(dt->du_wlh == NULL || dt->du_wlh == DISPATCH_WLH_ANON);
 	dt->du_wlh = NULL;
 }
 
@@ -1883,8 +1902,7 @@
 	}
 	_dispatch_timers_reconfigure = true;
 	_dispatch_timers_processing_mask |= 1 << tidx;
-	dispatch_assert(dt->du_wlh == NULL || dt->du_wlh == DISPATCH_WLH_ANON);
-	dt->du_wlh = DISPATCH_WLH_ANON;
+	dt->du_wlh = DISPATCH_WLH_GLOBAL;
 }
 
 DISPATCH_ALWAYS_INLINE
@@ -1904,7 +1922,7 @@
 // Updates the ordered list of timers based on next fire date for changes to ds.
 // Should only be called from the context of _dispatch_mgr_q.
 static void
-_dispatch_timers_update(dispatch_unote_t du, uint32_t flags)
+_dispatch_timers_update(dispatch_unote_t du)
 {
 	dispatch_timer_source_refs_t dr = du._dt;
 	dispatch_source_t ds = _dispatch_source_from_refs(dr);
@@ -1914,47 +1932,26 @@
 	DISPATCH_ASSERT_ON_MANAGER_QUEUE();
 
 	if (unlikely(dr->du_ident == DISPATCH_TIMER_IDENT_CANCELED)) {
-		dispatch_assert((flags & DISPATCH_TIMERS_RETAIN_2) == 0);
 		return;
 	}
 
 	// Unregister timers that are unconfigured, disabled, suspended or have
 	// missed intervals. Rearm after dispatch_set_timer(), resume or source
 	// invoke will reenable them
-	will_register = !(flags & DISPATCH_TIMERS_UNREGISTER) &&
-			dr->dt_timer.target < INT64_MAX &&
+	will_register = dr->dt_timer.target < INT64_MAX &&
 			!os_atomic_load2o(ds, ds_pending_data, relaxed) &&
 			!DISPATCH_QUEUE_IS_SUSPENDED(ds) &&
 			!os_atomic_load2o(dr, dt_pending_config, relaxed);
-	if (likely(!_dispatch_unote_registered(dr))) {
-		dispatch_assert((flags & DISPATCH_TIMERS_RETAIN_2) == 0);
-		if (unlikely(!will_register || !_dispatch_source_timer_tryarm(ds))) {
+	if (!_dispatch_unote_registered(dr) && will_register) {
+		if (unlikely(!_dispatch_source_timer_tryarm(ds))) {
 			return;
 		}
 		verb = "armed";
-	} else if (unlikely(!will_register)) {
+	} else if (unlikely(_dispatch_unote_registered(dr) && !will_register)) {
 		disarm = true;
 		verb = "disarmed";
 	}
 
-	// The heap owns a +2 on dispatch sources it references
-	//
-	// _dispatch_timers_run2() also sometimes passes DISPATCH_TIMERS_RETAIN_2
-	// when it wants to take over this +2 at the same time we are unregistering
-	// the timer from the heap.
-	//
-	// Compute our refcount balance according to these rules, if our balance
-	// would become negative we retain the source upfront, if it is positive, we
-	// get rid of the extraneous refcounts after we're done touching the source.
-	int refs = will_register ? -2 : 0;
-	if (_dispatch_unote_registered(dr) && !(flags & DISPATCH_TIMERS_RETAIN_2)) {
-		refs += 2;
-	}
-	if (refs < 0) {
-		dispatch_assert(refs == -2);
-		_dispatch_retain_2(ds);
-	}
-
 	uint32_t tidx = _dispatch_source_timer_idx(dr);
 	if (unlikely(_dispatch_unote_registered(dr) &&
 			(!will_register || dr->du_ident != tidx))) {
@@ -1969,10 +1966,6 @@
 	}
 	_dispatch_debug("kevent-source[%p]: %s timer[%p]", ds, verb, dr);
 	_dispatch_object_debug(ds, "%s", __func__);
-	if (refs > 0) {
-		dispatch_assert(refs == 2);
-		_dispatch_release_2_tailcall(ds);
-	}
 }
 
 #define DISPATCH_TIMER_MISSED_MARKER  1ul
@@ -2065,19 +2058,21 @@
 			continue;
 		}
 
+		_dispatch_retain(ds);
 		data = os_atomic_load2o(ds, ds_pending_data, relaxed);
 		if (unlikely(data)) {
 			// the release barrier is required to make the changes
 			// to `ds_timer` visible to _dispatch_source_timer_data()
 			if (os_atomic_cmpxchg2o(ds, ds_pending_data, data,
 					data | DISPATCH_TIMER_MISSED_MARKER, release)) {
-				_dispatch_timers_update(dr, DISPATCH_TIMERS_UNREGISTER);
+				_dispatch_timers_update(dr);
+				_dispatch_release(ds);
 				continue;
 			}
 		}
 
 		data = _dispatch_source_timer_compute_missed(dr, now, 0);
-		_dispatch_timers_update(dr, DISPATCH_TIMERS_RETAIN_2);
+		_dispatch_timers_update(dr);
 		pending_data = data << 1;
 		if (!_dispatch_unote_registered(dr) && dr->dt_timer.target < INT64_MAX){
 			// if we unregistered because of suspension we have to fake we
@@ -2090,7 +2085,7 @@
 		_dispatch_trace_timer_fire(dr, data, data);
 		_dispatch_debug("kevent-source[%p]: fired timer[%p]", ds, dr);
 		_dispatch_object_debug(ds, "%s", __func__);
-		dx_wakeup(ds, 0, DISPATCH_WAKEUP_MAKE_DIRTY | DISPATCH_WAKEUP_CONSUME_2);
+		dx_wakeup(ds, 0, DISPATCH_WAKEUP_FLUSH | DISPATCH_WAKEUP_CONSUME);
 	}
 }
 
@@ -2259,46 +2254,55 @@
 #pragma mark dispatch_mgr
 
 void
-_dispatch_mgr_queue_push(dispatch_queue_t dq, dispatch_object_t dou,
-		DISPATCH_UNUSED dispatch_qos_t qos)
+_dispatch_mgr_queue_wakeup(dispatch_queue_t dq,
+		dispatch_qos_t qos, dispatch_wakeup_flags_t flags)
 {
-	uint64_t dq_state;
-	_dispatch_trace_continuation_push(dq, dou._do);
-	if (unlikely(_dispatch_queue_push_update_tail(dq, dou._do))) {
-		_dispatch_queue_push_update_head(dq, dou._do);
-		dq_state = os_atomic_or2o(dq, dq_state, DISPATCH_QUEUE_DIRTY, release);
-		if (!_dq_state_drain_locked_by_self(dq_state)) {
-			_dispatch_event_loop_poke(DISPATCH_WLH_MANAGER, 0, 0);
-		}
+	if (flags & DISPATCH_WAKEUP_FLUSH) {
+		os_atomic_or2o(dq, dq_state, DISPATCH_QUEUE_DIRTY, release);
 	}
-}
 
-DISPATCH_NORETURN
-void
-_dispatch_mgr_queue_wakeup(DISPATCH_UNUSED dispatch_queue_t dq,
-		DISPATCH_UNUSED dispatch_qos_t qos,
-		DISPATCH_UNUSED dispatch_wakeup_flags_t flags)
-{
-	DISPATCH_INTERNAL_CRASH(0, "Don't try to wake up or override the manager");
+	if (_dispatch_queue_get_current() == &_dispatch_mgr_q) {
+		return;
+	}
+
+	if (!_dispatch_queue_class_probe(&_dispatch_mgr_q)) {
+		return;
+	}
+
+	_dispatch_event_loop_poke(DISPATCH_WLH_MANAGER, qos, 0);
 }
 
 #if DISPATCH_USE_MGR_THREAD
+DISPATCH_NOINLINE
+static void
+_dispatch_mgr_init(void)
+{
+	uint64_t owned = DISPATCH_QUEUE_SERIAL_DRAIN_OWNED;
+	_dispatch_queue_set_current(&_dispatch_mgr_q);
+	if (_dispatch_queue_drain_try_lock(&_dispatch_mgr_q,
+			DISPATCH_INVOKE_STEALING, NULL) != owned) {
+		DISPATCH_INTERNAL_CRASH(0, "Locking the manager should not fail");
+	}
+	_dispatch_mgr_priority_init();
+	_dispatch_event_loop_init();
+}
+
 DISPATCH_NOINLINE DISPATCH_NORETURN
 static void
 _dispatch_mgr_invoke(void)
 {
-#if DISPATCH_EVENT_BACKEND_KEVENT
-	dispatch_kevent_s evbuf[DISPATCH_DEFERRED_ITEMS_EVENT_COUNT];
-#endif
-	dispatch_deferred_items_s ddi = {
-#if DISPATCH_EVENT_BACKEND_KEVENT
-		.ddi_maxevents = DISPATCH_DEFERRED_ITEMS_EVENT_COUNT,
-		.ddi_eventlist = evbuf,
-#endif
-	};
+	dispatch_deferred_items_s ddi;
 	bool poll;
 
+	ddi.ddi_stashed_pri = DISPATCH_PRIORITY_NOSTASH;
+	ddi.ddi_stashed_dq = NULL;
+	ddi.ddi_stashed_rq = NULL;
+#if DISPATCH_EVENT_BACKEND_KEVENT
+	ddi.ddi_nevents = 0;
+#endif
+	dispatch_assert(_dispatch_get_wlh() == DISPATCH_WLH_GLOBAL);
 	_dispatch_deferred_items_set(&ddi);
+
 	for (;;) {
 		_dispatch_mgr_queue_drain();
 		poll = _dispatch_mgr_timers();
@@ -2321,9 +2325,7 @@
 	}
 #endif
 #if DISPATCH_USE_MGR_THREAD
-	_dispatch_queue_set_current(&_dispatch_mgr_q);
-	_dispatch_mgr_priority_init();
-	_dispatch_queue_mgr_lock(&_dispatch_mgr_q);
+	_dispatch_mgr_init();
 	// never returns, so burn bridges behind us & clear stack 2k ahead
 	_dispatch_clear_stack(2048);
 	_dispatch_mgr_invoke();
@@ -2344,8 +2346,14 @@
 		dispatch_deferred_items_t ddi)
 {
 	dispatch_assert(wlh);
+	uint64_t owned = DISPATCH_QUEUE_SERIAL_DRAIN_OWNED;
 	dispatch_priority_t old_dbp;
 
+	ddi->ddi_stashed_pri = DISPATCH_PRIORITY_NOSTASH;
+	ddi->ddi_stashed_dq = NULL;
+	ddi->ddi_stashed_rq = NULL;
+	ddi->ddi_nevents = 0;
+
 	pthread_priority_t pp = _dispatch_get_priority();
 	if (!(pp & _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG)) {
 		// If this thread does not have the event manager flag set, don't setup
@@ -2355,7 +2363,7 @@
 		// Also add the NEEDS_UNBIND flag so that
 		// _dispatch_priority_compute_update knows it has to unbind
 		pp &= _PTHREAD_PRIORITY_OVERCOMMIT_FLAG | ~_PTHREAD_PRIORITY_FLAGS_MASK;
-		if (wlh == DISPATCH_WLH_ANON) {
+		if (wlh == DISPATCH_WLH_GLOBAL) {
 			pp |= _PTHREAD_PRIORITY_NEEDS_UNBIND_FLAG;
 		} else {
 			// pthread sets the flag when it is an event delivery thread
@@ -2364,10 +2372,9 @@
 		}
 		_dispatch_thread_setspecific(dispatch_priority_key,
 				(void *)(uintptr_t)pp);
-		if (wlh != DISPATCH_WLH_ANON) {
+		ddi->ddi_stashed_pri = 0;
+		if (wlh != DISPATCH_WLH_GLOBAL) {
 			_dispatch_debug("wlh[%p]: handling events", wlh);
-		} else {
-			ddi->ddi_can_stash = true;
 		}
 		return DISPATCH_KEVENT_WORKER_IS_NOT_MANAGER;
 	}
@@ -2397,7 +2404,15 @@
 	// ensure kevents registered from this thread are registered at manager QoS
 	old_dbp = _dispatch_set_basepri(DISPATCH_PRIORITY_FLAG_MANAGER);
 	_dispatch_queue_set_current(&_dispatch_mgr_q);
-	_dispatch_queue_mgr_lock(&_dispatch_mgr_q);
+	if (_dispatch_queue_drain_try_lock(&_dispatch_mgr_q,
+			DISPATCH_INVOKE_STEALING, NULL) != owned) {
+		DISPATCH_INTERNAL_CRASH(0, "Locking the manager should not fail");
+	}
+	static int event_thread_init;
+	if (!event_thread_init) {
+		event_thread_init = 1;
+		_dispatch_event_loop_init();
+	}
 	return old_dbp;
 }
 
@@ -2405,35 +2420,38 @@
 static inline bool
 _dispatch_wlh_worker_thread_reset(dispatch_priority_t old_dbp)
 {
-	bool needs_poll = _dispatch_queue_mgr_unlock(&_dispatch_mgr_q);
+	dispatch_queue_t dq = &_dispatch_mgr_q;
+	uint64_t orig_dq_state = DISPATCH_QUEUE_SERIAL_DRAIN_OWNED;
+
+	orig_dq_state = _dispatch_queue_drain_unlock(dq, orig_dq_state);
 	_dispatch_reset_basepri(old_dbp);
-	_dispatch_reset_basepri_override();
 	_dispatch_queue_set_current(NULL);
-	return needs_poll;
+	return _dq_state_is_dirty(orig_dq_state);
 }
 
 DISPATCH_ALWAYS_INLINE
 static void
-_dispatch_wlh_worker_thread(dispatch_wlh_t wlh, dispatch_kevent_t events,
+_dispatch_wlh_worker_thread(dispatch_wlh_t wlh, dispatch_kevent_t *events,
 		int *nevents)
 {
 	_dispatch_introspection_thread_add();
-	DISPATCH_PERF_MON_VAR_INIT
 
-	dispatch_deferred_items_s ddi = {
-		.ddi_eventlist = events,
-	};
-	dispatch_priority_t old_dbp;
+	dispatch_kevent_t ke = *events;
+	DISPATCH_PERF_MON_VAR
+	int n = *nevents;
+	if (!dispatch_assume(n) || !dispatch_assume(*events)) return;
 
-	old_dbp = _dispatch_wlh_worker_thread_init(wlh, &ddi);
+	dispatch_deferred_items_s ddi;
+	dispatch_priority_t old_dbp = _dispatch_wlh_worker_thread_init(wlh, &ddi);
 	if (old_dbp == DISPATCH_KEVENT_WORKER_IS_NOT_MANAGER) {
 		_dispatch_perfmon_start_impl(true);
 	} else {
-		dispatch_assert(wlh == DISPATCH_WLH_ANON);
-		wlh = DISPATCH_WLH_ANON;
+		dispatch_assert(wlh == DISPATCH_WLH_GLOBAL);
+		wlh = DISPATCH_WLH_GLOBAL;
 	}
+	_dispatch_set_wlh(wlh);
 	_dispatch_deferred_items_set(&ddi);
-	_dispatch_event_loop_merge(events, *nevents);
+	_dispatch_event_loop_merge(ke, n);
 
 	if (old_dbp != DISPATCH_KEVENT_WORKER_IS_NOT_MANAGER) {
 		_dispatch_mgr_queue_drain();
@@ -2442,27 +2460,34 @@
 			poll = true;
 		}
 		if (poll) _dispatch_event_loop_poke(DISPATCH_WLH_MANAGER, 0, 0);
-	} else if (ddi.ddi_stashed_dou._do) {
-		_dispatch_debug("wlh[%p]: draining deferred item %p", wlh,
-				ddi.ddi_stashed_dou._do);
-		if (wlh == DISPATCH_WLH_ANON) {
-			dispatch_assert(ddi.ddi_nevents == 0);
+	} else if (ddi.ddi_stashed_dq) {
+		if (wlh == DISPATCH_WLH_GLOBAL) {
+			if (ddi.ddi_nevents) _dispatch_event_loop_update();
 			_dispatch_deferred_items_set(NULL);
-			_dispatch_root_queue_drain_deferred_item(&ddi
-					DISPATCH_PERF_MON_ARGS);
 		} else {
-			_dispatch_root_queue_drain_deferred_wlh(&ddi
-					DISPATCH_PERF_MON_ARGS);
+			ddi.ddi_stashed_pri = DISPATCH_PRIORITY_NOSTASH;
 		}
+
+		_dispatch_debug("wlh[%p]: draining deferred item %p", wlh,
+				ddi.ddi_stashed_dq);
+		_dispatch_root_queue_drain_deferred_item(ddi.ddi_stashed_rq,
+				ddi.ddi_stashed_dq DISPATCH_PERF_MON_ARGS);
 	}
 
 	_dispatch_deferred_items_set(NULL);
-	if (old_dbp == DISPATCH_KEVENT_WORKER_IS_NOT_MANAGER &&
-			!ddi.ddi_stashed_dou._do) {
+	_dispatch_reset_wlh();
+
+	if (ddi.ddi_nevents) {
+		_dispatch_debug("flushing %d deferred kevents", ddi.ddi_nevents);
+	}
+	*nevents = ddi.ddi_nevents;
+	dispatch_static_assert(__builtin_types_compatible_p(typeof(**events),
+			typeof(*ddi.ddi_eventlist)));
+	memcpy(*events, ddi.ddi_eventlist,
+		 (size_t)ddi.ddi_nevents * sizeof(*ddi.ddi_eventlist));
+	if (old_dbp == DISPATCH_KEVENT_WORKER_IS_NOT_MANAGER && !ddi.ddi_stashed_dq) {
 		_dispatch_perfmon_end(perfmon_thread_event_no_steal);
 	}
-	_dispatch_debug("returning %d deferred kevents", ddi.ddi_nevents);
-	*nevents = ddi.ddi_nevents;
 }
 
 DISPATCH_NOINLINE
@@ -2473,10 +2498,7 @@
 		// events for worker thread request have already been delivered earlier
 		return;
 	}
-	if (!dispatch_assume(*nevents && *events)) return;
-	_dispatch_adopt_wlh_anon();
-	_dispatch_wlh_worker_thread(DISPATCH_WLH_ANON, *events, nevents);
-	_dispatch_reset_wlh();
+	return _dispatch_wlh_worker_thread(DISPATCH_WLH_GLOBAL, events, nevents);
 }
 
 
diff --git a/src/source_internal.h b/src/source_internal.h
index 55b81e7..2082274 100644
--- a/src/source_internal.h
+++ b/src/source_internal.h
@@ -98,13 +98,13 @@
 
 #endif // __cplusplus
 
-void _dispatch_source_refs_register(dispatch_source_t ds,
-		dispatch_wlh_t wlh, dispatch_priority_t bp);
+dispatch_priority_t
+_dispatch_source_compute_kevent_priority(dispatch_source_t ds);
+void _dispatch_source_refs_register(dispatch_source_t ds, dispatch_priority_t bp);
 void _dispatch_source_refs_unregister(dispatch_source_t ds, uint32_t options);
 void _dispatch_source_xref_dispose(dispatch_source_t ds);
-void _dispatch_source_dispose(dispatch_source_t ds, bool *allow_free);
-void _dispatch_source_finalize_activation(dispatch_source_t ds,
-		bool *allow_resume);
+void _dispatch_source_dispose(dispatch_source_t ds);
+void _dispatch_source_finalize_activation(dispatch_source_t ds);
 void _dispatch_source_invoke(dispatch_source_t ds,
 		dispatch_invoke_context_t dic, dispatch_invoke_flags_t flags);
 void _dispatch_source_wakeup(dispatch_source_t ds, dispatch_qos_t qos,
@@ -117,8 +117,6 @@
 void _dispatch_source_merge_data(dispatch_source_t ds, pthread_priority_t pp,
 		unsigned long val);
 
-void _dispatch_mgr_queue_push(dispatch_queue_t dq, dispatch_object_t dou,
-		dispatch_qos_t qos);
 void _dispatch_mgr_queue_wakeup(dispatch_queue_t dq, dispatch_qos_t qos,
 		dispatch_wakeup_flags_t flags);
 void _dispatch_mgr_thread(dispatch_queue_t dq, dispatch_invoke_context_t dic,
diff --git a/src/swift/DispatchStubs.cc b/src/swift/DispatchStubs.cc
index de309c7..2c76b7b 100644
--- a/src/swift/DispatchStubs.cc
+++ b/src/swift/DispatchStubs.cc
@@ -173,6 +173,12 @@
   dispatch_retain(obj);
 }
 
+// DISPATCH_RUNTIME_STDLIB_INTERFACE
+// extern "C" dispatch_queue_t
+// _swift_apply_current_root_queue() {
+// 	return DISPATCH_APPLY_CURRENT_ROOT_QUEUE;
+// }
+
 #define SOURCE(t)                                                              \
   SWIFT_CC(swift)                                                              \
   DISPATCH_RUNTIME_STDLIB_INTERFACE extern "C" dispatch_source_type_t  \
diff --git a/src/swift/Queue.swift b/src/swift/Queue.swift
index 9075e97..b7628c9 100644
--- a/src/swift/Queue.swift
+++ b/src/swift/Queue.swift
@@ -344,5 +344,8 @@
 @_silgen_name("_swift_dispatch_get_main_queue")
 internal func _swift_dispatch_get_main_queue() -> dispatch_queue_t
 
+@_silgen_name("_swift_dispatch_apply_current_root_queue")
+internal func _swift_dispatch_apply_current_root_queue() -> dispatch_queue_t
+
 @_silgen_name("_swift_dispatch_apply_current")
 internal func _swift_dispatch_apply_current(_ iterations: Int, _ block: @convention(block) (Int) -> Void)
diff --git a/src/time.c b/src/time.c
index 5b0bab0..6db4880 100644
--- a/src/time.c
+++ b/src/time.c
@@ -20,74 +20,30 @@
 
 #include "internal.h"
 
-#if DISPATCH_USE_HOST_TIME
-typedef struct _dispatch_host_time_data_s {
-	long double frac;
-	bool ratio_1_to_1;
-} _dispatch_host_time_data_s;
-
-DISPATCH_CACHELINE_ALIGN
-static _dispatch_host_time_data_s _dispatch_host_time_data;
-
-uint64_t (*_dispatch_host_time_mach2nano)(uint64_t machtime);
-uint64_t (*_dispatch_host_time_nano2mach)(uint64_t nsec);
-
-static uint64_t
-_dispatch_mach_host_time_mach2nano(uint64_t machtime)
-{
-	_dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
-
-	if (unlikely(!machtime || data->ratio_1_to_1)) {
-		return machtime;
-	}
-	if (machtime >= INT64_MAX) {
-		return INT64_MAX;
-	}
-	long double big_tmp = ((long double)machtime * data->frac) + .5L;
-	if (unlikely(big_tmp >= INT64_MAX)) {
-		return INT64_MAX;
-	}
-	return (uint64_t)big_tmp;
-}
-
-static uint64_t
-_dispatch_mach_host_time_nano2mach(uint64_t nsec)
-{
-	_dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
-
-	if (unlikely(!nsec || data->ratio_1_to_1)) {
-		return nsec;
-	}
-	if (nsec >= INT64_MAX) {
-		return INT64_MAX;
-	}
-	long double big_tmp = ((long double)nsec / data->frac) + .5L;
-	if (unlikely(big_tmp >= INT64_MAX)) {
-		return INT64_MAX;
-	}
-	return (uint64_t)big_tmp;
-}
-
-static void
-_dispatch_host_time_init(mach_timebase_info_data_t *tbi)
-{
-	_dispatch_host_time_data.frac = tbi->numer;
-	_dispatch_host_time_data.frac /= tbi->denom;
-	_dispatch_host_time_data.ratio_1_to_1 = (tbi->numer == tbi->denom);
-	_dispatch_host_time_mach2nano = _dispatch_mach_host_time_mach2nano;
-	_dispatch_host_time_nano2mach = _dispatch_mach_host_time_nano2mach;
-}
-#endif // DISPATCH_USE_HOST_TIME
+#if !(defined(__i386__) || defined(__x86_64__) || !HAVE_MACH_ABSOLUTE_TIME) \
+		|| TARGET_OS_WIN32
+DISPATCH_CACHELINE_ALIGN _dispatch_host_time_data_s _dispatch_host_time_data = {
+	.ratio_1_to_1 = true,
+};
 
 void
-_dispatch_time_init(void)
+_dispatch_get_host_time_init(void *context DISPATCH_UNUSED)
 {
-#if DISPATCH_USE_HOST_TIME
+#if !TARGET_OS_WIN32
 	mach_timebase_info_data_t tbi;
 	(void)dispatch_assume_zero(mach_timebase_info(&tbi));
-	_dispatch_host_time_init(&tbi);
-#endif // DISPATCH_USE_HOST_TIME
+	_dispatch_host_time_data.frac = tbi.numer;
+	_dispatch_host_time_data.frac /= tbi.denom;
+	_dispatch_host_time_data.ratio_1_to_1 = (tbi.numer == tbi.denom);
+#else
+	LARGE_INTEGER freq;
+	dispatch_assume(QueryPerformanceFrequency(&freq));
+	_dispatch_host_time_data.frac = (long double)NSEC_PER_SEC /
+			(long double)freq.QuadPart;
+	_dispatch_host_time_data.ratio_1_to_1 = (freq.QuadPart == 1);
+#endif	/* TARGET_OS_WIN32 */
 }
+#endif
 
 dispatch_time_t
 dispatch_time(dispatch_time_t inval, int64_t delta)
diff --git a/src/voucher.c b/src/voucher.c
index 5beadf0..9f97b7a 100644
--- a/src/voucher.c
+++ b/src/voucher.c
@@ -359,11 +359,18 @@
 #define _voucher_mach_recipe_size(payload_size) \
 	(sizeof(mach_voucher_attr_recipe_data_t) + (payload_size))
 
+#if VOUCHER_USE_MACH_VOUCHER_PRIORITY
 #define _voucher_mach_recipe_alloca(v) ((mach_voucher_attr_recipe_t)alloca(\
 		_voucher_mach_recipe_size(0) + \
 		_voucher_mach_recipe_size(sizeof(ipc_pthread_priority_value_t)) + \
 		_voucher_mach_recipe_size(sizeof(_voucher_mach_udata_s)) + \
 		_voucher_extra_size(v)))
+#else
+#define _voucher_mach_recipe_alloca(v) ((mach_voucher_attr_recipe_t)alloca(\
+		_voucher_mach_recipe_size(0) + \
+		_voucher_mach_recipe_size(sizeof(_voucher_mach_udata_s)) + \
+		_voucher_extra_size(v)))
+#endif
 
 DISPATCH_ALWAYS_INLINE
 static inline mach_voucher_attr_recipe_size_t
@@ -384,6 +391,7 @@
 	};
 	size += _voucher_mach_recipe_size(0);
 
+#if VOUCHER_USE_MACH_VOUCHER_PRIORITY
 	if (pp) {
 		ipc_pthread_priority_value_t value = (ipc_pthread_priority_value_t)pp;
 		*mvar_buf++ = (mach_voucher_attr_recipe_data_t){
@@ -394,6 +402,7 @@
 		mvar_buf = _dispatch_memappend(mvar_buf, &value);
 		size += _voucher_mach_recipe_size(sizeof(value));
 	}
+#endif // VOUCHER_USE_MACH_VOUCHER_PRIORITY
 
 	if ((v && v->v_activity) || pp) {
 		_voucher_mach_udata_s *udata_buf;
@@ -508,6 +517,29 @@
 	mach_voucher_attr_recipe_size_t kvr_size = 0;
 	mach_voucher_attr_content_size_t udata_sz = 0;
 	_voucher_mach_udata_s *udata = NULL;
+#if !VOUCHER_USE_BANK_AUTOREDEEM
+	mach_voucher_t rkv;
+	const mach_voucher_attr_recipe_data_t redeem_recipe[] = {
+		[0] = {
+			.key = MACH_VOUCHER_ATTR_KEY_ALL,
+			.command = MACH_VOUCHER_ATTR_COPY,
+			.previous_voucher = kv,
+		},
+		[1] = {
+			.key = MACH_VOUCHER_ATTR_KEY_BANK,
+			.command = MACH_VOUCHER_ATTR_REDEEM,
+		},
+	};
+	kr = _voucher_create_mach_voucher(redeem_recipe, sizeof(redeem_recipe),
+			&rkv);
+	if (!dispatch_assume_zero(kr)) {
+		_voucher_dealloc_mach_voucher(kv);
+		_dispatch_kvoucher_debug("redeemed from 0x%08x", rkv, kv);
+		kv = rkv;
+	} else {
+		_dispatch_voucher_debug_machport(kv);
+	}
+#endif
 	voucher_t v = _voucher_find_and_retain(kv);
 	if (v) {
 		_dispatch_voucher_debug("kvoucher[0x%08x] found", v, kv);
@@ -562,12 +594,15 @@
 				.key = MACH_VOUCHER_ATTR_KEY_USER_DATA,
 				.command = MACH_VOUCHER_ATTR_REMOVE,
 			},
+#if VOUCHER_USE_MACH_VOUCHER_PRIORITY
 			[2] = {
 				.key = MACH_VOUCHER_ATTR_KEY_PTHPRIORITY,
 				.command = MACH_VOUCHER_ATTR_REMOVE,
 			},
+#endif
 		};
 		mach_voucher_attr_recipe_size_t size = sizeof(remove_userdata_recipe);
+
 		kr = _voucher_create_mach_voucher(remove_userdata_recipe, size, &nkv);
 		if (!dispatch_assume_zero(kr)) {
 			_dispatch_voucher_debug("kvoucher[0x%08x] udata removal "
@@ -768,7 +803,7 @@
 {
 	_dispatch_voucher_debug("xref_dispose", voucher);
 	_voucher_remove(voucher);
-	return _os_object_release_internal_n_inline((_os_object_t)voucher, 1);
+	return _os_object_release_internal_inline((_os_object_t)voucher);
 }
 
 void
@@ -834,7 +869,6 @@
 	if (dbgp) {
 		dm = dispatch_mach_create_f("com.apple.debug-channel",
 				DISPATCH_TARGET_QUEUE_DEFAULT, NULL, handler);
-		dm->dm_recv_refs->du_can_be_wlh = false; // 29906118
 		dispatch_mach_connect(dm, dbgp, MACH_PORT_NULL, NULL);
 		// will force the DISPATCH_MACH_CONNECTED event
 		dispatch_mach_send_barrier_f(dm, NULL,
@@ -1091,13 +1125,7 @@
 	info_size = proc_pidinfo(getpid(), PROC_PIDUNIQIDENTIFIERINFO, 1,
 			&p_uniqinfo, PROC_PIDUNIQIDENTIFIERINFO_SIZE);
 	if (slowpath(info_size != PROC_PIDUNIQIDENTIFIERINFO_SIZE)) {
-		if (info_size == 0) {
-			DISPATCH_INTERNAL_CRASH(errno,
-				"Unable to get the unique pid (error)");
-		} else {
-			DISPATCH_INTERNAL_CRASH(info_size,
-				"Unable to get the unique pid (size)");
-		}
+		DISPATCH_INTERNAL_CRASH(info_size, "Unable to get the unique pid");
 	}
 	_voucher_unique_pid = p_uniqinfo.p_uniqueid;
 
@@ -1429,7 +1457,7 @@
 	size_t offset = 0;
 	#define bufprintf(...) \
 			offset += dsnprintf(&buf[offset], bufsiz - offset, ##__VA_ARGS__)
-	bufprintf("voucher[%p] = { xref = %d, ref = %d", v,
+	bufprintf("voucher[%p] = { xrefcnt = 0x%x, refcnt = 0x%x", v,
 			v->os_obj_xref_cnt + 1, v->os_obj_ref_cnt + 1);
 
 	if (v->v_kvbase) {
diff --git a/src/voucher_internal.h b/src/voucher_internal.h
index a0ddd4d..d16fc8a 100644
--- a/src/voucher_internal.h
+++ b/src/voucher_internal.h
@@ -123,7 +123,9 @@
 #define DISPATCH_VOUCHER_ACTIVITY_DEBUG 1
 #endif
 
+#if VOUCHER_USE_MACH_VOUCHER_PRIORITY
 #include <voucher/ipc_pthread_priority_types.h>
+#endif
 
 typedef uint32_t _voucher_magic_t;
 typedef uint32_t _voucher_priority_t;
@@ -262,14 +264,6 @@
 #define _dispatch_voucher_debug_machport(name) ((void)(name))
 #endif
 
-#ifndef DISPATCH_VOUCHER_OBJC_DEBUG
-#if DISPATCH_INTROSPECTION || DISPATCH_DEBUG
-#define DISPATCH_VOUCHER_OBJC_DEBUG 1
-#else
-#define DISPATCH_VOUCHER_OBJC_DEBUG 0
-#endif
-#endif // DISPATCH_VOUCHER_OBJC_DEBUG
-
 #if DISPATCH_PURE_C
 
 DISPATCH_ALWAYS_INLINE
diff --git a/xcodeconfig/libdispatch-dyld-stub.xcconfig b/xcodeconfig/libdispatch-dyld-stub.xcconfig
index dd1814d..aabda62 100644
--- a/xcodeconfig/libdispatch-dyld-stub.xcconfig
+++ b/xcodeconfig/libdispatch-dyld-stub.xcconfig
@@ -18,11 +18,11 @@
 // @APPLE_APACHE_LICENSE_HEADER_END@
 //
 
+OTHER_LDFLAGS =
+BUILD_VARIANTS = normal
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DISPATCH_VARIANT_STATIC=1 DISPATCH_VARIANT_DYLD_STUB=1 USE_OBJC=0 DISPATCH_USE_DTRACE=0
 PRODUCT_NAME = libdispatch_dyld_stub
 INSTALL_PATH = /usr/local/lib/dyld_stub
-BUILD_VARIANTS = normal
-GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DISPATCH_VARIANT_DYLD_STUB=1 $(STATICLIB_PREPROCESSOR_DEFINITIONS)
-OTHER_LDFLAGS =
-VERSIONING_SYSTEM =
 EXCLUDED_SOURCE_FILE_NAMES = *
-INCLUDED_SOURCE_FILE_NAMES = voucher.c // minimal with DISPATCH_VARIANT_DYLD_STUB
+INCLUDED_SOURCE_FILE_NAMES = voucher.c // it's minimal with DISPATCH_VARIANT_DYLD_STUB
+VERSIONING_SYSTEM =
diff --git a/xcodeconfig/libdispatch-mp-static.xcconfig b/xcodeconfig/libdispatch-mp-static.xcconfig
index af3715f..1f0eddc 100644
--- a/xcodeconfig/libdispatch-mp-static.xcconfig
+++ b/xcodeconfig/libdispatch-mp-static.xcconfig
@@ -18,12 +18,13 @@
 // @APPLE_APACHE_LICENSE_HEADER_END@
 //
 
-// skip simulator
-SUPPORTED_PLATFORMS = macosx iphoneos appletvos watchos
+OTHER_LDFLAGS =
+BUILD_VARIANTS = normal debug
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DISPATCH_VARIANT_STATIC=1 USE_OBJC=0 DISPATCH_USE_DTRACE=0
 PRODUCT_NAME = libdispatch
 INSTALL_PATH = /usr/local/lib/system
-BUILD_VARIANTS = normal debug
-GCC_PREPROCESSOR_DEFINITIONS = $(inherited) $(STATICLIB_PREPROCESSOR_DEFINITIONS)
-OTHER_LDFLAGS =
+
+// skip simulator
+SUPPORTED_PLATFORMS = macosx iphoneos appletvos watchos
 SKIP_INSTALL[sdk=*simulator*] = YES
 EXCLUDED_SOURCE_FILE_NAMES[sdk=*simulator*] = *
diff --git a/xcodeconfig/libdispatch-resolved.xcconfig b/xcodeconfig/libdispatch-resolved.xcconfig
index 2f2e273..a42add8 100644
--- a/xcodeconfig/libdispatch-resolved.xcconfig
+++ b/xcodeconfig/libdispatch-resolved.xcconfig
@@ -23,4 +23,3 @@
 OTHER_LDFLAGS =
 SKIP_INSTALL = YES
 VERSIONING_SYSTEM =
-EXCLUDED_SOURCE_FILE_NAMES = *
diff --git a/xcodeconfig/libdispatch-up-static.xcconfig b/xcodeconfig/libdispatch-up-static.xcconfig
index 170c5b3..0ece635 100644
--- a/xcodeconfig/libdispatch-up-static.xcconfig
+++ b/xcodeconfig/libdispatch-up-static.xcconfig
@@ -18,11 +18,8 @@
 // @APPLE_APACHE_LICENSE_HEADER_END@
 //
 
-// skip simulator
-SUPPORTED_PLATFORMS = macosx iphoneos appletvos watchos
-PRODUCT_NAME = libdispatch_up
-BUILD_VARIANTS = normal
-GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DISPATCH_HW_CONFIG_UP=1 $(STATICLIB_PREPROCESSOR_DEFINITIONS)
 OTHER_LDFLAGS =
+BUILD_VARIANTS = normal
 SKIP_INSTALL = YES
-EXCLUDED_SOURCE_FILE_NAMES[sdk=*simulator*] = *
+EXCLUDED_SOURCE_FILE_NAMES = *
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) USE_OBJC=0 DISPATCH_USE_DTRACE=0
diff --git a/xcodeconfig/libdispatch.order b/xcodeconfig/libdispatch.order
index a25ecc9..9642ca4 100644
--- a/xcodeconfig/libdispatch.order
+++ b/xcodeconfig/libdispatch.order
@@ -71,6 +71,18 @@
 _OBJC_METACLASS_$_OS_dispatch_queue_serial
 _OBJC_METACLASS_$_OS_dispatch_queue_concurrent
 _OBJC_METACLASS_$_OS_dispatch_queue_root
+_OBJC_METACLASS_$_OS_dispatch_queue_main
+_OBJC_METACLASS_$_OS_dispatch_queue_runloop
+_OBJC_METACLASS_$_OS_dispatch_queue_mgr
+_OBJC_METACLASS_$_OS_dispatch_queue_specific_queue
+_OBJC_METACLASS_$_OS_dispatch_queue_attr
+_OBJC_METACLASS_$_OS_dispatch_source
+_OBJC_METACLASS_$_OS_dispatch_mach
+_OBJC_METACLASS_$_OS_dispatch_mach_msg
+_OBJC_METACLASS_$_OS_dispatch_io
+_OBJC_METACLASS_$_OS_dispatch_operation
+_OBJC_METACLASS_$_OS_dispatch_disk
+_OBJC_METACLASS_$_OS_object
 _OBJC_METACLASS_$_OS_voucher
 #_OBJC_METACLASS_$_OS_voucher_recipe
 _OBJC_METACLASS_$_OS_dispatch_data
diff --git a/xcodeconfig/libdispatch.xcconfig b/xcodeconfig/libdispatch.xcconfig
index 643e1d3..a2ea6d9 100644
--- a/xcodeconfig/libdispatch.xcconfig
+++ b/xcodeconfig/libdispatch.xcconfig
@@ -71,19 +71,16 @@
 CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES
 CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES
 CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES
-CLANG_WARN_SUSPICIOUS_MOVE = YES
-CLANG_WARN_UNREACHABLE_CODE = YES
 GCC_TREAT_WARNINGS_AS_ERRORS = YES
 GCC_OPTIMIZATION_LEVEL = s
-GCC_NO_COMMON_BLOCKS = YES
 GCC_PREPROCESSOR_DEFINITIONS = __DARWIN_NON_CANCELABLE=1 $(DISPATCH_PREPROCESSOR_DEFINITIONS)
-STATICLIB_PREPROCESSOR_DEFINITIONS = DISPATCH_VARIANT_STATIC=1 USE_OBJC=0 DISPATCH_USE_DTRACE=0
+GCC_NO_COMMON_BLOCKS = YES
 WARNING_CFLAGS = -Wall -Wextra -Warray-bounds-pointer-arithmetic -Watomic-properties -Wcomma -Wconditional-uninitialized -Wcovered-switch-default -Wdate-time -Wdeprecated -Wdouble-promotion -Wduplicate-enum -Wexpansion-to-defined -Wfloat-equal -Widiomatic-parentheses -Wignored-qualifiers -Wimplicit-fallthrough -Wnullable-to-nonnull-conversion -Wobjc-interface-ivars -Wover-aligned -Wpacked -Wpointer-arith -Wselector -Wstatic-in-inline -Wsuper-class-method-mismatch -Wswitch-enum -Wtautological-compare -Wunguarded-availability -Wunused -Wno-unknown-warning-option $(NO_WARNING_CFLAGS)
 NO_WARNING_CFLAGS = -Wno-pedantic -Wno-bad-function-cast -Wno-c++-compat -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-cast-align -Wno-cast-qual -Wno-disabled-macro-expansion -Wno-documentation-unknown-command -Wno-format-nonliteral -Wno-missing-variable-declarations -Wno-old-style-cast -Wno-padded -Wno-reserved-id-macro -Wno-shift-sign-overflow -Wno-undef -Wno-unreachable-code-aggressive -Wno-unused-macros -Wno-used-but-marked-unused -Wno-vla
-OTHER_CFLAGS = -fverbose-asm -isystem $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders $(PLATFORM_CFLAGS)
+OTHER_CFLAGS = -fverbose-asm -isystem $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
 OTHER_CFLAGS[arch=i386][sdk=macosx*] = $(OTHER_CFLAGS) -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-exceptions
 OTHER_CFLAGS_normal = -momit-leaf-frame-pointer
-OTHER_CFLAGS_profile = $(OTHER_CFLAGS_normal) -DDISPATCH_PROFILE=1 -DDISPATCH_PERF_MON=1
+OTHER_CFLAGS_profile = $(OTHER_CFLAGS_normal) -DDISPATCH_PROFILE=1
 OTHER_CFLAGS_debug = -fstack-protector -fno-inline -O0 -DDISPATCH_DEBUG=1 -DOS_DEBUG=1
 GENERATE_PROFILING_CODE = NO
 DYLIB_CURRENT_VERSION = $(CURRENT_PROJECT_VERSION)
diff --git a/xcodeconfig/libfirehose.xcconfig b/xcodeconfig/libfirehose.xcconfig
index 4c71199..07a8b9a 100644
--- a/xcodeconfig/libfirehose.xcconfig
+++ b/xcodeconfig/libfirehose.xcconfig
@@ -18,17 +18,18 @@
 // @APPLE_APACHE_LICENSE_HEADER_END@
 //
 
+OTHER_MIGFLAGS = -novouchers
+OTHER_LDFLAGS =
 SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator
 PRODUCT_NAME = $(TARGET_NAME)
 INSTALL_PATH = /usr/local/lib/
-GCC_PREPROCESSOR_DEFINITIONS = $(inherited) FIREHOSE_SERVER=1 DISPATCH_USE_DTRACE=0
-OTHER_MIGFLAGS = -novouchers
-OTHER_LDFLAGS =
 PUBLIC_HEADERS_FOLDER_PATH = /usr/include/os
 PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/os
 STRIP_INSTALLED_PRODUCT = NO
 COPY_PHASE_STRIP = NO
 SEPARATE_STRIP = NO
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) FIREHOSE_SERVER=1 DISPATCH_USE_DTRACE=0
+
 VALID_ARCHS[sdk=macosx*] = $(NATIVE_ARCH_ACTUAL)
 
 COPY_HEADERS_RUN_UNIFDEF = YES
diff --git a/xcodeconfig/libfirehose_kernel.xcconfig b/xcodeconfig/libfirehose_kernel.xcconfig
index c572f80..f6b2a99 100644
--- a/xcodeconfig/libfirehose_kernel.xcconfig
+++ b/xcodeconfig/libfirehose_kernel.xcconfig
@@ -20,14 +20,16 @@
 
 #include "libfirehose.xcconfig"
 
-SUPPORTED_PLATFORMS = macosx iphoneos appletvos watchos
-PRODUCT_NAME = $(TARGET_NAME)
-INSTALL_PATH = /usr/local/lib/kernel/
-GCC_PREPROCESSOR_DEFINITIONS = $(inherited) KERNEL=1 DISPATCH_USE_DTRACE=0
 OTHER_CFLAGS = -mkernel -nostdinc -Wno-packed
 // LLVM_LTO = YES
+PRODUCT_NAME = $(TARGET_NAME)
+INSTALL_PATH = /usr/local/lib/kernel/
 PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/kernel/os
+SUPPORTED_PLATFORMS = macosx iphoneos appletvos watchos
+
 HEADER_SEARCH_PATHS = $(PROJECT_DIR) $(SDKROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders $(SDKROOT)/System/Library/Frameworks/Kernel.framework/Headers $(SDKROOT)/usr/local/include/os $(SDKROOT)/usr/local/include/firehose
 
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) KERNEL=1 DISPATCH_USE_DTRACE=0
+
 COPY_HEADERS_RUN_UNIFDEF = YES
 COPY_HEADERS_UNIFDEF_FLAGS = -DKERNEL=1 -DOS_FIREHOSE_SPI=1 -DOS_VOUCHER_ACTIVITY_SPI_TYPES=1 -UOS_VOUCHER_ACTIVITY_SPI