@@ -56,6 +56,18 @@ _dispatch_thread_switch(dispatch_lock value, dispatch_lock_options_t flags,
5656#endif
5757#endif
5858
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+
5971#pragma mark - semaphores
6072
6173#if USE_MACH_SEM
@@ -394,8 +406,10 @@ _dispatch_unfair_lock_wake(uint32_t *uaddr, uint32_t flags)
394406#include <sys/time.h>
395407#ifdef __ANDROID__
396408#include <sys/syscall.h>
397- #else
409+ #elif __linux__
398410#include <syscall.h>
411+ #else
412+ #include <sys/futex.h>
399413#endif /* __ANDROID__ */
400414
401415DISPATCH_ALWAYS_INLINE
@@ -404,7 +418,12 @@ _dispatch_futex(uint32_t *uaddr, int op, uint32_t val,
404418 const struct timespec * timeout , uint32_t * uaddr2 , uint32_t val3 ,
405419 int opflags )
406420{
421+ #if __linux__
407422 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
408427}
409428
410429// returns 0, ETIMEDOUT, EFAULT, EINTR, EWOULDBLOCK
@@ -414,11 +433,15 @@ _futex_blocking_op(uint32_t *uaddr, int futex_op, uint32_t val,
414433 const struct timespec * timeout , int flags )
415434{
416435 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 ) {
419438 return 0 ;
420439 }
421- switch (errno ) {
440+ #if __linux__
441+ // syscall sets errno to communicate error code.
442+ err = errno
443+ #endif
444+ switch (err ) {
422445 case EINTR :
423446 /*
424447 * 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)
454477 DISPATCH_INTERNAL_CRASH (errno , "_dlock_wake() failed" );
455478}
456479
480+ #if HAVE_FUTEX_PI
457481static void
458482_dispatch_futex_lock_pi (uint32_t * uaddr , struct timespec * timeout , int detect ,
459483 int opflags )
@@ -471,6 +495,7 @@ _dispatch_futex_unlock_pi(uint32_t *uaddr, int opflags)
471495 if (rc == 0 ) return ;
472496 DISPATCH_CLIENT_CRASH (errno , "futex_unlock_pi() failed" );
473497}
498+ #endif
474499
475500#endif
476501#pragma mark - wait for address
@@ -605,7 +630,7 @@ _dispatch_unfair_lock_lock_slow(dispatch_unfair_lock_t dul,
605630 }
606631 }
607632}
608- #elif HAVE_FUTEX
633+ #elif HAVE_FUTEX_PI
609634void
610635_dispatch_unfair_lock_lock_slow (dispatch_unfair_lock_t dul ,
611636 dispatch_lock_options_t flags )
@@ -642,7 +667,7 @@ _dispatch_unfair_lock_unlock_slow(dispatch_unfair_lock_t dul, dispatch_lock cur)
642667 if (_dispatch_lock_has_waiters (cur )) {
643668 _dispatch_unfair_lock_wake (& dul -> dul_lock , 0 );
644669 }
645- #elif HAVE_FUTEX
670+ #elif HAVE_FUTEX_PI
646671 // futex_unlock_pi() handles both OWNER_DIED which we abuse & WAITERS
647672 _dispatch_futex_unlock_pi (& dul -> dul_lock , FUTEX_PRIVATE_FLAG );
648673#else
0 commit comments