Skip to content

Commit ef765a3

Browse files
committed
shims: add a new HAVE_WAIT_ON_ADDRESS and adopt in locks
This introduces a new `HAVE_WAIT_ON_ADDRESS` which is the equivalent to `HAVE_FUTEX` on Linux. Extend the other sites to use this rather than `defined(_WIN32)`. This identified a couple of additional sites that required updating which is included in this change now.
1 parent c4c3516 commit ef765a3

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

src/shims/lock.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ _dispatch_wait_on_address(uint32_t volatile *_address, uint32_t value,
507507
return _dispatch_futex_wait(address, value, &ts, FUTEX_PRIVATE_FLAG);
508508
}
509509
return _dispatch_futex_wait(address, value, NULL, FUTEX_PRIVATE_FLAG);
510-
#elif defined(_WIN32)
510+
#elif HAVE_WAIT_ON_ADDRESS
511511
return WaitOnAddress(address, &value, sizeof(value), INFINITE) == TRUE;
512512
#else
513513
#error _dispatch_wait_on_address unimplemented for this platform
@@ -521,7 +521,7 @@ _dispatch_wake_by_address(uint32_t volatile *address)
521521
_dispatch_ulock_wake((uint32_t *)address, ULF_WAKE_ALL);
522522
#elif HAVE_FUTEX
523523
_dispatch_futex_wake((uint32_t *)address, INT_MAX, FUTEX_PRIVATE_FLAG);
524-
#elif defined(_WIN32)
524+
#elif HAVE_WAIT_ON_ADDRESS
525525
WakeByAddressAll((uint32_t *)address);
526526
#else
527527
(void)address;
@@ -537,6 +537,8 @@ _dispatch_thread_event_signal_slow(dispatch_thread_event_t dte)
537537
_dispatch_ulock_wake(&dte->dte_value, 0);
538538
#elif HAVE_FUTEX
539539
_dispatch_futex_wake(&dte->dte_value, 1, FUTEX_PRIVATE_FLAG);
540+
#elif HAVE_WAIT_ON_ADDRESS
541+
WakeByAddressSingle(&dte->dte_value);
540542
#else
541543
_dispatch_sema4_signal(&dte->dte_sema, 1);
542544
#endif
@@ -545,7 +547,7 @@ _dispatch_thread_event_signal_slow(dispatch_thread_event_t dte)
545547
void
546548
_dispatch_thread_event_wait_slow(dispatch_thread_event_t dte)
547549
{
548-
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
550+
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS
549551
for (;;) {
550552
uint32_t value = os_atomic_load(&dte->dte_value, acquire);
551553
if (likely(value == 0)) return;
@@ -558,6 +560,8 @@ _dispatch_thread_event_wait_slow(dispatch_thread_event_t dte)
558560
#elif HAVE_FUTEX
559561
_dispatch_futex_wait(&dte->dte_value, UINT32_MAX,
560562
NULL, FUTEX_PRIVATE_FLAG);
563+
#elif HAVE_WAIT_ON_ADDRESS
564+
WaitOnAddress(&dte->dte_value, &value, sizeof(value), INFINITE);
561565
#endif
562566
}
563567
#else

src/shims/lock.h

+13-5
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ _dispatch_lock_has_failed_trylock(dispatch_lock lock_value)
174174
#endif
175175
#endif // HAVE_FUTEX
176176

177+
#ifndef HAVE_WAIT_ON_ADDRESS
178+
#if defined(_WIN32)
179+
#define HAVE_WAIT_ON_ADDRESS 1
180+
#else
181+
#define HAVE_WIAT_ON_ADDRESS 0
182+
#endif
183+
#endif
184+
177185
#if defined(__x86_64__) || defined(__i386__) || defined(__s390x__)
178186
#define DISPATCH_ONCE_USE_QUIESCENT_COUNTER 0
179187
#elif __APPLE__
@@ -271,7 +279,7 @@ void _dispatch_wake_by_address(uint32_t volatile *address);
271279
* This locking primitive has no notion of ownership
272280
*/
273281
typedef struct dispatch_thread_event_s {
274-
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
282+
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS
275283
// 1 means signalled but not waited on yet
276284
// UINT32_MAX means waited on, but not signalled yet
277285
// 0 is the initial and final state
@@ -289,7 +297,7 @@ DISPATCH_ALWAYS_INLINE
289297
static inline void
290298
_dispatch_thread_event_init(dispatch_thread_event_t dte)
291299
{
292-
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
300+
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS
293301
dte->dte_value = 0;
294302
#else
295303
_dispatch_sema4_init(&dte->dte_sema, _DSEMA4_POLICY_FIFO);
@@ -300,7 +308,7 @@ DISPATCH_ALWAYS_INLINE
300308
static inline void
301309
_dispatch_thread_event_signal(dispatch_thread_event_t dte)
302310
{
303-
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
311+
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS
304312
if (os_atomic_add_orig(&dte->dte_value, 1u, release) == 0) {
305313
// 0 -> 1 transition doesn't need a signal
306314
// force a wake even when the value is corrupt,
@@ -318,7 +326,7 @@ DISPATCH_ALWAYS_INLINE
318326
static inline void
319327
_dispatch_thread_event_wait(dispatch_thread_event_t dte)
320328
{
321-
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
329+
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS
322330
if (os_atomic_sub(&dte->dte_value, 1u, acquire) == 0) {
323331
// 1 -> 0 is always a valid transition, so we can return
324332
// for any other value, take the slow path which checks it's not corrupt
@@ -334,7 +342,7 @@ DISPATCH_ALWAYS_INLINE
334342
static inline void
335343
_dispatch_thread_event_destroy(dispatch_thread_event_t dte)
336344
{
337-
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX
345+
#if HAVE_UL_COMPARE_AND_WAIT || HAVE_FUTEX || HAVE_WAIT_ON_ADDRESS
338346
// nothing to do
339347
dispatch_assert(dte->dte_value == 0);
340348
#else

0 commit comments

Comments
 (0)