aboutsummaryrefslogtreecommitdiff
path: root/nptl/pthread_cond_signal.c
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2013-02-18 16:07:10 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2013-02-18 16:07:10 +0530
commit8313cb997d2da2465c8560d3164358a68ea1e9ad (patch)
treeb48995a23e51dc148f6a493b68faa9de83c6acdd /nptl/pthread_cond_signal.c
parentf78b5caa6ece23ce86f6cabac8edf3ecd6850473 (diff)
downloadglibc-8313cb997d2da2465c8560d3164358a68ea1e9ad.zip
glibc-8313cb997d2da2465c8560d3164358a68ea1e9ad.tar.gz
glibc-8313cb997d2da2465c8560d3164358a68ea1e9ad.tar.bz2
FUTEX_*_REQUEUE_PI support for non-x86 code
Add FUTEX_*_REQUEUE_PI support for the default C code and also add implementations for s-390 and ppc.
Diffstat (limited to 'nptl/pthread_cond_signal.c')
-rw-r--r--nptl/pthread_cond_signal.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
index 908a2ac..102d0b3 100644
--- a/nptl/pthread_cond_signal.c
+++ b/nptl/pthread_cond_signal.c
@@ -47,12 +47,35 @@ __pthread_cond_signal (cond)
++cond->__data.__wakeup_seq;
++cond->__data.__futex;
- /* Wake one. */
- if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1,
- 1, &cond->__data.__lock,
- pshared), 0))
- return 0;
+#if (defined lll_futex_cmp_requeue_pi \
+ && defined __ASSUME_REQUEUE_PI)
+ int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP;
+ pthread_mutex_t *mut = cond->__data.__mutex;
+ /* Do not use requeue for pshared condvars. */
+ if (mut != (void *) ~0l)
+ pi_flag &= mut->__data.__kind;
+
+ if (__builtin_expect (pi_flag == PTHREAD_MUTEX_PRIO_INHERIT_NP, 0)
+ /* This can only really fail with a ENOSYS, since nobody can modify
+ futex while we have the cond_lock. */
+ && lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, 0,
+ &mut->__data.__lock,
+ cond->__data.__futex, pshared) == 0)
+ {
+ lll_unlock (cond->__data.__lock, pshared);
+ return 0;
+ }
+ else
+#endif
+ /* Wake one. */
+ if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex,
+ 1, 1,
+ &cond->__data.__lock,
+ pshared), 0))
+ return 0;
+
+ /* Fallback if neither of them work. */
lll_futex_wake (&cond->__data.__futex, 1, pshared);
}