diff options
Diffstat (limited to 'nptl/pthread_cond_broadcast.c')
-rw-r--r-- | nptl/pthread_cond_broadcast.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c index 968ee03da7..0702ec0ec2 100644 --- a/nptl/pthread_cond_broadcast.c +++ b/nptl/pthread_cond_broadcast.c @@ -53,34 +53,37 @@ __pthread_cond_broadcast (cond) /* We are done. */ lll_unlock (cond->__data.__lock, pshared); - /* Do not use requeue for pshared condvars. */ - if (cond->__data.__mutex == (void *) ~0l) - goto wake_all; - /* Wake everybody. */ pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex; - /* XXX: Kernel so far doesn't support requeue to PI futex. */ - /* XXX: Kernel so far can only requeue to the same type of futex, - in this case private (we don't requeue for pshared condvars). */ - if (__builtin_expect (mut->__data.__kind - & (PTHREAD_MUTEX_PRIO_INHERIT_NP - | PTHREAD_MUTEX_PSHARED_BIT), 0)) + /* Do not use requeue for pshared condvars. */ + if (mut == (void *) ~0l + || PTHREAD_MUTEX_PSHARED (mut) & PTHREAD_MUTEX_PSHARED_BIT) goto wake_all; - /* lll_futex_requeue returns 0 for success and non-zero - for errors. */ - if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1, - INT_MAX, &mut->__data.__lock, - futex_val, LLL_PRIVATE), 0)) +#if (defined lll_futex_cmp_requeue_pi \ + && defined __ASSUME_REQUEUE_PI) + int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP; + pi_flag &= mut->__data.__kind; + + if (pi_flag == PTHREAD_MUTEX_PRIO_INHERIT_NP) { - /* The requeue functionality is not available. */ - wake_all: - lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared); + if (lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, INT_MAX, + &mut->__data.__lock, futex_val, + LLL_PRIVATE) == 0) + return 0; } - - /* That's all. */ - return 0; + else +#endif + /* lll_futex_requeue returns 0 for success and non-zero + for errors. */ + if (!__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1, + INT_MAX, &mut->__data.__lock, + futex_val, LLL_PRIVATE), 0)) + return 0; + +wake_all: + lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared); } /* We are done. */ |