about summary refs log tree commit diff
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.tar.gz
glibc-8313cb997d2da2465c8560d3164358a68ea1e9ad.tar.xz
glibc-8313cb997d2da2465c8560d3164358a68ea1e9ad.zip
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 908a2acfaf..102d0b380c 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);
     }