diff --git a/dispatch/CMakeLists.txt b/dispatch/CMakeLists.txt index 7f68ed381..8e033dfd3 100644 --- a/dispatch/CMakeLists.txt +++ b/dispatch/CMakeLists.txt @@ -13,6 +13,7 @@ install(FILES semaphore.h source.h time.h + workloop.h DESTINATION "${INSTALL_DISPATCH_HEADERS_DIR}") if(ENABLE_SWIFT) diff --git a/dispatch/base.h b/dispatch/base.h index 0a2370bd8..8e0a7bbf4 100644 --- a/dispatch/base.h +++ b/dispatch/base.h @@ -62,7 +62,7 @@ #define DISPATCH_CONST __attribute__((__const__)) #define DISPATCH_WARN_RESULT __attribute__((__warn_unused_result__)) #define DISPATCH_MALLOC __attribute__((__malloc__)) -#define DISPATCH_ALWAYS_INLINE __attribute__((__always_inline__)) +#define DISPATCH_ALWAYS_INLINE __attribute__((unused, __always_inline__)) #define DISPATCH_UNAVAILABLE __attribute__((__unavailable__)) #define DISPATCH_UNAVAILABLE_MSG(msg) __attribute__((__unavailable__(msg))) #elif defined(_MSC_VER) diff --git a/dispatch/dispatch.h b/dispatch/dispatch.h index 9b517f36c..9c5bf101b 100644 --- a/dispatch/dispatch.h +++ b/dispatch/dispatch.h @@ -62,7 +62,9 @@ #endif #include +#if HAVE_MACH #include +#endif #include #include #include diff --git a/dispatch/time.h b/dispatch/time.h index 02dd27f6e..56a40a499 100644 --- a/dispatch/time.h +++ b/dispatch/time.h @@ -66,7 +66,7 @@ struct timespec; */ typedef uint64_t dispatch_time_t; -enum { +enum : unsigned long long { DISPATCH_WALLTIME_NOW DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = ~1ull, }; diff --git a/dispatch/workloop.h b/dispatch/workloop.h index 98c4f8a41..7ca103c35 100644 --- a/dispatch/workloop.h +++ b/dispatch/workloop.h @@ -133,6 +133,7 @@ void dispatch_workloop_set_autorelease_frequency(dispatch_workloop_t workloop, dispatch_autorelease_frequency_t frequency); +#if HAVE_MACH /*! * @function dispatch_workloop_set_os_workgroup * @@ -159,6 +160,7 @@ DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW void dispatch_workloop_set_os_workgroup(dispatch_workloop_t workloop, os_workgroup_t workgroup); +#endif __END_DECLS diff --git a/os/clock.h b/os/clock.h index 665e1d871..81832f3f8 100644 --- a/os/clock.h +++ b/os/clock.h @@ -1,7 +1,14 @@ #ifndef __OS_CLOCK__ #define __OS_CLOCK__ +#if defined(__APPLE__) #include +#elif defined(_WIN32) +#include +#elif defined(__unix__) +#include +#endif + #include /* diff --git a/os/eventlink_private.h b/os/eventlink_private.h index eb55a745b..35dd315d0 100644 --- a/os/eventlink_private.h +++ b/os/eventlink_private.h @@ -1,8 +1,11 @@ #ifndef __OS_EVENTLINK__ #define __OS_EVENTLINK__ -#include +#if HAVE_MACH #include +#endif + +#include #include __BEGIN_DECLS @@ -108,6 +111,7 @@ OS_EXPORT OS_OBJECT_WARN_UNUSED_RESULT int os_eventlink_activate(os_eventlink_t eventlink); +#if HAVE_MACH /*! * @function os_eventlink_extract_remote_port * @@ -138,6 +142,7 @@ os_eventlink_extract_remote_port(os_eventlink_t eventlink, mach_port_t *port_out OS_EXPORT OS_OBJECT_RETURNS_RETAINED os_eventlink_t _Nullable os_eventlink_create_with_port(const char *name, mach_port_t mach_port); +#endif /*! * @function os_eventlink_create_remote_with_eventlink diff --git a/os/generic_unix_base.h b/os/generic_unix_base.h index aaf6f8504..9b0802c8d 100644 --- a/os/generic_unix_base.h +++ b/os/generic_unix_base.h @@ -40,6 +40,14 @@ #define API_DEPRECATED_WITH_REPLACEMENT(...) #endif +#ifndef SPI_AVAILABLE +#define SPI_AVAILABLE(...) +#endif + +#ifndef SPI_DEPRECATED +#define SPI_DEPRECATED(...) +#endif + #if __GNUC__ #define OS_EXPECT(x, v) __builtin_expect((x), (v)) #define OS_UNUSED __attribute__((__unused__)) diff --git a/os/generic_win_base.h b/os/generic_win_base.h index afc5f4265..0ba5bd028 100644 --- a/os/generic_win_base.h +++ b/os/generic_win_base.h @@ -46,6 +46,14 @@ typedef void pthread_attr_t; #define API_DEPRECATED_WITH_REPLACEMENT(...) #endif +#ifndef SPI_AVAILABLE +#define SPI_AVAILABLE(...) +#endif + +#ifndef SPI_DEPRECATED +#define SPI_DEPRECATED(...) +#endif + #if !defined(__has_attribute) #define __has_attribute(attibute) 0 #endif @@ -99,6 +107,18 @@ typedef void pthread_attr_t; #define OS_SWIFT_UNAVAILABLE(msg) #endif +#if __has_attribute(swift_private) +# define OS_REFINED_FOR_SWIFT __attribute__((__swift_private__)) +#else +# define OS_REFINED_FOR_SWIFT +#endif + +#if __has_attribute(swift_name) +# define OS_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name))) +#else +# define OS_SWIFT_NAME(_name) +#endif + #define __OS_STRINGIFY(s) #s #define OS_STRINGIFY(s) __OS_STRINGIFY(s) diff --git a/os/voucher_private.h b/os/voucher_private.h index 3e72c919a..dec03b3c3 100644 --- a/os/voucher_private.h +++ b/os/voucher_private.h @@ -128,7 +128,7 @@ voucher_adopt(voucher_t _Nullable voucher OS_OBJECT_CONSUMED); */ SPI_AVAILABLE(macos(12.0), ios(15.0)) -__header_always_inline bool +DISPATCH_ALWAYS_INLINE static bool voucher_needs_adopt(voucher_t _Nullable voucher) { #if __APPLE__ @@ -136,6 +136,7 @@ voucher_needs_adopt(voucher_t _Nullable voucher) return (((void *) voucher) != _pthread_getspecific_direct(OS_VOUCHER_TSD_KEY)); } #endif + (void)voucher; return true; } diff --git a/private/channel_private.h b/private/channel_private.h index 9c2ecf626..ca5ff7efc 100644 --- a/private/channel_private.h +++ b/private/channel_private.h @@ -259,7 +259,7 @@ dispatch_channel_create(const char *_Nullable label, API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0), bridgeos(4.0)) DISPATCH_EXPORT DISPATCH_NOTHROW DISPATCH_NONNULL_ALL void -dispatch_channel_wakeup(dispatch_channel_t channel, qos_class_t qos_class); +dispatch_channel_wakeup(dispatch_channel_t channel, dispatch_qos_class_t qos_class); /*! @typedef dispatch_channel_enumerator_handler_t * diff --git a/private/private.h b/private/private.h index e49d15c95..a98ecd835 100644 --- a/private/private.h +++ b/private/private.h @@ -67,7 +67,9 @@ #endif #include #include +#if HAVE_MACH #include +#endif #include #include #include diff --git a/private/queue_private.h b/private/queue_private.h index 199fcaeed..011c1e3b7 100644 --- a/private/queue_private.h +++ b/private/queue_private.h @@ -537,7 +537,7 @@ SPI_AVAILABLE(macos(12.0), ios(15.0)) DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 void dispatch_async_swift_job(dispatch_queue_t queue, void *swift_job, - qos_class_t qos); + dispatch_qos_class_t qos); __END_DECLS diff --git a/private/time_private.h b/private/time_private.h index e8dd1accf..6495af2c6 100644 --- a/private/time_private.h +++ b/private/time_private.h @@ -49,7 +49,7 @@ __BEGIN_DECLS * dispatch_source_set_timer(ds, t, 10 * NSEC_PER_SEC, 0); * dispatch_activate(ds); */ -enum { +enum : unsigned long long { DISPATCH_MONOTONICTIME_NOW DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = (1ull << 63) }; diff --git a/src/benchmark.c b/src/benchmark.c index 259a67ca5..309c2106a 100644 --- a/src/benchmark.c +++ b/src/benchmark.c @@ -60,7 +60,7 @@ _dispatch_benchmark_init(void *context) } while (i < cnt); delta = _dispatch_uptime() - start; - lcost = (typeof(lcost)) delta; + lcost = (__typeof__(lcost)) delta; #if HAVE_MACH_ABSOLUTE_TIME lcost *= bdata->tbi.numer; lcost /= bdata->tbi.denom; @@ -113,7 +113,7 @@ dispatch_benchmark_f(size_t count, register void *ctxt, } while (i < count); delta = _dispatch_uptime() - start; - conversion = (typeof(conversion)) delta; + conversion = (__typeof__(conversion)) delta; #if HAVE_MACH_ABSOLUTE_TIME conversion *= bdata.tbi.numer; big_denom = bdata.tbi.denom; diff --git a/src/event/event.c b/src/event/event.c index b908419d2..6f00f2f47 100644 --- a/src/event/event.c +++ b/src/event/event.c @@ -760,9 +760,9 @@ _dispatch_timer_heap_update(dispatch_timer_heap_t dth, #pragma mark timer unote #define _dispatch_timer_du_debug(what, du) \ - _dispatch_debug("kevent-source[%p]: %s kevent[%p] { ident = 0x%x }", \ + _dispatch_debug("kevent-source[%p]: %s kevent[%p] { ident = 0x%llx }", \ _dispatch_wref2ptr((du)->du_owner_wref), what, \ - (du), (du)->du_ident) + (du), (unsigned long long)(du)->du_ident) DISPATCH_ALWAYS_INLINE static inline unsigned int diff --git a/src/event/event_windows.c b/src/event/event_windows.c index 94674a3bf..a65dd8a3c 100644 --- a/src/event/event_windows.c +++ b/src/event/event_windows.c @@ -974,6 +974,12 @@ _dispatch_event_loop_end_ownership(dispatch_wlh_t wlh, uint64_t old_state, (void)wlh; (void)old_state; (void)new_state; (void)flags; } +void +_dispatch_event_loop_ensure_ownership(dispatch_wlh_t wlh) +{ + (void)wlh; +} + #if DISPATCH_WLH_DEBUG void _dispatch_event_loop_assert_not_owned(dispatch_wlh_t wlh) diff --git a/src/init.c b/src/init.c index 08f790828..23b4ea722 100644 --- a/src/init.c +++ b/src/init.c @@ -342,6 +342,7 @@ struct dispatch_queue_global_s _dispatch_root_queues[] = { #define _DISPATCH_COOPERATIVE_ROOT_QUEUE_ENTRY(n, flags, ...) \ [_DISPATCH_ROOT_QUEUE_IDX(n, flags)] = { \ .do_vtable = DISPATCH_VTABLE(queue_concurrent), \ + .do_ctxt = _dispatch_root_queue_ctxt(_DISPATCH_ROOT_QUEUE_IDX(n, flags)), \ .dq_priority = flags | ((flags & DISPATCH_PRIORITY_FLAG_FALLBACK) ? \ _dispatch_priority_make_fallback(DISPATCH_QOS_##n) : \ _dispatch_priority_make(DISPATCH_QOS_##n, 0)), \ diff --git a/src/internal.h b/src/internal.h index d22a3ac09..269ba866a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -219,10 +219,12 @@ upcast(dispatch_object_t dou) #endif // __OBJC__ #include +#if HAVE_MACH #include #include #include #include +#endif #include #include #include @@ -241,14 +243,18 @@ upcast(dispatch_object_t dou) #endif #include "os/object_private.h" #include "os/eventlink_private.h" +#if HAVE_MACH #include "os/workgroup_object_private.h" #include "os/workgroup_interval_private.h" +#endif #include "apply_private.h" #include "queue_private.h" #include "channel_private.h" #include "workloop_private.h" #include "source_private.h" +#if HAVE_MACH #include "mach_private.h" +#endif #include "data_private.h" #include "time_private.h" #include "os/voucher_private.h" @@ -587,11 +593,11 @@ void _dispatch_log(const char *msg, ...); */ DISPATCH_ALWAYS_INLINE static inline void -_dispatch_assert(long e, size_t line) DISPATCH_STATIC_ASSERT_IF(!e) +_dispatch_assert(long long e, size_t line) DISPATCH_STATIC_ASSERT_IF(!e) { if (unlikely(DISPATCH_DEBUG && !e)) _dispatch_abort(line, e); } -#define dispatch_assert(e) _dispatch_assert((long)(e), __LINE__) +#define dispatch_assert(e) _dispatch_assert((long long)(e), __LINE__) /* * A lot of API return zero upon success and not-zero on fail. Let's capture @@ -599,11 +605,11 @@ _dispatch_assert(long e, size_t line) DISPATCH_STATIC_ASSERT_IF(!e) */ DISPATCH_ALWAYS_INLINE static inline void -_dispatch_assert_zero(long e, size_t line) DISPATCH_STATIC_ASSERT_IF(e) +_dispatch_assert_zero(long long e, size_t line) DISPATCH_STATIC_ASSERT_IF(e) { if (unlikely(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_zero((long long)(e), __LINE__) /* * For reporting bugs or impedance mismatches between libdispatch and external @@ -613,12 +619,12 @@ _dispatch_assert_zero(long e, size_t line) DISPATCH_STATIC_ASSERT_IF(e) */ DISPATCH_ALWAYS_INLINE static inline void -_dispatch_assume(long e, size_t line) DISPATCH_STATIC_ASSERT_IF(!e) +_dispatch_assume(long long e, size_t line) DISPATCH_STATIC_ASSERT_IF(!e) { if (unlikely(!e)) _dispatch_bug(line, e); } #define dispatch_assume(e) \ - ({ __typeof__(e) _e = (e); _dispatch_assume((long)_e, __LINE__); _e; }) + ({ __typeof__(e) _e = (e); _dispatch_assume((long long)_e, __LINE__); _e; }) /* * A lot of API return zero upon success and not-zero on fail. Let's capture @@ -1180,7 +1186,9 @@ extern bool _dispatch_kevent_workqueue_enabled; /* #includes dependent on internal.h */ #include "object_internal.h" +#if HAVE_MACH #include "workgroup_internal.h" +#endif #include "eventlink_internal.h" #include "semaphore_internal.h" #include "introspection_internal.h" diff --git a/src/queue.c b/src/queue.c index 44cdb4aa5..0bbc11b43 100644 --- a/src/queue.c +++ b/src/queue.c @@ -794,7 +794,10 @@ _dispatch_async_redirect_invoke(dispatch_continuation_t dc, { dispatch_thread_frame_s dtf; struct dispatch_continuation_s *other_dc = dc->dc_other; - dispatch_invoke_flags_t ctxt_flags = (dispatch_invoke_flags_t)dc->dc_ctxt; +#if DISPATCH_SIZEOF_PTR == 8 + dispatch_assert(((uintptr_t)dc->dc_ctxt >> 32) == 0); +#endif + dispatch_invoke_flags_t ctxt_flags = (dispatch_invoke_flags_t)(uintptr_t)dc->dc_ctxt; // if we went through _dispatch_root_queue_push_override, // the "right" root queue was stuffed into dc_func dispatch_queue_global_t assumed_rq = (dispatch_queue_global_t)dc->dc_func; @@ -4056,9 +4059,11 @@ static void _dispatch_workloop_attributes_dispose(dispatch_workloop_t dwl) { if (dwl->dwl_attr) { +#if HAVE_MACH if (dwl->dwl_attr->workgroup) { _os_object_release(dwl->dwl_attr->workgroup->_as_os_obj); } +#endif free(dwl->dwl_attr); } } @@ -4127,6 +4132,7 @@ dispatch_workloop_set_qos_class_floor(dispatch_workloop_t dwl, #endif // TARGET_OS_MAC } +#if HAVE_MACH void dispatch_workloop_set_os_workgroup(dispatch_workloop_t dwl, os_workgroup_t wg) { @@ -4142,6 +4148,7 @@ dispatch_workloop_set_os_workgroup(dispatch_workloop_t dwl, os_workgroup_t wg) _os_object_retain(wg->_as_os_obj); dwl->dwl_attr->workgroup = wg; } +#endif void dispatch_workloop_set_qos_class(dispatch_workloop_t dwl, @@ -5758,11 +5765,11 @@ dispatch_channel_enqueue(dispatch_channel_t dch, void *ctxt) #ifndef __APPLE__ #if __BLOCKS__ -void typeof(dispatch_channel_async) dispatch_channel_async +__typeof__(dispatch_channel_async) dispatch_channel_async __attribute__((__alias__("dispatch_async"))); #endif -void typeof(dispatch_channel_async_f) dispatch_channel_async_f +__typeof__(dispatch_channel_async_f) dispatch_channel_async_f __attribute__((__alias__("dispatch_async_f"))); #endif @@ -6984,7 +6991,19 @@ _dispatch_worker_thread(void *context) /* Set it up before the configure block so that it can get overridden by * client if they want to name their threads differently */ if (dq->_as_dq->dq_label) { +#if defined(__APPLE__) pthread_setname_np(dq->_as_dq->dq_label); +#elif defined(_WIN32) + int length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, dq->_as_dq->dq_label, -1, NULL, 0); + if (length) { + WCHAR *description = calloc(length + 1, sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, dq->_as_dq->dq_label, -1, description, length); + SetThreadDescription(GetCurrentThread(), description); + free(description); + } +#else + pthread_setname_np(pthread_self(), dq->_as_dq->dq_label); +#endif } if (pqc->dpq_thread_configure) { @@ -7813,11 +7832,21 @@ _dispatch_sig_thread(void *ctxt DISPATCH_UNUSED) _dispatch_clear_stack(0); #if defined(_WIN32) Sleep(INFINITE); + __assume(0); #else _dispatch_sigsuspend(); #endif } +#if defined(_WIN32) +static unsigned WINAPI +_dispatch_sig_thread_thunk(LPVOID lpParameter) +{ + _dispatch_sig_thread(lpParameter); + return 0; +} +#endif + void dispatch_main(void) { @@ -7883,6 +7912,7 @@ _dispatch_queue_cleanup2(void) // See dispatch_main for call to _dispatch_sig_thread on linux. #ifndef __linux__ if (_dispatch_program_is_probably_callback_driven) { +#if defined(_POSIX_THREADS) pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); @@ -7892,6 +7922,13 @@ _dispatch_queue_cleanup2(void) DISPATCH_CLIENT_CRASH(r, "Unable to create signal thread"); } pthread_attr_destroy(&attr); +#else + uintptr_t hThread = 0; + if (unlikely(!(hThread = _beginthreadex(NULL, /* stack_size */ 0, _dispatch_sig_thread_thunk, NULL, STACK_SIZE_PARAM_IS_A_RESERVATION, NULL)))) { + DISPATCH_CLIENT_CRASH(errno, "unable to create signal thread"); + } + CloseHandle((HANDLE)hThread); +#endif // this used to be here as a workaround for 6778970 // but removing it had bincompat fallouts :'( sleep(1); @@ -7955,7 +7992,7 @@ _dispatch_context_cleanup(void *ctxt) #pragma mark - #pragma mark dispatch_init -#if !DISPATCH_USE_COOPERATIVE_WORKQUEUE +#if !DISPATCH_USE_INTERNAL_WORKQUEUE && !DISPATCH_USE_COOPERATIVE_WORKQUEUE static void _dispatch_cooperative_root_queue_init_fallback(dispatch_queue_global_t dq) { diff --git a/src/queue_internal.h b/src/queue_internal.h index 68a5fec23..120d8332c 100644 --- a/src/queue_internal.h +++ b/src/queue_internal.h @@ -445,6 +445,13 @@ DISPATCH_OPTIONS(dispatch_queue_flags, uint32_t, #pragma mark - #pragma mark dispatch_queue_t +typedef struct dispatch_pthread_root_queue_observer_hooks_s { + void (*queue_will_execute)(dispatch_queue_t queue); + void (*queue_did_execute)(dispatch_queue_t queue); +} dispatch_pthread_root_queue_observer_hooks_s; +typedef dispatch_pthread_root_queue_observer_hooks_s + *dispatch_pthread_root_queue_observer_hooks_t; + typedef struct dispatch_queue_specific_s { const void *dqs_key; void *dqs_ctxt; @@ -475,7 +482,9 @@ typedef struct dispatch_workloop_attr_s { uint8_t percent; uint32_t refillms; } dwla_cpupercent; +#if HAVE_MACH os_workgroup_t workgroup; +#endif dispatch_pthread_root_queue_observer_hooks_s dwla_observers; } dispatch_workloop_attr_s; @@ -651,13 +660,6 @@ struct dispatch_queue_global_s { } DISPATCH_CACHELINE_ALIGN; -typedef struct dispatch_pthread_root_queue_observer_hooks_s { - void (*queue_will_execute)(dispatch_queue_t queue); - void (*queue_did_execute)(dispatch_queue_t queue); -} dispatch_pthread_root_queue_observer_hooks_s; -typedef dispatch_pthread_root_queue_observer_hooks_s - *dispatch_pthread_root_queue_observer_hooks_t; - #ifdef __APPLE__ #define DISPATCH_IOHID_SPI 1 @@ -1240,7 +1242,7 @@ struct dispatch_apply_attr_s { uint32_t flags; size_t per_cluster_parallelism; uintptr_t guard; /* To prevent copying */ -#if defined(__LP64__) +#if DISPATCH_SIZEOF_PTR == 8 uint8_t unused[40]; #else uint8_t unused[48]; diff --git a/src/shims/atomic.h b/src/shims/atomic.h index 44af102eb..7832d544a 100644 --- a/src/shims/atomic.h +++ b/src/shims/atomic.h @@ -134,15 +134,22 @@ typedef struct { unsigned long __opaque_zero; } os_atomic_dependency_t; +#define _os_atomic_auto_dependency(e) \ + _Generic(e, \ + os_atomic_dependency_t: (e), \ + default: os_atomic_make_dependency(e)) + #define OS_ATOMIC_DEPENDENCY_NONE ((os_atomic_dependency_t){ 0UL }) #define os_atomic_make_dependency(v) ((void)(v), OS_ATOMIC_DEPENDENCY_NONE) #define os_atomic_inject_dependency(p, e) \ - ((typeof(*(p)) *)((p) + _os_atomic_auto_dependency(e).__opaque_zero)) + ((__typeof__(*(p)) *)((p) + _os_atomic_auto_dependency(e).__opaque_zero)) #define os_atomic_load_with_dependency_on(p, e) \ os_atomic_load(os_atomic_inject_dependency(p, e), dependency) #define os_atomic_thread_fence(m) atomic_thread_fence(memory_order_##m) +#define os_atomic_init(p, v) atomic_init(_os_atomic_c11_atomic(p), v) + #define os_atomic_inc(p, m) \ os_atomic_add((p), 1, m) #define os_atomic_inc_orig(p, m) \ diff --git a/src/shims/lock.c b/src/shims/lock.c index 4a750b3bd..17f8f0fae 100644 --- a/src/shims/lock.c +++ b/src/shims/lock.c @@ -507,7 +507,7 @@ _dispatch_wait_on_address(uint32_t volatile *_address, uint32_t value, return _dispatch_futex_wait(address, value, &ts, FUTEX_PRIVATE_FLAG); } return _dispatch_futex_wait(address, value, NULL, FUTEX_PRIVATE_FLAG); -#elif defined(_WIN32) +#elif HAVE_WAIT_ON_ADDRESS return WaitOnAddress(address, &value, sizeof(value), INFINITE) == TRUE; #else #error _dispatch_wait_on_address unimplemented for this platform @@ -521,7 +521,7 @@ _dispatch_wake_by_address(uint32_t volatile *address) _dispatch_ulock_wake((uint32_t *)address, ULF_WAKE_ALL); #elif HAVE_FUTEX _dispatch_futex_wake((uint32_t *)address, INT_MAX, FUTEX_PRIVATE_FLAG); -#elif defined(_WIN32) +#elif HAVE_WAIT_ON_ADDRESS WakeByAddressAll((uint32_t *)address); #else (void)address; @@ -537,6 +537,8 @@ _dispatch_thread_event_signal_slow(dispatch_thread_event_t dte) _dispatch_ulock_wake(&dte->dte_value, 0); #elif HAVE_FUTEX _dispatch_futex_wake(&dte->dte_value, 1, FUTEX_PRIVATE_FLAG); +#elif HAVE_WAIT_ON_ADDRESS + WakeByAddressSingle(&dte->dte_value); #else _dispatch_sema4_signal(&dte->dte_sema, 1); #endif @@ -545,7 +547,7 @@ _dispatch_thread_event_signal_slow(dispatch_thread_event_t dte) void _dispatch_thread_event_wait_slow(dispatch_thread_event_t dte) { -#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX +#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS for (;;) { uint32_t value = os_atomic_load(&dte->dte_value, acquire); if (likely(value == 0)) return; @@ -558,6 +560,8 @@ _dispatch_thread_event_wait_slow(dispatch_thread_event_t dte) #elif HAVE_FUTEX _dispatch_futex_wait(&dte->dte_value, UINT32_MAX, NULL, FUTEX_PRIVATE_FLAG); +#elif HAVE_WAIT_ON_ADDRESS + WaitOnAddress(&dte->dte_value, &value, sizeof(value), INFINITE); #endif } #else diff --git a/src/shims/lock.h b/src/shims/lock.h index 9c602724c..de03d25fe 100644 --- a/src/shims/lock.h +++ b/src/shims/lock.h @@ -174,6 +174,14 @@ _dispatch_lock_has_failed_trylock(dispatch_lock lock_value) #endif #endif // HAVE_FUTEX +#ifndef HAVE_WAIT_ON_ADDRESS +#if defined(_WIN32) +#define HAVE_WAIT_ON_ADDRESS 1 +#else +#define HAVE_WIAT_ON_ADDRESS 0 +#endif +#endif + #if defined(__x86_64__) || defined(__i386__) || defined(__s390x__) #define DISPATCH_ONCE_USE_QUIESCENT_COUNTER 0 #elif __APPLE__ @@ -271,7 +279,7 @@ void _dispatch_wake_by_address(uint32_t volatile *address); * This locking primitive has no notion of ownership */ typedef struct dispatch_thread_event_s { -#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX +#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS // 1 means signalled but not waited on yet // UINT32_MAX means waited on, but not signalled yet // 0 is the initial and final state @@ -289,7 +297,7 @@ DISPATCH_ALWAYS_INLINE static inline void _dispatch_thread_event_init(dispatch_thread_event_t dte) { -#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX +#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS dte->dte_value = 0; #else _dispatch_sema4_init(&dte->dte_sema, _DSEMA4_POLICY_FIFO); @@ -300,7 +308,7 @@ DISPATCH_ALWAYS_INLINE static inline void _dispatch_thread_event_signal(dispatch_thread_event_t dte) { -#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX +#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS if (os_atomic_add_orig(&dte->dte_value, 1u, release) == 0) { // 0 -> 1 transition doesn't need a signal // force a wake even when the value is corrupt, @@ -318,7 +326,7 @@ DISPATCH_ALWAYS_INLINE static inline void _dispatch_thread_event_wait(dispatch_thread_event_t dte) { -#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX +#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS if (os_atomic_sub(&dte->dte_value, 1u, acquire) == 0) { // 1 -> 0 is always a valid transition, so we can return // for any other value, take the slow path which checks it's not corrupt @@ -334,7 +342,7 @@ DISPATCH_ALWAYS_INLINE static inline void _dispatch_thread_event_destroy(dispatch_thread_event_t dte) { -#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX +#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS // nothing to do dispatch_assert(dte->dte_value == 0); #else diff --git a/src/shims/yield.h b/src/shims/yield.h index aeb429d44..fd8bf0088 100644 --- a/src/shims/yield.h +++ b/src/shims/yield.h @@ -161,14 +161,14 @@ void *_dispatch_wait_for_enqueuer(void **ptr, void **tailp); #define _dispatch_preemption_yield_to(th, n) thread_switch(th, \ DISPATCH_YIELD_THREAD_SWITCH_OPTION, (mach_msg_timeout_t)(n)) #elif HAVE_PTHREAD_YIELD_NP -#define _dispatch_preemption_yield(n) { (void)n; pthread_yield_np(); } -#define _dispatch_preemption_yield_to(th, n) { (void)n; pthread_yield_np(); } +#define _dispatch_preemption_yield(n) ({ (void)n; pthread_yield_np(); }) +#define _dispatch_preemption_yield_to(th, n) ({ (void)n; pthread_yield_np(); }) #elif defined(_WIN32) -#define _dispatch_preemption_yield(n) { (void)n; Sleep(0); } -#define _dispatch_preemption_yield_to(th, n) { (void)n; Sleep(0); } +#define _dispatch_preemption_yield(n) ({ (void)n; Sleep(0); }) +#define _dispatch_preemption_yield_to(th, n) ({ (void)n; Sleep(0); }) #else -#define _dispatch_preemption_yield(n) { (void)n; sched_yield(); } -#define _dispatch_preemption_yield_to(th, n) { (void)n; sched_yield(); } +#define _dispatch_preemption_yield(n) ({ (void)n; sched_yield(); }) +#define _dispatch_preemption_yield_to(th, n) ({ (void)n; sched_yield(); }) #endif // HAVE_MACH #if DISPATCH_HAVE_YIELD_TO_ENQUEUER diff --git a/src/source.c b/src/source.c index 9af2a4a8b..4ee634933 100644 --- a/src/source.c +++ b/src/source.c @@ -1449,11 +1449,11 @@ _dispatch_source_debug_attr(dispatch_source_t ds, char* buf, size_t bufsiz) dispatch_source_refs_t dr = ds->ds_refs; dispatch_queue_flags_t dqf = _dispatch_queue_atomic_flags(ds); dispatch_unote_state_t du_state = _dispatch_unote_state(dr); - return dsnprintf(buf, bufsiz, "target = %s[%p], ident = 0x%x, " + return dsnprintf(buf, bufsiz, "target = %s[%p], ident = 0x%llx, " "mask = 0x%x, pending_data = 0x%llx, registered = %d, " "armed = %d, %s%s%s", target && target->dq_label ? target->dq_label : "", target, - dr->du_ident, dr->du_fflags, (unsigned long long)dr->ds_pending_data, + (unsigned long long)dr->du_ident, dr->du_fflags, (unsigned long long)dr->ds_pending_data, _du_state_registered(du_state), _du_state_armed(du_state), (dqf & DSF_CANCELED) ? "cancelled, " : "", (dqf & DSF_NEEDS_EVENT) ? "needs-event, " : "", diff --git a/src/swift/Block.swift b/src/swift/Block.swift index 71d998ba6..c9fd90a33 100644 --- a/src/swift/Block.swift +++ b/src/swift/Block.swift @@ -41,9 +41,9 @@ public class DispatchWorkItem { public init(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], block: @escaping @convention(block) () -> ()) { #if os(Windows) && (arch(arm64) || arch(x86_64)) - let flags = dispatch_block_flags_t(UInt32(flags.rawValue)) + let flags = dispatch_block_flags_t(rawValue: UInt32(flags.rawValue)) #else - let flags: dispatch_block_flags_t = numericCast(flags.rawValue) + let flags = dispatch_block_flags_t(rawValue: flags.rawValue) #endif _block = dispatch_block_create_with_qos_class(flags, qos.qosClass.rawValue.rawValue, Int32(qos.relativePriority), block) @@ -53,9 +53,9 @@ public class DispatchWorkItem { // dispatch_block_t, as we know the lifetime of the block in question. internal init(flags: DispatchWorkItemFlags = [], noescapeBlock: () -> ()) { #if os(Windows) && (arch(arm64) || arch(x86_64)) - let flags = dispatch_block_flags_t(UInt32(flags.rawValue)) + let flags = dispatch_block_flags_t(rawValue: UInt32(flags.rawValue)) #else - let flags: dispatch_block_flags_t = numericCast(flags.rawValue) + let flags = dispatch_block_flags_t(rawValue: flags.rawValue) #endif _block = _swift_dispatch_block_create_noescape(flags, noescapeBlock) } diff --git a/src/swift/Queue.swift b/src/swift/Queue.swift index fe7406c42..7b6e12a2e 100644 --- a/src/swift/Queue.swift +++ b/src/swift/Queue.swift @@ -98,13 +98,13 @@ extension DispatchQueue { switch self { case .inherit: // DISPATCH_AUTORELEASE_FREQUENCY_INHERIT - return CDispatch.dispatch_queue_attr_make_with_autorelease_frequency(attr, dispatch_autorelease_frequency_t(0)) + return CDispatch.dispatch_queue_attr_make_with_autorelease_frequency(attr, dispatch_autorelease_frequency_t(rawValue: 0)!) case .workItem: // DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM - return CDispatch.dispatch_queue_attr_make_with_autorelease_frequency(attr, dispatch_autorelease_frequency_t(1)) + return CDispatch.dispatch_queue_attr_make_with_autorelease_frequency(attr, dispatch_autorelease_frequency_t(rawValue: 1)!) case .never: // DISPATCH_AUTORELEASE_FREQUENCY_NEVER - return CDispatch.dispatch_queue_attr_make_with_autorelease_frequency(attr, dispatch_autorelease_frequency_t(2)) + return CDispatch.dispatch_queue_attr_make_with_autorelease_frequency(attr, dispatch_autorelease_frequency_t(rawValue: 2)!) } } else { return attr diff --git a/src/voucher.c b/src/voucher.c index 61f1643df..e4d5e72da 100644 --- a/src/voucher.c +++ b/src/voucher.c @@ -1987,14 +1987,13 @@ voucher_get_current_persona_proximate_info(struct proc_persona_info *persona_inf } #endif // __has_include() -bool -voucher_process_can_use_arbitrary_personas(void) +void +_voucher_activity_debug_channel_init(void) { - return false; } void -_voucher_activity_debug_channel_init(void) +_voucher_atfork_parent(void) { }