]> git.saurik.com Git - apple/libdispatch.git/blobdiff - src/init.c
libdispatch-913.30.4.tar.gz
[apple/libdispatch.git] / src / init.c
index 5cbf8057f36ef10fd146a7e66b597863d0b1b0c9..6672fac45dbbb2fb37391bfd420e832ce6bcf14c 100644 (file)
@@ -21,6 +21,8 @@
 // Contains exported global data and initialization & other routines that must
 // only exist once in the shared library even when resolvers are used.
 
 // 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
 #include "internal.h"
 
 #if HAVE_MACH
@@ -47,69 +49,119 @@ DISPATCH_EXPORT DISPATCH_NOTHROW
 void
 dispatch_atfork_prepare(void)
 {
 void
 dispatch_atfork_prepare(void)
 {
+       _os_object_atfork_prepare();
 }
 
 DISPATCH_EXPORT DISPATCH_NOTHROW
 void
 dispatch_atfork_parent(void)
 {
 }
 
 DISPATCH_EXPORT DISPATCH_NOTHROW
 void
 dispatch_atfork_parent(void)
 {
+       _os_object_atfork_parent();
+}
+
+DISPATCH_EXPORT DISPATCH_NOTHROW
+void
+dispatch_atfork_child(void)
+{
+       _os_object_atfork_child();
+       _voucher_atfork_child();
+       _dispatch_event_loop_atfork_child();
+       if (_dispatch_is_multithreaded_inline()) {
+               _dispatch_child_of_unsafe_fork = true;
+       }
+       _dispatch_queue_atfork_child();
+       // clear the _PROHIBIT and _MULTITHREADED bits if set
+       _dispatch_unsafe_fork = 0;
+}
+
+int
+_dispatch_sigmask(void)
+{
+       sigset_t mask;
+       int r = 0;
+
+       /* Workaround: 6269619 Not all signals can be delivered on any thread */
+       r |= sigfillset(&mask);
+       r |= sigdelset(&mask, SIGILL);
+       r |= sigdelset(&mask, SIGTRAP);
+#if HAVE_DECL_SIGEMT
+       r |= sigdelset(&mask, SIGEMT);
+#endif
+       r |= sigdelset(&mask, SIGFPE);
+       r |= sigdelset(&mask, SIGBUS);
+       r |= sigdelset(&mask, SIGSEGV);
+       r |= sigdelset(&mask, SIGSYS);
+       r |= sigdelset(&mask, SIGPIPE);
+       r |= sigdelset(&mask, SIGPROF);
+       r |= pthread_sigmask(SIG_BLOCK, &mask, NULL);
+       return dispatch_assume_zero(r);
 }
 
 #pragma mark -
 #pragma mark dispatch_globals
 
 }
 
 #pragma mark -
 #pragma mark dispatch_globals
 
+DISPATCH_HIDE_SYMBOL(dispatch_assert_queue, 10.12, 10.0, 10.0, 3.0);
+DISPATCH_HIDE_SYMBOL(dispatch_assert_queue_not, 10.12, 10.0, 10.0, 3.0);
+DISPATCH_HIDE_SYMBOL(dispatch_queue_create_with_target, 10.12, 10.0, 10.0, 3.0);
+
 #if DISPATCH_COCOA_COMPAT
 #if DISPATCH_COCOA_COMPAT
-void (*dispatch_begin_thread_4GC)(void);
-void (*dispatch_end_thread_4GC)(void);
 void *(*_dispatch_begin_NSAutoReleasePool)(void);
 void (*_dispatch_end_NSAutoReleasePool)(void *);
 #endif
 
 void *(*_dispatch_begin_NSAutoReleasePool)(void);
 void (*_dispatch_end_NSAutoReleasePool)(void *);
 #endif
 
-#if !DISPATCH_USE_DIRECT_TSD
+#if DISPATCH_USE_THREAD_LOCAL_STORAGE
+__thread struct dispatch_tsd __dispatch_tsd;
+pthread_key_t __dispatch_tsd_key;
+#elif !DISPATCH_USE_DIRECT_TSD
 pthread_key_t dispatch_queue_key;
 pthread_key_t dispatch_queue_key;
-pthread_key_t dispatch_sema4_key;
+pthread_key_t dispatch_frame_key;
 pthread_key_t dispatch_cache_key;
 pthread_key_t dispatch_cache_key;
-pthread_key_t dispatch_io_key;
-pthread_key_t dispatch_apply_key;
-pthread_key_t dispatch_defaultpriority_key;
+pthread_key_t dispatch_context_key;
+pthread_key_t dispatch_pthread_root_queue_observer_hooks_key;
+pthread_key_t dispatch_basepri_key;
 #if DISPATCH_INTROSPECTION
 pthread_key_t dispatch_introspection_key;
 #elif DISPATCH_PERF_MON
 pthread_key_t dispatch_bcounter_key;
 #endif
 #if DISPATCH_INTROSPECTION
 pthread_key_t dispatch_introspection_key;
 #elif DISPATCH_PERF_MON
 pthread_key_t dispatch_bcounter_key;
 #endif
-#endif // !DISPATCH_USE_DIRECT_TSD
+pthread_key_t dispatch_wlh_key;
+pthread_key_t dispatch_voucher_key;
+pthread_key_t dispatch_deferred_items_key;
+#endif // !DISPATCH_USE_DIRECT_TSD && !DISPATCH_USE_THREAD_LOCAL_STORAGE
 
 #if VOUCHER_USE_MACH_VOUCHER
 dispatch_once_t _voucher_task_mach_voucher_pred;
 mach_voucher_t _voucher_task_mach_voucher;
 
 #if VOUCHER_USE_MACH_VOUCHER
 dispatch_once_t _voucher_task_mach_voucher_pred;
 mach_voucher_t _voucher_task_mach_voucher;
-_voucher_activity_t _voucher_activity_default;
+#if !VOUCHER_USE_EMPTY_MACH_BASE_VOUCHER
+mach_voucher_t _voucher_default_task_mach_voucher;
 #endif
 #endif
-voucher_activity_mode_t _voucher_activity_mode;
+dispatch_once_t _firehose_task_buffer_pred;
+firehose_buffer_t _firehose_task_buffer;
+const uint32_t _firehose_spi_version = OS_FIREHOSE_SPI_VERSION;
+uint64_t _voucher_unique_pid;
+voucher_activity_hooks_t _voucher_libtrace_hooks;
+dispatch_mach_t _voucher_activity_debug_channel;
+#endif
+#if HAVE_PTHREAD_WORKQUEUE_QOS && DISPATCH_DEBUG
 int _dispatch_set_qos_class_enabled;
 int _dispatch_set_qos_class_enabled;
-
-
-DISPATCH_NOINLINE
-voucher_activity_mode_t
-voucher_activity_get_mode(void)
-{
-       return _voucher_activity_mode;
-}
-
-void
-voucher_activity_set_mode_4libtrace(voucher_activity_mode_t mode)
-{
-       if (_voucher_activity_disabled()) return;
-       _voucher_activity_mode = mode;
-}
+#endif
+#if DISPATCH_USE_KEVENT_WORKQUEUE && DISPATCH_USE_MGR_THREAD
+int _dispatch_kevent_workqueue_enabled;
+#endif
 
 DISPATCH_HW_CONFIG();
 
 DISPATCH_HW_CONFIG();
-bool _dispatch_safe_fork = true, _dispatch_child_of_unsafe_fork;
+uint8_t _dispatch_unsafe_fork;
+bool _dispatch_child_of_unsafe_fork;
+#if DISPATCH_USE_MEMORYPRESSURE_SOURCE
+bool _dispatch_memory_warn;
+int _dispatch_continuation_cache_limit = DISPATCH_CONTINUATION_CACHE_LIMIT;
+#endif
 
 DISPATCH_NOINLINE
 bool
 _dispatch_is_multithreaded(void)
 {
 
 DISPATCH_NOINLINE
 bool
 _dispatch_is_multithreaded(void)
 {
-       return !_dispatch_safe_fork;
+       return _dispatch_is_multithreaded_inline();
 }
 
 DISPATCH_NOINLINE
 }
 
 DISPATCH_NOINLINE
@@ -120,7 +172,7 @@ _dispatch_is_fork_of_multithreaded_parent(void)
 }
 
 const struct dispatch_queue_offsets_s dispatch_queue_offsets = {
 }
 
 const struct dispatch_queue_offsets_s dispatch_queue_offsets = {
-       .dqo_version = 5,
+       .dqo_version = 6,
        .dqo_label = offsetof(struct dispatch_queue_s, dq_label),
        .dqo_label_size = sizeof(((dispatch_queue_t)NULL)->dq_label),
        .dqo_flags = 0,
        .dqo_label = offsetof(struct dispatch_queue_s, dq_label),
        .dqo_label_size = sizeof(((dispatch_queue_t)NULL)->dq_label),
        .dqo_flags = 0,
@@ -129,30 +181,16 @@ const struct dispatch_queue_offsets_s dispatch_queue_offsets = {
        .dqo_serialnum_size = sizeof(((dispatch_queue_t)NULL)->dq_serialnum),
        .dqo_width = offsetof(struct dispatch_queue_s, dq_width),
        .dqo_width_size = sizeof(((dispatch_queue_t)NULL)->dq_width),
        .dqo_serialnum_size = sizeof(((dispatch_queue_t)NULL)->dq_serialnum),
        .dqo_width = offsetof(struct dispatch_queue_s, dq_width),
        .dqo_width_size = sizeof(((dispatch_queue_t)NULL)->dq_width),
-       .dqo_running = offsetof(struct dispatch_queue_s, dq_running),
-       .dqo_running_size = sizeof(((dispatch_queue_t)NULL)->dq_running),
-       .dqo_suspend_cnt = offsetof(struct dispatch_queue_s, do_suspend_cnt),
-       .dqo_suspend_cnt_size = sizeof(((dispatch_queue_t)NULL)->do_suspend_cnt),
+       .dqo_running = 0,
+       .dqo_running_size = 0,
+       .dqo_suspend_cnt = 0,
+       .dqo_suspend_cnt_size = 0,
        .dqo_target_queue = offsetof(struct dispatch_queue_s, do_targetq),
        .dqo_target_queue_size = sizeof(((dispatch_queue_t)NULL)->do_targetq),
        .dqo_target_queue = offsetof(struct dispatch_queue_s, do_targetq),
        .dqo_target_queue_size = sizeof(((dispatch_queue_t)NULL)->do_targetq),
-       .dqo_priority = offsetof(struct dispatch_queue_s, dq_priority),
-       .dqo_priority_size = sizeof(((dispatch_queue_t)NULL)->dq_priority),
+       .dqo_priority = 0,
+       .dqo_priority_size = 0,
 };
 
 };
 
-#if VOUCHER_USE_MACH_VOUCHER
-const struct voucher_offsets_s voucher_offsets = {
-       .vo_version = 1,
-       .vo_activity_ids_count = offsetof(struct voucher_s, v_activities),
-       .vo_activity_ids_count_size = sizeof(((voucher_t)NULL)->v_activities),
-       .vo_activity_ids_array = (uint16_t)_voucher_activity_ids((voucher_t)(NULL)),
-       .vo_activity_ids_array_entry_size = sizeof(voucher_activity_id_t),
-};
-#else // VOUCHER_USE_MACH_VOUCHER
-const struct voucher_offsets_s voucher_offsets = {
-       .vo_version = 0,
-};
-#endif // VOUCHER_USE_MACH_VOUCHER
-
 #if DISPATCH_USE_DIRECT_TSD
 const struct dispatch_tsd_indexes_s dispatch_tsd_indexes = {
        .dti_version = 2,
 #if DISPATCH_USE_DIRECT_TSD
 const struct dispatch_tsd_indexes_s dispatch_tsd_indexes = {
        .dti_version = 2,
@@ -160,85 +198,112 @@ const struct dispatch_tsd_indexes_s dispatch_tsd_indexes = {
        .dti_voucher_index = dispatch_voucher_key,
        .dti_qos_class_index = dispatch_priority_key,
 };
        .dti_voucher_index = dispatch_voucher_key,
        .dti_qos_class_index = dispatch_priority_key,
 };
-#else // DISPATCH_USE_DIRECT_TSD
-#error Not implemented on this platform
 #endif // DISPATCH_USE_DIRECT_TSD
 
 // 6618342 Contact the team that owns the Instrument DTrace probe before
 //         renaming this symbol
 DISPATCH_CACHELINE_ALIGN
 struct dispatch_queue_s _dispatch_main_q = {
 #endif // DISPATCH_USE_DIRECT_TSD
 
 // 6618342 Contact the team that owns the Instrument DTrace probe before
 //         renaming this symbol
 DISPATCH_CACHELINE_ALIGN
 struct dispatch_queue_s _dispatch_main_q = {
-       .do_vtable = DISPATCH_VTABLE(queue),
+       DISPATCH_GLOBAL_OBJECT_HEADER(queue_main),
 #if !DISPATCH_USE_RESOLVERS
        .do_targetq = &_dispatch_root_queues[
                        DISPATCH_ROOT_QUEUE_IDX_DEFAULT_QOS_OVERCOMMIT],
 #endif
 #if !DISPATCH_USE_RESOLVERS
        .do_targetq = &_dispatch_root_queues[
                        DISPATCH_ROOT_QUEUE_IDX_DEFAULT_QOS_OVERCOMMIT],
 #endif
-       .do_ref_cnt = DISPATCH_OBJECT_GLOBAL_REFCNT,
-       .do_xref_cnt = DISPATCH_OBJECT_GLOBAL_REFCNT,
-       .do_suspend_cnt = DISPATCH_OBJECT_SUSPEND_LOCK,
+       .dq_state = DISPATCH_QUEUE_STATE_INIT_VALUE(1) |
+                       DISPATCH_QUEUE_ROLE_BASE_ANON,
        .dq_label = "com.apple.main-thread",
        .dq_label = "com.apple.main-thread",
-       .dq_running = 1,
-       .dq_width = 1,
-       .dq_is_thread_bound = 1,
+       .dq_atomic_flags = DQF_THREAD_BOUND | DQF_CANNOT_TRYSYNC | DQF_WIDTH(1),
        .dq_serialnum = 1,
 };
 
 #pragma mark -
 #pragma mark dispatch_queue_attr_t
 
        .dq_serialnum = 1,
 };
 
 #pragma mark -
 #pragma mark dispatch_queue_attr_t
 
-#define DISPATCH_QUEUE_ATTR_INITIALIZER(qos, prio, overcommit, concurrent) \
-               { \
-                       .do_vtable = DISPATCH_VTABLE(queue_attr), \
-                       .do_ref_cnt = DISPATCH_OBJECT_GLOBAL_REFCNT, \
-                       .do_xref_cnt = DISPATCH_OBJECT_GLOBAL_REFCNT, \
-                       .do_next = DISPATCH_OBJECT_LISTLESS, \
-                       .dqa_qos_class = (qos), \
-                       .dqa_relative_priority = (qos) ? (prio) : 0, \
-                       .dqa_overcommit = (overcommit), \
-                       .dqa_concurrent = (concurrent), \
-               }
+#define DISPATCH_QUEUE_ATTR_INIT(qos, prio, overcommit, freq, concurrent, \
+                       inactive) \
+       { \
+               DISPATCH_GLOBAL_OBJECT_HEADER(queue_attr), \
+               .dqa_qos_and_relpri = (_dispatch_priority_make(qos, prio) & \
+                               DISPATCH_PRIORITY_REQUESTED_MASK), \
+               .dqa_overcommit = _dispatch_queue_attr_overcommit_##overcommit, \
+               .dqa_autorelease_frequency = DISPATCH_AUTORELEASE_FREQUENCY_##freq, \
+               .dqa_concurrent = (concurrent), \
+               .dqa_inactive = (inactive), \
+       }
 
 
-#define DISPATCH_QUEUE_ATTR_KIND_INIT(qos, prio) \
-               { \
-                       [DQA_INDEX_NON_OVERCOMMIT][DQA_INDEX_CONCURRENT] = \
-                                       DISPATCH_QUEUE_ATTR_INITIALIZER(qos, prio, 0, 1), \
-                       [DQA_INDEX_NON_OVERCOMMIT][DQA_INDEX_SERIAL] = \
-                                       DISPATCH_QUEUE_ATTR_INITIALIZER(qos, prio, 0, 0), \
-                       [DQA_INDEX_OVERCOMMIT][DQA_INDEX_CONCURRENT] = \
-                                       DISPATCH_QUEUE_ATTR_INITIALIZER(qos, prio, 1, 1), \
-                       [DQA_INDEX_OVERCOMMIT][DQA_INDEX_SERIAL] = \
-                                       DISPATCH_QUEUE_ATTR_INITIALIZER(qos, prio, 1, 0), \
-               }
+#define DISPATCH_QUEUE_ATTR_ACTIVE_INIT(qos, prio, overcommit, freq, \
+                       concurrent) \
+       { \
+               [DQA_INDEX_ACTIVE] = DISPATCH_QUEUE_ATTR_INIT( \
+                               qos, prio, overcommit, freq, concurrent, false), \
+               [DQA_INDEX_INACTIVE] = DISPATCH_QUEUE_ATTR_INIT( \
+                               qos, prio, overcommit, freq, concurrent, true), \
+       }
+
+#define DISPATCH_QUEUE_ATTR_OVERCOMMIT_INIT(qos, prio, overcommit) \
+       { \
+               [DQA_INDEX_AUTORELEASE_FREQUENCY_INHERIT][DQA_INDEX_CONCURRENT] = \
+                               DISPATCH_QUEUE_ATTR_ACTIVE_INIT( \
+                                               qos, prio, overcommit, INHERIT, 1), \
+               [DQA_INDEX_AUTORELEASE_FREQUENCY_INHERIT][DQA_INDEX_SERIAL] = \
+                               DISPATCH_QUEUE_ATTR_ACTIVE_INIT( \
+                                               qos, prio, overcommit, INHERIT, 0), \
+               [DQA_INDEX_AUTORELEASE_FREQUENCY_WORK_ITEM][DQA_INDEX_CONCURRENT] = \
+                               DISPATCH_QUEUE_ATTR_ACTIVE_INIT( \
+                                               qos, prio, overcommit, WORK_ITEM, 1), \
+               [DQA_INDEX_AUTORELEASE_FREQUENCY_WORK_ITEM][DQA_INDEX_SERIAL] = \
+                               DISPATCH_QUEUE_ATTR_ACTIVE_INIT( \
+                                               qos, prio, overcommit, WORK_ITEM, 0), \
+               [DQA_INDEX_AUTORELEASE_FREQUENCY_NEVER][DQA_INDEX_CONCURRENT] = \
+                               DISPATCH_QUEUE_ATTR_ACTIVE_INIT( \
+                                               qos, prio, overcommit, NEVER, 1), \
+               [DQA_INDEX_AUTORELEASE_FREQUENCY_NEVER][DQA_INDEX_SERIAL] = \
+                               DISPATCH_QUEUE_ATTR_ACTIVE_INIT(\
+                                               qos, prio, overcommit, NEVER, 0), \
+       }
 
 #define DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, prio) \
 
 #define DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, prio) \
-               [prio] = DISPATCH_QUEUE_ATTR_KIND_INIT(qos, -(prio))
+       [prio] = { \
+               [DQA_INDEX_UNSPECIFIED_OVERCOMMIT] = \
+                               DISPATCH_QUEUE_ATTR_OVERCOMMIT_INIT(qos, -(prio), unspecified),\
+               [DQA_INDEX_NON_OVERCOMMIT] = \
+                               DISPATCH_QUEUE_ATTR_OVERCOMMIT_INIT(qos, -(prio), disabled), \
+               [DQA_INDEX_OVERCOMMIT] = \
+                               DISPATCH_QUEUE_ATTR_OVERCOMMIT_INIT(qos, -(prio), enabled), \
+       }
 
 #define DISPATCH_QUEUE_ATTR_PRIO_INIT(qos) \
 
 #define DISPATCH_QUEUE_ATTR_PRIO_INIT(qos) \
-               { \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 0), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 1), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 2), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 3), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 4), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 5), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 6), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 7), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 8), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 9), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 10), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 11), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 12), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 13), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 14), \
-                       DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 15), \
-               }
+       { \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 0), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 1), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 2), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 3), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 4), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 5), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 6), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 7), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 8), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 9), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 10), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 11), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 12), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 13), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 14), \
+               DISPATCH_QUEUE_ATTR_PRIO_INITIALIZER(qos, 15), \
+       }
 
 #define DISPATCH_QUEUE_ATTR_QOS_INITIALIZER(qos) \
 
 #define DISPATCH_QUEUE_ATTR_QOS_INITIALIZER(qos) \
-               [DQA_INDEX_QOS_CLASS_##qos] = \
-                               DISPATCH_QUEUE_ATTR_PRIO_INIT(_DISPATCH_QOS_CLASS_##qos)
+       [DQA_INDEX_QOS_CLASS_##qos] = \
+                       DISPATCH_QUEUE_ATTR_PRIO_INIT(DISPATCH_QOS_##qos)
 
 
+// DISPATCH_QUEUE_CONCURRENT resp. _dispatch_queue_attr_concurrent is aliased
+// to array member [0][0][0][0][0][0] and their properties must match!
 const struct dispatch_queue_attr_s _dispatch_queue_attrs[]
 const struct dispatch_queue_attr_s _dispatch_queue_attrs[]
-               [DISPATCH_QUEUE_ATTR_PRIO_COUNT][2][2] = {
+               [DISPATCH_QUEUE_ATTR_PRIO_COUNT]
+               [DISPATCH_QUEUE_ATTR_OVERCOMMIT_COUNT]
+               [DISPATCH_QUEUE_ATTR_AUTORELEASE_FREQUENCY_COUNT]
+               [DISPATCH_QUEUE_ATTR_CONCURRENCY_COUNT]
+               [DISPATCH_QUEUE_ATTR_INACTIVE_COUNT] = {
        DISPATCH_QUEUE_ATTR_QOS_INITIALIZER(UNSPECIFIED),
        DISPATCH_QUEUE_ATTR_QOS_INITIALIZER(MAINTENANCE),
        DISPATCH_QUEUE_ATTR_QOS_INITIALIZER(BACKGROUND),
        DISPATCH_QUEUE_ATTR_QOS_INITIALIZER(UNSPECIFIED),
        DISPATCH_QUEUE_ATTR_QOS_INITIALIZER(MAINTENANCE),
        DISPATCH_QUEUE_ATTR_QOS_INITIALIZER(BACKGROUND),
@@ -248,6 +313,20 @@ const struct dispatch_queue_attr_s _dispatch_queue_attrs[]
        DISPATCH_QUEUE_ATTR_QOS_INITIALIZER(USER_INTERACTIVE),
 };
 
        DISPATCH_QUEUE_ATTR_QOS_INITIALIZER(USER_INTERACTIVE),
 };
 
+#if DISPATCH_VARIANT_STATIC
+// <rdar://problem/16778703>
+struct dispatch_queue_attr_s _dispatch_queue_attr_concurrent =
+       DISPATCH_QUEUE_ATTR_INIT(QOS_CLASS_UNSPECIFIED, 0,
+                       unspecified, INHERIT, 1, false);
+#endif // DISPATCH_VARIANT_STATIC
+
+// _dispatch_queue_attr_concurrent is aliased using libdispatch.aliases
+// and the -alias_list linker option on Darwin but needs to be done manually
+// for other platforms.
+#ifndef __APPLE__
+extern struct dispatch_queue_attr_s _dispatch_queue_attr_concurrent
+       __attribute__((__alias__("_dispatch_queue_attrs")));
+#endif
 
 #pragma mark -
 #pragma mark dispatch_vtables
 
 #pragma mark -
 #pragma mark dispatch_vtables
@@ -262,41 +341,89 @@ DISPATCH_VTABLE_INSTANCE(semaphore,
 DISPATCH_VTABLE_INSTANCE(group,
        .do_type = DISPATCH_GROUP_TYPE,
        .do_kind = "group",
 DISPATCH_VTABLE_INSTANCE(group,
        .do_type = DISPATCH_GROUP_TYPE,
        .do_kind = "group",
-       .do_dispose = _dispatch_semaphore_dispose,
-       .do_debug = _dispatch_semaphore_debug,
+       .do_dispose = _dispatch_group_dispose,
+       .do_debug = _dispatch_group_debug,
 );
 
 DISPATCH_VTABLE_INSTANCE(queue,
 );
 
 DISPATCH_VTABLE_INSTANCE(queue,
-       .do_type = DISPATCH_QUEUE_TYPE,
+       .do_type = DISPATCH_QUEUE_LEGACY_TYPE,
        .do_kind = "queue",
        .do_dispose = _dispatch_queue_dispose,
        .do_kind = "queue",
        .do_dispose = _dispatch_queue_dispose,
+       .do_suspend = _dispatch_queue_suspend,
+       .do_resume = _dispatch_queue_resume,
+       .do_push = _dispatch_queue_push,
+       .do_invoke = _dispatch_queue_invoke,
+       .do_wakeup = _dispatch_queue_wakeup,
+       .do_debug = dispatch_queue_debug,
+       .do_set_targetq = _dispatch_queue_set_target_queue,
+);
+
+DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_serial, queue,
+       .do_type = DISPATCH_QUEUE_SERIAL_TYPE,
+       .do_kind = "serial-queue",
+       .do_dispose = _dispatch_queue_dispose,
+       .do_suspend = _dispatch_queue_suspend,
+       .do_resume = _dispatch_queue_resume,
+       .do_finalize_activation = _dispatch_queue_finalize_activation,
+       .do_push = _dispatch_queue_push,
+       .do_invoke = _dispatch_queue_invoke,
+       .do_wakeup = _dispatch_queue_wakeup,
+       .do_debug = dispatch_queue_debug,
+       .do_set_targetq = _dispatch_queue_set_target_queue,
+);
+
+DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_concurrent, queue,
+       .do_type = DISPATCH_QUEUE_CONCURRENT_TYPE,
+       .do_kind = "concurrent-queue",
+       .do_dispose = _dispatch_queue_dispose,
+       .do_suspend = _dispatch_queue_suspend,
+       .do_resume = _dispatch_queue_resume,
+       .do_finalize_activation = _dispatch_queue_finalize_activation,
+       .do_push = _dispatch_queue_push,
        .do_invoke = _dispatch_queue_invoke,
        .do_invoke = _dispatch_queue_invoke,
-       .do_probe = _dispatch_queue_probe,
+       .do_wakeup = _dispatch_queue_wakeup,
        .do_debug = dispatch_queue_debug,
        .do_debug = dispatch_queue_debug,
+       .do_set_targetq = _dispatch_queue_set_target_queue,
 );
 
 );
 
+
 DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_root, queue,
 DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_root, queue,
-       .do_type = DISPATCH_QUEUE_ROOT_TYPE,
+       .do_type = DISPATCH_QUEUE_GLOBAL_ROOT_TYPE,
        .do_kind = "global-queue",
        .do_dispose = _dispatch_pthread_root_queue_dispose,
        .do_kind = "global-queue",
        .do_dispose = _dispatch_pthread_root_queue_dispose,
-       .do_probe = _dispatch_root_queue_probe,
+       .do_push = _dispatch_root_queue_push,
+       .do_invoke = NULL,
+       .do_wakeup = _dispatch_root_queue_wakeup,
+       .do_debug = dispatch_queue_debug,
+);
+
+
+DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_main, queue,
+       .do_type = DISPATCH_QUEUE_SERIAL_TYPE,
+       .do_kind = "main-queue",
+       .do_dispose = _dispatch_queue_dispose,
+       .do_push = _dispatch_queue_push,
+       .do_invoke = _dispatch_queue_invoke,
+       .do_wakeup = _dispatch_main_queue_wakeup,
        .do_debug = dispatch_queue_debug,
 );
 
 DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_runloop, queue,
        .do_debug = dispatch_queue_debug,
 );
 
 DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_runloop, queue,
-       .do_type = DISPATCH_QUEUE_ROOT_TYPE,
+       .do_type = DISPATCH_QUEUE_RUNLOOP_TYPE,
        .do_kind = "runloop-queue",
        .do_dispose = _dispatch_runloop_queue_dispose,
        .do_kind = "runloop-queue",
        .do_dispose = _dispatch_runloop_queue_dispose,
+       .do_push = _dispatch_queue_push,
        .do_invoke = _dispatch_queue_invoke,
        .do_invoke = _dispatch_queue_invoke,
-       .do_probe = _dispatch_runloop_queue_probe,
+       .do_wakeup = _dispatch_runloop_queue_wakeup,
        .do_debug = dispatch_queue_debug,
 );
 
 DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_mgr, queue,
        .do_type = DISPATCH_QUEUE_MGR_TYPE,
        .do_kind = "mgr-queue",
        .do_debug = dispatch_queue_debug,
 );
 
 DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_mgr, queue,
        .do_type = DISPATCH_QUEUE_MGR_TYPE,
        .do_kind = "mgr-queue",
+       .do_push = _dispatch_mgr_queue_push,
        .do_invoke = _dispatch_mgr_thread,
        .do_invoke = _dispatch_mgr_thread,
-       .do_probe = _dispatch_mgr_queue_probe,
+       .do_wakeup = _dispatch_mgr_queue_wakeup,
        .do_debug = dispatch_queue_debug,
 );
 
        .do_debug = dispatch_queue_debug,
 );
 
@@ -304,8 +431,9 @@ DISPATCH_VTABLE_INSTANCE(queue_specific_queue,
        .do_type = DISPATCH_QUEUE_SPECIFIC_TYPE,
        .do_kind = "queue-context",
        .do_dispose = _dispatch_queue_specific_queue_dispose,
        .do_type = DISPATCH_QUEUE_SPECIFIC_TYPE,
        .do_kind = "queue-context",
        .do_dispose = _dispatch_queue_specific_queue_dispose,
-       .do_invoke = (void*)_dispatch_queue_invoke,
-       .do_probe = (void *)_dispatch_queue_probe,
+       .do_push = (void *)_dispatch_queue_push,
+       .do_invoke = (void *)_dispatch_queue_invoke,
+       .do_wakeup = (void *)_dispatch_queue_wakeup,
        .do_debug = (void *)dispatch_queue_debug,
 );
 
        .do_debug = (void *)dispatch_queue_debug,
 );
 
@@ -318,18 +446,29 @@ DISPATCH_VTABLE_INSTANCE(source,
        .do_type = DISPATCH_SOURCE_KEVENT_TYPE,
        .do_kind = "kevent-source",
        .do_dispose = _dispatch_source_dispose,
        .do_type = DISPATCH_SOURCE_KEVENT_TYPE,
        .do_kind = "kevent-source",
        .do_dispose = _dispatch_source_dispose,
+       .do_suspend = (void *)_dispatch_queue_suspend,
+       .do_resume = (void *)_dispatch_queue_resume,
+       .do_finalize_activation = _dispatch_source_finalize_activation,
+       .do_push = (void *)_dispatch_queue_push,
        .do_invoke = _dispatch_source_invoke,
        .do_invoke = _dispatch_source_invoke,
-       .do_probe = _dispatch_source_probe,
+       .do_wakeup = _dispatch_source_wakeup,
        .do_debug = _dispatch_source_debug,
        .do_debug = _dispatch_source_debug,
+       .do_set_targetq = (void *)_dispatch_queue_set_target_queue,
 );
 
 );
 
+#if HAVE_MACH
 DISPATCH_VTABLE_INSTANCE(mach,
        .do_type = DISPATCH_MACH_CHANNEL_TYPE,
        .do_kind = "mach-channel",
        .do_dispose = _dispatch_mach_dispose,
 DISPATCH_VTABLE_INSTANCE(mach,
        .do_type = DISPATCH_MACH_CHANNEL_TYPE,
        .do_kind = "mach-channel",
        .do_dispose = _dispatch_mach_dispose,
+       .do_suspend = (void *)_dispatch_queue_suspend,
+       .do_resume = (void *)_dispatch_queue_resume,
+       .do_finalize_activation = _dispatch_mach_finalize_activation,
+       .do_push = (void *)_dispatch_queue_push,
        .do_invoke = _dispatch_mach_invoke,
        .do_invoke = _dispatch_mach_invoke,
-       .do_probe = _dispatch_mach_probe,
+       .do_wakeup = _dispatch_mach_wakeup,
        .do_debug = _dispatch_mach_debug,
        .do_debug = _dispatch_mach_debug,
+       .do_set_targetq = (void *)_dispatch_queue_set_target_queue,
 );
 
 DISPATCH_VTABLE_INSTANCE(mach_msg,
 );
 
 DISPATCH_VTABLE_INSTANCE(mach_msg,
@@ -339,13 +478,15 @@ DISPATCH_VTABLE_INSTANCE(mach_msg,
        .do_invoke = _dispatch_mach_msg_invoke,
        .do_debug = _dispatch_mach_msg_debug,
 );
        .do_invoke = _dispatch_mach_msg_invoke,
        .do_debug = _dispatch_mach_msg_debug,
 );
+#endif // HAVE_MACH
 
 
-#if !USE_OBJC
+#if !DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
 DISPATCH_VTABLE_INSTANCE(data,
        .do_type = DISPATCH_DATA_TYPE,
        .do_kind = "data",
        .do_dispose = _dispatch_data_dispose,
        .do_debug = _dispatch_data_debug,
 DISPATCH_VTABLE_INSTANCE(data,
        .do_type = DISPATCH_DATA_TYPE,
        .do_kind = "data",
        .do_dispose = _dispatch_data_dispose,
        .do_debug = _dispatch_data_debug,
+       .do_set_targetq = (void*)_dispatch_data_set_target_queue,
 );
 #endif
 
 );
 #endif
 
@@ -354,6 +495,7 @@ DISPATCH_VTABLE_INSTANCE(io,
        .do_kind = "channel",
        .do_dispose = _dispatch_io_dispose,
        .do_debug = _dispatch_io_debug,
        .do_kind = "channel",
        .do_dispose = _dispatch_io_dispose,
        .do_debug = _dispatch_io_debug,
+       .do_set_targetq = _dispatch_io_set_target_queue,
 );
 
 DISPATCH_VTABLE_INSTANCE(operation,
 );
 
 DISPATCH_VTABLE_INSTANCE(operation,
@@ -369,21 +511,54 @@ DISPATCH_VTABLE_INSTANCE(disk,
        .do_dispose = _dispatch_disk_dispose,
 );
 
        .do_dispose = _dispatch_disk_dispose,
 );
 
+
 void
 _dispatch_vtable_init(void)
 {
 void
 _dispatch_vtable_init(void)
 {
-#if USE_OBJC
+#if OS_OBJECT_HAVE_OBJC2
        // ObjC classes and dispatch vtables are co-located via linker order and
        // alias files, verify correct layout during initialization rdar://10640168
        // ObjC classes and dispatch vtables are co-located via linker order and
        // alias files, verify correct layout during initialization rdar://10640168
-       DISPATCH_OBJC_CLASS_DECL(semaphore);
-       dispatch_assert((char*)DISPATCH_VTABLE(semaphore) -
-                       (char*)DISPATCH_OBJC_CLASS(semaphore) == 0);
        dispatch_assert((char*)&DISPATCH_CONCAT(_,DISPATCH_CLASS(semaphore_vtable))
        dispatch_assert((char*)&DISPATCH_CONCAT(_,DISPATCH_CLASS(semaphore_vtable))
-                       - (char*)DISPATCH_OBJC_CLASS(semaphore) ==
-                       sizeof(_os_object_class_s));
+                       - (char*)DISPATCH_VTABLE(semaphore) ==
+                       offsetof(struct dispatch_semaphore_vtable_s, _os_obj_vtable));
 #endif // USE_OBJC
 }
 
 #endif // USE_OBJC
 }
 
+#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
 
 #pragma mark -
 #pragma mark dispatch_bug
 
@@ -397,12 +572,20 @@ _dispatch_build_init(void *context DISPATCH_UNUSED)
        size_t bufsz = sizeof(_dispatch_build);
 
        sysctl(mib, 2, _dispatch_build, &bufsz, NULL, 0);
        size_t bufsz = sizeof(_dispatch_build);
 
        sysctl(mib, 2, _dispatch_build, &bufsz, NULL, 0);
+#if TARGET_IPHONE_SIMULATOR
+       char *sim_version = getenv("SIMULATOR_RUNTIME_BUILD_VERSION");
+       if (sim_version) {
+               (void)strlcat(_dispatch_build, " ", sizeof(_dispatch_build));
+               (void)strlcat(_dispatch_build, sim_version, sizeof(_dispatch_build));
+       }
+#endif // TARGET_IPHONE_SIMULATOR
+
 #else
        /*
         * XXXRW: What to do here for !Mac OS X?
         */
        memset(_dispatch_build, 0, sizeof(_dispatch_build));
 #else
        /*
         * XXXRW: What to do here for !Mac OS X?
         */
        memset(_dispatch_build, 0, sizeof(_dispatch_build));
-#endif
+#endif // __APPLE__
 }
 
 static dispatch_once_t _dispatch_build_pred;
 }
 
 static dispatch_once_t _dispatch_build_pred;
@@ -437,19 +620,35 @@ _dispatch_bug_client(const char* msg)
        _dispatch_bug_log("BUG in libdispatch client: %s", msg);
 }
 
        _dispatch_bug_log("BUG in libdispatch client: %s", msg);
 }
 
+#if HAVE_MACH
 void
 _dispatch_bug_mach_client(const char* msg, mach_msg_return_t kr)
 {
        _dispatch_bug_log("BUG in libdispatch client: %s %s - 0x%x", msg,
                        mach_error_string(kr), kr);
 }
 void
 _dispatch_bug_mach_client(const char* msg, mach_msg_return_t kr)
 {
        _dispatch_bug_log("BUG in libdispatch client: %s %s - 0x%x", msg,
                        mach_error_string(kr), kr);
 }
+#endif
 
 void
 _dispatch_bug_kevent_client(const char* msg, const char* filter,
                const char *operation, int err)
 {
 
 void
 _dispatch_bug_kevent_client(const char* msg, const char* filter,
                const char *operation, int err)
 {
-       _dispatch_bug_log("BUG in libdispatch client: %s[%s] %s: \"%s\" - 0x%x",
-                       msg, filter, operation, strerror(err), err);
+       if (operation && err) {
+               _dispatch_bug_log("BUG in libdispatch client: %s[%s] %s: \"%s\" - 0x%x",
+                               msg, filter, operation, strerror(err), err);
+       } else if (operation) {
+               _dispatch_bug_log("BUG in libdispatch client: %s[%s] %s",
+                               msg, filter, operation);
+       } else {
+               _dispatch_bug_log("BUG in libdispatch: %s[%s]: \"%s\" - 0x%x",
+                               msg, filter, strerror(err), err);
+       }
+}
+
+void
+_dispatch_bug_deprecated(const char *msg)
+{
+       _dispatch_bug_log("DEPRECATED USE in libdispatch client: %s", msg);
 }
 
 void
 }
 
 void
@@ -466,6 +665,9 @@ _dispatch_abort(size_t line, long val)
 
 static int dispatch_logfile = -1;
 static bool dispatch_log_disabled;
 
 static int dispatch_logfile = -1;
 static bool dispatch_log_disabled;
+#if DISPATCH_DEBUG
+static uint64_t dispatch_log_basetime;
+#endif
 static dispatch_once_t _dispatch_logv_pred;
 
 static void
 static dispatch_once_t _dispatch_logv_pred;
 
 static void
@@ -502,9 +704,12 @@ _dispatch_logv_init(void *context DISPATCH_UNUSED)
                if (dispatch_logfile != -1) {
                        struct timeval tv;
                        gettimeofday(&tv, NULL);
                if (dispatch_logfile != -1) {
                        struct timeval tv;
                        gettimeofday(&tv, NULL);
+#if DISPATCH_DEBUG
+                       dispatch_log_basetime = _dispatch_absolute_time();
+#endif
                        dprintf(dispatch_logfile, "=== log file opened for %s[%u] at "
                                        "%ld.%06u ===\n", getprogname() ?: "", getpid(),
                        dprintf(dispatch_logfile, "=== log file opened for %s[%u] at "
                                        "%ld.%06u ===\n", getprogname() ?: "", getpid(),
-                                       tv.tv_sec, tv.tv_usec);
+                                       tv.tv_sec, (int)tv.tv_usec);
                }
        }
 }
                }
        }
 }
@@ -527,13 +732,20 @@ static void
 _dispatch_logv_file(const char *msg, va_list ap)
 {
        char buf[2048];
 _dispatch_logv_file(const char *msg, va_list ap)
 {
        char buf[2048];
-       int r = vsnprintf(buf, sizeof(buf), msg, ap);
+       size_t bufsiz = sizeof(buf), offset = 0;
+       int r;
+
+#if DISPATCH_DEBUG
+       offset += dsnprintf(&buf[offset], bufsiz - offset, "%llu\t",
+                       _dispatch_absolute_time() - dispatch_log_basetime);
+#endif
+       r = vsnprintf(&buf[offset], bufsiz - offset, msg, ap);
        if (r < 0) return;
        if (r < 0) return;
-       size_t len = (size_t)r;
-       if (len > sizeof(buf) - 1) {
-               len = sizeof(buf) - 1;
+       offset += (size_t)r;
+       if (offset > bufsiz - 1) {
+               offset = bufsiz - 1;
        }
        }
-       _dispatch_log_file(buf, len);
+       _dispatch_log_file(buf, offset);
 }
 
 #if DISPATCH_USE_SIMPLE_ASL
 }
 
 #if DISPATCH_USE_SIMPLE_ASL
@@ -563,7 +775,7 @@ _dispatch_syslog(const char *msg)
 static inline void
 _dispatch_vsyslog(const char *msg, va_list ap)
 {
 static inline void
 _dispatch_vsyslog(const char *msg, va_list ap)
 {
-       vsyslog(LOG_NOTICE, msg, *ap_ptr);
+       vsyslog(LOG_NOTICE, msg, ap);
 }
 #endif // DISPATCH_USE_SIMPLE_ASL
 
 }
 #endif // DISPATCH_USE_SIMPLE_ASL
 
@@ -607,7 +819,7 @@ static size_t
 _dispatch_object_debug2(dispatch_object_t dou, char* buf, size_t bufsiz)
 {
        DISPATCH_OBJECT_TFB(_dispatch_objc_debug, dou, buf, bufsiz);
 _dispatch_object_debug2(dispatch_object_t dou, char* buf, size_t bufsiz)
 {
        DISPATCH_OBJECT_TFB(_dispatch_objc_debug, dou, buf, bufsiz);
-       if (dou._do->do_vtable->do_debug) {
+       if (dx_vtable(dou._do)->do_debug) {
                return dx_debug(dou._do, buf, bufsiz);
        }
        return strlcpy(buf, "NULL vtable slot: ", bufsiz);
                return dx_debug(dou._do, buf, bufsiz);
        }
        return strlcpy(buf, "NULL vtable slot: ", bufsiz);
@@ -618,22 +830,27 @@ static void
 _dispatch_debugv(dispatch_object_t dou, const char *msg, va_list ap)
 {
        char buf[2048];
 _dispatch_debugv(dispatch_object_t dou, const char *msg, va_list ap)
 {
        char buf[2048];
+       size_t bufsiz = sizeof(buf), offset = 0;
        int r;
        int r;
-       size_t offs;
+#if DISPATCH_DEBUG && !DISPATCH_USE_OS_DEBUG_LOG
+       offset += dsnprintf(&buf[offset], bufsiz - offset, "%llu\t\t%p\t",
+                       _dispatch_absolute_time() - dispatch_log_basetime,
+                       (void *)_dispatch_thread_self());
+#endif
        if (dou._do) {
        if (dou._do) {
-               offs = _dispatch_object_debug2(dou, buf, sizeof(buf));
-               dispatch_assert(offs + 2 < sizeof(buf));
-               buf[offs++] = ':';
-               buf[offs++] = ' ';
-               buf[offs]   = '\0';
+               offset += _dispatch_object_debug2(dou, &buf[offset], bufsiz - offset);
+               dispatch_assert(offset + 2 < bufsiz);
+               buf[offset++] = ':';
+               buf[offset++] = ' ';
+               buf[offset]   = '\0';
        } else {
        } else {
-               offs = strlcpy(buf, "NULL: ", sizeof(buf));
+               offset += strlcpy(&buf[offset], "NULL: ", bufsiz - offset);
        }
        }
-       r = vsnprintf(buf + offs, sizeof(buf) - offs, msg, ap);
+       r = vsnprintf(&buf[offset], bufsiz - offset, msg, ap);
 #if !DISPATCH_USE_OS_DEBUG_LOG
 #if !DISPATCH_USE_OS_DEBUG_LOG
-       size_t len = offs + (r < 0 ? 0 : (size_t)r);
-       if (len > sizeof(buf) - 1) {
-               len = sizeof(buf) - 1;
+       size_t len = offset + (r < 0 ? 0 : (size_t)r);
+       if (len > bufsiz - 1) {
+               len = bufsiz - 1;
        }
        _dispatch_logv(buf, len, NULL);
 #else
        }
        _dispatch_logv(buf, len, NULL);
 #else
@@ -680,6 +897,7 @@ void
 _dispatch_temporary_resource_shortage(void)
 {
        sleep(1);
 _dispatch_temporary_resource_shortage(void)
 {
        sleep(1);
+       asm("");  // prevent tailcall
 }
 
 void *
 }
 
 void *
@@ -692,14 +910,35 @@ _dispatch_calloc(size_t num_items, size_t size)
        return buf;
 }
 
        return buf;
 }
 
+/**
+ * If the source string is mutable, allocates memory and copies the contents.
+ * Otherwise returns the source string.
+ */
+const char *
+_dispatch_strdup_if_mutable(const char *str)
+{
+#if HAVE_DYLD_IS_MEMORY_IMMUTABLE
+       size_t size = strlen(str) + 1;
+       if (slowpath(!_dyld_is_memory_immutable(str, size))) {
+               char *clone = (char *) malloc(size);
+               if (dispatch_assume(clone)) {
+                       memcpy(clone, str, size);
+               }
+               return clone;
+       }
+       return str;
+#else
+       return strdup(str);
+#endif
+}
+
 #pragma mark -
 #pragma mark dispatch_block_t
 
 #ifdef __BLOCKS__
 
 #pragma mark -
 #pragma mark dispatch_block_t
 
 #ifdef __BLOCKS__
 
-#undef _dispatch_Block_copy
-dispatch_block_t
-_dispatch_Block_copy(dispatch_block_t db)
+void *
+(_dispatch_Block_copy)(void *db)
 {
        dispatch_block_t rval;
 
 {
        dispatch_block_t rval;
 
@@ -709,7 +948,7 @@ _dispatch_Block_copy(dispatch_block_t db)
                }
                return rval;
        }
                }
                return rval;
        }
-       DISPATCH_CLIENT_CRASH("NULL was passed where a block should have been");
+       DISPATCH_CLIENT_CRASH(0, "NULL was passed where a block should have been");
 }
 
 void
 }
 
 void
@@ -720,47 +959,14 @@ _dispatch_call_block_and_release(void *block)
        Block_release(b);
 }
 
        Block_release(b);
 }
 
-#pragma mark -
-#pragma mark _dispatch_block_create no_objc
-
-#if !USE_OBJC
-
-// The compiler hides the name of the function it generates, and changes it if
-// we try to reference it directly, but the linker still sees it.
-extern void DISPATCH_BLOCK_SPECIAL_INVOKE(void *)
-               asm("____dispatch_block_create_block_invoke");
-void (*_dispatch_block_special_invoke)(void*) = DISPATCH_BLOCK_SPECIAL_INVOKE;
-
-dispatch_block_t
-_dispatch_block_create(dispatch_block_flags_t flags, voucher_t voucher,
-               pthread_priority_t pri, dispatch_block_t block)
-{
-       dispatch_block_t copy_block = _dispatch_Block_copy(block); // 17094902
-       (void)voucher; // No voucher capture! (requires ObjC runtime)
-       struct dispatch_block_private_data_s dbpds =
-                       DISPATCH_BLOCK_PRIVATE_DATA_INITIALIZER(flags, NULL, pri, copy_block);
-       dispatch_block_t new_block = _dispatch_Block_copy(^{
-               // Capture object references, which retains copy_block.
-               // All retained objects must be captured by the *block*. We
-               // cannot borrow any references, because the block might be
-               // called zero or several times, so Block_release() is the
-               // only place that can release retained objects.
-               (void)copy_block;
-               _dispatch_block_invoke(&dbpds);
-       });
-       Block_release(copy_block);
-       return new_block;
-}
-
-#endif // !USE_OBJC
-
 #endif // __BLOCKS__
 
 #pragma mark -
 #pragma mark dispatch_client_callout
 
 // Abort on uncaught exceptions thrown from client callouts rdar://8577499
 #endif // __BLOCKS__
 
 #pragma mark -
 #pragma mark dispatch_client_callout
 
 // Abort on uncaught exceptions thrown from client callouts rdar://8577499
-#if DISPATCH_USE_CLIENT_CALLOUT && (__USING_SJLJ_EXCEPTIONS__ || !USE_OBJC)
+#if DISPATCH_USE_CLIENT_CALLOUT && (__USING_SJLJ_EXCEPTIONS__ || !USE_OBJC || \
+               OS_OBJECT_HAVE_OBJC1)
 // On platforms with SjLj exceptions, avoid the SjLj overhead on every callout
 // by clearing the unwinder's TSD pointer to the handler stack around callouts
 
 // On platforms with SjLj exceptions, avoid the SjLj overhead on every callout
 // by clearing the unwinder's TSD pointer to the handler stack around callouts
 
@@ -797,19 +1003,21 @@ _dispatch_client_callout2(void *ctxt, size_t i, void (*f)(void *, size_t))
        _dispatch_set_unwind_tsd(u);
 }
 
        _dispatch_set_unwind_tsd(u);
 }
 
+#if HAVE_MACH
+
 #undef _dispatch_client_callout3
 #undef _dispatch_client_callout3
-bool
-_dispatch_client_callout3(void *ctxt, dispatch_data_t region, size_t offset,
-               const void *buffer, size_t size, dispatch_data_applier_function_t f)
+DISPATCH_NOINLINE
+void
+_dispatch_client_callout3(void *ctxt, dispatch_mach_reason_t reason,
+               dispatch_mach_msg_t dmsg, dispatch_mach_async_reply_callback_t f)
 {
        _dispatch_get_tsd_base();
        void *u = _dispatch_get_unwind_tsd();
 {
        _dispatch_get_tsd_base();
        void *u = _dispatch_get_unwind_tsd();
-       if (fastpath(!u)) return f(ctxt, region, offset, buffer, size);
+       if (fastpath(!u)) return f(ctxt, reason, dmsg);
        _dispatch_set_unwind_tsd(NULL);
        _dispatch_set_unwind_tsd(NULL);
-       bool res = f(ctxt, region, offset, buffer, size);
+       f(ctxt, reason, dmsg);
        _dispatch_free_unwind_tsd();
        _dispatch_set_unwind_tsd(u);
        _dispatch_free_unwind_tsd();
        _dispatch_set_unwind_tsd(u);
-       return res;
 }
 
 #undef _dispatch_client_callout4
 }
 
 #undef _dispatch_client_callout4
@@ -826,6 +1034,7 @@ _dispatch_client_callout4(void *ctxt, dispatch_mach_reason_t reason,
        _dispatch_free_unwind_tsd();
        _dispatch_set_unwind_tsd(u);
 }
        _dispatch_free_unwind_tsd();
        _dispatch_set_unwind_tsd(u);
 }
+#endif // HAVE_MACH
 
 #endif // DISPATCH_USE_CLIENT_CALLOUT
 
 
 #endif // DISPATCH_USE_CLIENT_CALLOUT
 
@@ -834,7 +1043,7 @@ _dispatch_client_callout4(void *ctxt, dispatch_mach_reason_t reason,
 
 #if !USE_OBJC
 
 
 #if !USE_OBJC
 
-static const _os_object_class_s _os_object_class;
+static const _os_object_vtable_s _os_object_vtable;
 
 void
 _os_object_init(void)
 
 void
 _os_object_init(void)
@@ -857,7 +1066,7 @@ _os_object_alloc_realized(const void *cls, size_t size)
 _os_object_t
 _os_object_alloc(const void *cls, size_t size)
 {
 _os_object_t
 _os_object_alloc(const void *cls, size_t size)
 {
-       if (!cls) cls = &_os_object_class;
+       if (!cls) cls = &_os_object_vtable;
        return _os_object_alloc_realized(cls, size);
 }
 
        return _os_object_alloc_realized(cls, size);
 }
 
@@ -871,6 +1080,7 @@ _os_object_dealloc(_os_object_t obj)
 void
 _os_object_xref_dispose(_os_object_t obj)
 {
 void
 _os_object_xref_dispose(_os_object_t obj)
 {
+       _os_object_xrefcnt_dispose_barrier(obj);
        if (fastpath(obj->os_obj_isa->_os_obj_xref_dispose)) {
                return obj->os_obj_isa->_os_obj_xref_dispose(obj);
        }
        if (fastpath(obj->os_obj_isa->_os_obj_xref_dispose)) {
                return obj->os_obj_isa->_os_obj_xref_dispose(obj);
        }
@@ -880,6 +1090,7 @@ _os_object_xref_dispose(_os_object_t obj)
 void
 _os_object_dispose(_os_object_t obj)
 {
 void
 _os_object_dispose(_os_object_t obj)
 {
+       _os_object_refcnt_dispose_barrier(obj);
        if (fastpath(obj->os_obj_isa->_os_obj_dispose)) {
                return obj->os_obj_isa->_os_obj_dispose(obj);
        }
        if (fastpath(obj->os_obj_isa->_os_obj_dispose)) {
                return obj->os_obj_isa->_os_obj_dispose(obj);
        }
@@ -904,347 +1115,66 @@ os_release(void *obj)
        }
 }
 
        }
 }
 
-#pragma mark -
-#pragma mark dispatch_autorelease_pool no_objc
-
-#if DISPATCH_COCOA_COMPAT
-
-void *_dispatch_autorelease_pool_push(void) {
-       void *pool = NULL;
-       if (_dispatch_begin_NSAutoReleasePool) {
-               pool = _dispatch_begin_NSAutoReleasePool();
-       }
-       return pool;
-}
-
-void _dispatch_autorelease_pool_pop(void *pool) {
-       if (_dispatch_end_NSAutoReleasePool) {
-               _dispatch_end_NSAutoReleasePool(pool);
-       }
-}
-
-#endif // DISPATCH_COCOA_COMPAT
-#endif // !USE_OBJC
-
-#pragma mark -
-#pragma mark dispatch_source_types
-
-static void
-dispatch_source_type_timer_init(dispatch_source_t ds,
-       dispatch_source_type_t type DISPATCH_UNUSED,
-       uintptr_t handle DISPATCH_UNUSED,
-       unsigned long mask,
-       dispatch_queue_t q)
+void
+_os_object_atfork_prepare(void)
 {
 {
-       if (fastpath(!ds->ds_refs)) {
-               ds->ds_refs = _dispatch_calloc(1ul,
-                               sizeof(struct dispatch_timer_source_refs_s));
-       }
-       ds->ds_needs_rearm = true;
-       ds->ds_is_timer = true;
-       if (q == dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)
-                       || q == dispatch_get_global_queue(
-                       DISPATCH_QUEUE_PRIORITY_BACKGROUND, DISPATCH_QUEUE_OVERCOMMIT)){
-               mask |= DISPATCH_TIMER_BACKGROUND; // <rdar://problem/12200216>
-       }
-       ds_timer(ds->ds_refs).flags = mask;
+       return;
 }
 
 }
 
-const struct dispatch_source_type_s _dispatch_source_type_timer = {
-       .ke = {
-               .filter = DISPATCH_EVFILT_TIMER,
-       },
-       .mask = DISPATCH_TIMER_STRICT|DISPATCH_TIMER_BACKGROUND|
-                       DISPATCH_TIMER_WALL_CLOCK,
-       .init = dispatch_source_type_timer_init,
-};
-
-static void
-dispatch_source_type_timer_with_aggregate_init(dispatch_source_t ds,
-       dispatch_source_type_t type, uintptr_t handle, unsigned long mask,
-       dispatch_queue_t q)
+void
+_os_object_atfork_parent(void)
 {
 {
-       ds->ds_refs = _dispatch_calloc(1ul,
-                       sizeof(struct dispatch_timer_source_aggregate_refs_s));
-       dispatch_source_type_timer_init(ds, type, handle, mask, q);
-       ds_timer(ds->ds_refs).flags |= DISPATCH_TIMER_WITH_AGGREGATE;
-       ds->dq_specific_q = (void*)handle;
-       _dispatch_retain(ds->dq_specific_q);
+       return;
 }
 
 }
 
-const struct dispatch_source_type_s _dispatch_source_type_timer_with_aggregate={
-       .ke = {
-               .filter = DISPATCH_EVFILT_TIMER,
-               .ident = ~0ull,
-       },
-       .mask = DISPATCH_TIMER_STRICT|DISPATCH_TIMER_BACKGROUND,
-       .init = dispatch_source_type_timer_with_aggregate_init,
-};
-
-static void
-dispatch_source_type_interval_init(dispatch_source_t ds,
-       dispatch_source_type_t type, uintptr_t handle, unsigned long mask,
-       dispatch_queue_t q)
+void
+_os_object_atfork_child(void)
 {
 {
-       dispatch_source_type_timer_init(ds, type, handle, mask, q);
-       ds_timer(ds->ds_refs).flags |= DISPATCH_TIMER_INTERVAL;
-       unsigned long ident = _dispatch_source_timer_idx(ds->ds_refs);
-       ds->ds_dkev->dk_kevent.ident = ds->ds_ident_hack = ident;
-       _dispatch_source_set_interval(ds, handle);
+       return;
 }
 
 }
 
-const struct dispatch_source_type_s _dispatch_source_type_interval = {
-       .ke = {
-               .filter = DISPATCH_EVFILT_TIMER,
-               .ident = ~0ull,
-       },
-       .mask = DISPATCH_TIMER_STRICT|DISPATCH_TIMER_BACKGROUND|
-                       DISPATCH_INTERVAL_UI_ANIMATION,
-       .init = dispatch_source_type_interval_init,
-};
-
-const struct dispatch_source_type_s _dispatch_source_type_read = {
-       .ke = {
-               .filter = EVFILT_READ,
-               .flags = EV_DISPATCH,
-       },
-};
-
-const struct dispatch_source_type_s _dispatch_source_type_write = {
-       .ke = {
-               .filter = EVFILT_WRITE,
-               .flags = EV_DISPATCH,
-       },
-};
+#pragma mark -
+#pragma mark dispatch_autorelease_pool no_objc
 
 
-#if DISPATCH_USE_MEMORYSTATUS
+#if DISPATCH_COCOA_COMPAT
 
 
-#if TARGET_IPHONE_SIMULATOR // rdar://problem/9219483
-static int _dispatch_ios_simulator_memory_warnings_fd = -1;
-static void
-_dispatch_ios_simulator_memorypressure_init(void *context DISPATCH_UNUSED)
+void*
+_dispatch_autorelease_pool_push(void)
 {
 {
-       char *e = getenv("SIMULATOR_MEMORY_WARNINGS");
-       if (!e) return;
-       _dispatch_ios_simulator_memory_warnings_fd = open(e, O_EVTONLY);
-       if (_dispatch_ios_simulator_memory_warnings_fd == -1) {
-               (void)dispatch_assume_zero(errno);
+       void *pool = NULL;
+       if (_dispatch_begin_NSAutoReleasePool) {
+               pool = _dispatch_begin_NSAutoReleasePool();
        }
        }
+       return pool;
 }
 }
-#endif
-
-static void
-dispatch_source_type_memorystatus_init(dispatch_source_t ds,
-       dispatch_source_type_t type DISPATCH_UNUSED,
-       uintptr_t handle DISPATCH_UNUSED,
-       unsigned long mask DISPATCH_UNUSED,
-       dispatch_queue_t q DISPATCH_UNUSED)
-{
-#if TARGET_IPHONE_SIMULATOR
-       static dispatch_once_t pred;
-       dispatch_once_f(&pred, NULL, _dispatch_ios_simulator_memorypressure_init);
-       handle = (uintptr_t)_dispatch_ios_simulator_memory_warnings_fd;
-       mask = NOTE_ATTRIB;
-       ds->ds_dkev->dk_kevent.filter = EVFILT_VNODE;
-       ds->ds_dkev->dk_kevent.ident = handle;
-       ds->ds_dkev->dk_kevent.flags |= EV_CLEAR;
-       ds->ds_dkev->dk_kevent.fflags = (uint32_t)mask;
-       ds->ds_ident_hack = handle;
-       ds->ds_pending_data_mask = mask;
-       ds->ds_memorystatus_override = 1;
-#endif
-       ds->ds_is_level = false;
-}
-
-#ifndef NOTE_MEMORYSTATUS_LOW_SWAP
-#define NOTE_MEMORYSTATUS_LOW_SWAP 0x8
-#endif
-
-const struct dispatch_source_type_s _dispatch_source_type_memorystatus = {
-       .ke = {
-               .filter = EVFILT_MEMORYSTATUS,
-               .flags = EV_DISPATCH,
-       },
-       .mask = NOTE_MEMORYSTATUS_PRESSURE_NORMAL|NOTE_MEMORYSTATUS_PRESSURE_WARN
-                       |NOTE_MEMORYSTATUS_PRESSURE_CRITICAL|NOTE_MEMORYSTATUS_LOW_SWAP,
-       .init = dispatch_source_type_memorystatus_init,
-};
-
-static void
-dispatch_source_type_vm_init(dispatch_source_t ds,
-       dispatch_source_type_t type,
-       uintptr_t handle,
-       unsigned long mask,
-       dispatch_queue_t q)
-{
-       // Map legacy vm pressure to memorystatus warning rdar://problem/15907505
-       mask = NOTE_MEMORYSTATUS_PRESSURE_WARN;
-       ds->ds_dkev->dk_kevent.fflags = (uint32_t)mask;
-       ds->ds_pending_data_mask = mask;
-       ds->ds_vmpressure_override = 1;
-       dispatch_source_type_memorystatus_init(ds, type, handle, mask, q);
-}
-
-const struct dispatch_source_type_s _dispatch_source_type_vm = {
-       .ke = {
-               .filter = EVFILT_MEMORYSTATUS,
-               .flags = EV_DISPATCH,
-       },
-       .mask = NOTE_VM_PRESSURE,
-       .init = dispatch_source_type_vm_init,
-};
-
-#elif DISPATCH_USE_VM_PRESSURE
 
 
-static void
-dispatch_source_type_vm_init(dispatch_source_t ds,
-       dispatch_source_type_t type DISPATCH_UNUSED,
-       uintptr_t handle DISPATCH_UNUSED,
-       unsigned long mask DISPATCH_UNUSED,
-       dispatch_queue_t q DISPATCH_UNUSED)
+void
+_dispatch_autorelease_pool_pop(void *pool)
 {
 {
-       ds->ds_is_level = false;
+       if (_dispatch_end_NSAutoReleasePool) {
+               _dispatch_end_NSAutoReleasePool(pool);
+       }
 }
 
 }
 
-const struct dispatch_source_type_s _dispatch_source_type_vm = {
-       .ke = {
-               .filter = EVFILT_VM,
-               .flags = EV_DISPATCH,
-       },
-       .mask = NOTE_VM_PRESSURE,
-       .init = dispatch_source_type_vm_init,
-};
-
-#endif // DISPATCH_USE_VM_PRESSURE
-
-const struct dispatch_source_type_s _dispatch_source_type_proc = {
-       .ke = {
-               .filter = EVFILT_PROC,
-               .flags = EV_CLEAR,
-       },
-       .mask = NOTE_EXIT|NOTE_FORK|NOTE_EXEC
-#if HAVE_DECL_NOTE_SIGNAL
-                       |NOTE_SIGNAL
-#endif
-#if HAVE_DECL_NOTE_REAP
-                       |NOTE_REAP
-#endif
-                       ,
-};
-
-const struct dispatch_source_type_s _dispatch_source_type_signal = {
-       .ke = {
-               .filter = EVFILT_SIGNAL,
-       },
-};
-
-const struct dispatch_source_type_s _dispatch_source_type_vnode = {
-       .ke = {
-               .filter = EVFILT_VNODE,
-               .flags = EV_CLEAR,
-       },
-       .mask = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|
-                       NOTE_RENAME|NOTE_REVOKE
-#if HAVE_DECL_NOTE_NONE
-                       |NOTE_NONE
-#endif
-                       ,
-};
-
-const struct dispatch_source_type_s _dispatch_source_type_vfs = {
-       .ke = {
-               .filter = EVFILT_FS,
-               .flags = EV_CLEAR,
-       },
-       .mask = VQ_NOTRESP|VQ_NEEDAUTH|VQ_LOWDISK|VQ_MOUNT|VQ_UNMOUNT|VQ_DEAD|
-                       VQ_ASSIST|VQ_NOTRESPLOCK
-#if HAVE_DECL_VQ_UPDATE
-                       |VQ_UPDATE
-#endif
-#if HAVE_DECL_VQ_VERYLOWDISK
-                       |VQ_VERYLOWDISK
-#endif
-                       ,
-};
-
-const struct dispatch_source_type_s _dispatch_source_type_sock = {
-#ifdef EVFILT_SOCK
-       .ke = {
-               .filter = EVFILT_SOCK,
-               .flags = EV_CLEAR,
-       },
-       .mask = NOTE_CONNRESET |  NOTE_READCLOSED | NOTE_WRITECLOSED |
-               NOTE_TIMEOUT | NOTE_NOSRCADDR |  NOTE_IFDENIED | NOTE_SUSPEND |
-               NOTE_RESUME | NOTE_KEEPALIVE
-#ifdef NOTE_ADAPTIVE_WTIMO
-               | NOTE_ADAPTIVE_WTIMO | NOTE_ADAPTIVE_RTIMO
-#endif
-#ifdef NOTE_CONNECTED
-               | NOTE_CONNECTED | NOTE_DISCONNECTED | NOTE_CONNINFO_UPDATED
-#endif
-               ,
-#endif // EVFILT_SOCK
-};
-
-const struct dispatch_source_type_s _dispatch_source_type_data_add = {
-       .ke = {
-               .filter = DISPATCH_EVFILT_CUSTOM_ADD,
-       },
-};
-
-const struct dispatch_source_type_s _dispatch_source_type_data_or = {
-       .ke = {
-               .filter = DISPATCH_EVFILT_CUSTOM_OR,
-               .flags = EV_CLEAR,
-               .fflags = ~0u,
-       },
-};
-
-#if HAVE_MACH
-
-static void
-dispatch_source_type_mach_send_init(dispatch_source_t ds,
-       dispatch_source_type_t type DISPATCH_UNUSED,
-       uintptr_t handle DISPATCH_UNUSED, unsigned long mask,
-       dispatch_queue_t q DISPATCH_UNUSED)
+void
+_dispatch_last_resort_autorelease_pool_push(dispatch_invoke_context_t dic)
 {
 {
-       if (!mask) {
-               // Preserve legacy behavior that (mask == 0) => DISPATCH_MACH_SEND_DEAD
-               ds->ds_dkev->dk_kevent.fflags = DISPATCH_MACH_SEND_DEAD;
-               ds->ds_pending_data_mask = DISPATCH_MACH_SEND_DEAD;
-       }
+       dic->dic_autorelease_pool = _dispatch_autorelease_pool_push();
 }
 
 }
 
-const struct dispatch_source_type_s _dispatch_source_type_mach_send = {
-       .ke = {
-               .filter = DISPATCH_EVFILT_MACH_NOTIFICATION,
-               .flags = EV_CLEAR,
-       },
-       .mask = DISPATCH_MACH_SEND_DEAD|DISPATCH_MACH_SEND_POSSIBLE,
-       .init = dispatch_source_type_mach_send_init,
-};
-
-static void
-dispatch_source_type_mach_recv_init(dispatch_source_t ds,
-       dispatch_source_type_t type DISPATCH_UNUSED,
-       uintptr_t handle DISPATCH_UNUSED,
-       unsigned long mask DISPATCH_UNUSED,
-       dispatch_queue_t q DISPATCH_UNUSED)
+void
+_dispatch_last_resort_autorelease_pool_pop(dispatch_invoke_context_t dic)
 {
 {
-       ds->ds_is_level = false;
+       _dispatch_autorelease_pool_pop(dic->dic_autorelease_pool);
+       dic->dic_autorelease_pool = NULL;
 }
 
 }
 
-const struct dispatch_source_type_s _dispatch_source_type_mach_recv = {
-       .ke = {
-               .filter = EVFILT_MACHPORT,
-               .flags = EV_DISPATCH,
-               .fflags = DISPATCH_MACH_RECV_MESSAGE,
-       },
-       .init = dispatch_source_type_mach_recv_init,
-};
+#endif // DISPATCH_COCOA_COMPAT
+#endif // !USE_OBJC
 
 #pragma mark -
 #pragma mark dispatch_mig
 
 #pragma mark -
 #pragma mark dispatch_mig
+#if HAVE_MACH
 
 void *
 dispatch_mach_msg_get_context(mach_msg_header_t *msg)
 
 void *
 dispatch_mach_msg_get_context(mach_msg_header_t *msg)
@@ -1279,22 +1209,16 @@ kern_return_t
 _dispatch_mach_notify_port_destroyed(mach_port_t notify DISPATCH_UNUSED,
                mach_port_t name)
 {
 _dispatch_mach_notify_port_destroyed(mach_port_t notify DISPATCH_UNUSED,
                mach_port_t name)
 {
-       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;
+       DISPATCH_INTERNAL_CRASH(name, "unexpected receipt of port-destroyed");
+       return KERN_FAILURE;
 }
 
 kern_return_t
 }
 
 kern_return_t
-_dispatch_mach_notify_no_senders(mach_port_t notify,
-               mach_port_mscount_t mscnt DISPATCH_UNUSED)
+_dispatch_mach_notify_no_senders(mach_port_t notify DISPATCH_UNUSED,
+               mach_port_mscount_t mscnt)
 {
 {
-       // this function should never be called
-       (void)dispatch_assume_zero(notify);
-       return KERN_SUCCESS;
+       DISPATCH_INTERNAL_CRASH(mscnt, "unexpected receipt of no-more-senders");
+       return KERN_FAILURE;
 }
 
 kern_return_t
 }
 
 kern_return_t