about summary refs log tree commit diff
path: root/nptl/pthread_cond_broadcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/pthread_cond_broadcast.c')
-rw-r--r--nptl/pthread_cond_broadcast.c45
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.  */