diff options
Diffstat (limited to 'nptl/sysdeps/pthread/pthread_cond_signal.c')
-rw-r--r-- | nptl/sysdeps/pthread/pthread_cond_signal.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/nptl/sysdeps/pthread/pthread_cond_signal.c b/nptl/sysdeps/pthread/pthread_cond_signal.c index 1a035fe05f..b9d8af07b2 100644 --- a/nptl/sysdeps/pthread/pthread_cond_signal.c +++ b/nptl/sysdeps/pthread/pthread_cond_signal.c @@ -25,13 +25,15 @@ #include <pthreadP.h> #include <shlib-compat.h> +#include <kernel-features.h> + int __pthread_cond_signal (cond) pthread_cond_t *cond; { /* Make sure we are alone. */ - lll_mutex_lock(cond->__data.__lock); + lll_mutex_lock (cond->__data.__lock); /* Are there any waiters to be woken? */ if (cond->__data.__total_seq > cond->__data.__wakeup_seq) @@ -50,7 +52,22 @@ __pthread_cond_signal (cond) #endif /* Wake one. */ - lll_futex_wake (futex, 1); + int r = lll_futex_requeue (futex, 0, 1, &cond->__data.__lock); + if (__builtin_expect (r == -EINVAL, 0)) + { + /* The requeue functionality is not available. */ +#ifndef __ASSUME_FUTEX_REQUEUE + lll_futex_wake (futex, 1); +#endif + } + else if (r != 0) + { + /* We always have to make the syscall if requeue actually + moved a thread. */ + lll_mutex_unlock_force (cond->__data.__lock); + + return 0; + } } /* We are done. */ |