summaryrefslogtreecommitdiffstats
path: root/libpthread/nptl/sysdeps/pthread/pthread_cond_broadcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread/nptl/sysdeps/pthread/pthread_cond_broadcast.c')
-rw-r--r--libpthread/nptl/sysdeps/pthread/pthread_cond_broadcast.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/libpthread/nptl/sysdeps/pthread/pthread_cond_broadcast.c b/libpthread/nptl/sysdeps/pthread/pthread_cond_broadcast.c
index f6e83ed3f..5e7465774 100644
--- a/libpthread/nptl/sysdeps/pthread/pthread_cond_broadcast.c
+++ b/libpthread/nptl/sysdeps/pthread/pthread_cond_broadcast.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
@@ -23,14 +23,18 @@
#include <lowlevellock.h>
#include <pthread.h>
#include <pthreadP.h>
+
#include <bits/kernel-features.h>
int
-__pthread_cond_broadcast (pthread_cond_t *cond)
+__pthread_cond_broadcast (
+ pthread_cond_t *cond)
{
+ int pshared = (cond->__data.__mutex == (void *) ~0l)
+ ? LLL_SHARED : LLL_PRIVATE;
/* Make sure we are alone. */
- lll_mutex_lock (cond->__data.__lock);
+ lll_lock (cond->__data.__lock, pshared);
/* Are there any waiters to be woken? */
if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
@@ -44,7 +48,7 @@ __pthread_cond_broadcast (pthread_cond_t *cond)
++cond->__data.__broadcast_seq;
/* We are done. */
- lll_mutex_unlock (cond->__data.__lock);
+ lll_unlock (cond->__data.__lock, pshared);
/* Do not use requeue for pshared condvars. */
if (cond->__data.__mutex == (void *) ~0l)
@@ -52,15 +56,24 @@ __pthread_cond_broadcast (pthread_cond_t *cond)
/* 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))
+ 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), 0))
+ futex_val, LLL_PRIVATE), 0))
{
/* The requeue functionality is not available. */
wake_all:
- lll_futex_wake (&cond->__data.__futex, INT_MAX);
+ lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared);
}
/* That's all. */
@@ -68,8 +81,9 @@ __pthread_cond_broadcast (pthread_cond_t *cond)
}
/* We are done. */
- lll_mutex_unlock (cond->__data.__lock);
+ lll_unlock (cond->__data.__lock, pshared);
return 0;
}
+
weak_alias(__pthread_cond_broadcast, pthread_cond_broadcast)