@@ -56,6 +56,18 @@ _dispatch_thread_switch(dispatch_lock value, dispatch_lock_options_t flags,
56
56
#endif
57
57
#endif
58
58
59
+ #if defined(__unix__ )
60
+ DISPATCH_ALWAYS_INLINE
61
+ static inline void
62
+ _dispatch_thread_switch (dispatch_lock value , dispatch_lock_options_t flags ,
63
+ uint32_t timeout )
64
+ {
65
+ (void )value ;
66
+ (void )flags ;
67
+ (void )timeout ;
68
+ }
69
+ #endif
70
+
59
71
#pragma mark - semaphores
60
72
61
73
#if USE_MACH_SEM
@@ -394,8 +406,10 @@ _dispatch_unfair_lock_wake(uint32_t *uaddr, uint32_t flags)
394
406
#include <sys/time.h>
395
407
#ifdef __ANDROID__
396
408
#include <sys/syscall.h>
397
- #else
409
+ #elif __linux__
398
410
#include <syscall.h>
411
+ #else
412
+ #include <sys/futex.h>
399
413
#endif /* __ANDROID__ */
400
414
401
415
DISPATCH_ALWAYS_INLINE
@@ -404,7 +418,12 @@ _dispatch_futex(uint32_t *uaddr, int op, uint32_t val,
404
418
const struct timespec * timeout , uint32_t * uaddr2 , uint32_t val3 ,
405
419
int opflags )
406
420
{
421
+ #if __linux__
407
422
return (int )syscall (SYS_futex , uaddr , op | opflags , val , timeout , uaddr2 , val3 );
423
+ #else
424
+ (void )val3 ;
425
+ return futex (uaddr , op | opflags , (int )val , timeout , uaddr2 );
426
+ #endif
408
427
}
409
428
410
429
// returns 0, ETIMEDOUT, EFAULT, EINTR, EWOULDBLOCK
@@ -414,11 +433,15 @@ _futex_blocking_op(uint32_t *uaddr, int futex_op, uint32_t val,
414
433
const struct timespec * timeout , int flags )
415
434
{
416
435
for (;;) {
417
- int rc = _dispatch_futex (uaddr , futex_op , val , timeout , NULL , 0 , flags );
418
- if (!rc ) {
436
+ int err = _dispatch_futex (uaddr , futex_op , val , timeout , NULL , 0 , flags );
437
+ if (!err ) {
419
438
return 0 ;
420
439
}
421
- switch (errno ) {
440
+ #if __linux__
441
+ // syscall sets errno to communicate error code.
442
+ err = errno
443
+ #endif
444
+ switch (err ) {
422
445
case EINTR :
423
446
/*
424
447
* if we have a timeout, we need to return for the caller to
@@ -454,6 +477,7 @@ _dispatch_futex_wake(uint32_t *uaddr, int wake, int opflags)
454
477
DISPATCH_INTERNAL_CRASH (errno , "_dlock_wake() failed" );
455
478
}
456
479
480
+ #if HAVE_FUTEX_PI
457
481
static void
458
482
_dispatch_futex_lock_pi (uint32_t * uaddr , struct timespec * timeout , int detect ,
459
483
int opflags )
@@ -471,6 +495,7 @@ _dispatch_futex_unlock_pi(uint32_t *uaddr, int opflags)
471
495
if (rc == 0 ) return ;
472
496
DISPATCH_CLIENT_CRASH (errno , "futex_unlock_pi() failed" );
473
497
}
498
+ #endif
474
499
475
500
#endif
476
501
#pragma mark - wait for address
@@ -599,7 +624,7 @@ _dispatch_unfair_lock_lock_slow(dispatch_unfair_lock_t dul,
599
624
}
600
625
}
601
626
}
602
- #elif HAVE_FUTEX
627
+ #elif HAVE_FUTEX_PI
603
628
void
604
629
_dispatch_unfair_lock_lock_slow (dispatch_unfair_lock_t dul ,
605
630
dispatch_lock_options_t flags )
@@ -636,7 +661,7 @@ _dispatch_unfair_lock_unlock_slow(dispatch_unfair_lock_t dul, dispatch_lock cur)
636
661
if (_dispatch_lock_has_waiters (cur )) {
637
662
_dispatch_unfair_lock_wake (& dul -> dul_lock , 0 );
638
663
}
639
- #elif HAVE_FUTEX
664
+ #elif HAVE_FUTEX_PI
640
665
// futex_unlock_pi() handles both OWNER_DIED which we abuse & WAITERS
641
666
_dispatch_futex_unlock_pi (& dul -> dul_lock , FUTEX_PRIVATE_FLAG );
642
667
#else
0 commit comments