-/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2003-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <endian.h>
#include <errno.h>
#include <lowlevellock.h>
#include <pthread.h>
#include <pthreadP.h>
+#include <stap-probe.h>
#include <shlib-compat.h>
#include <kernel-features.h>
int
-__pthread_cond_broadcast (cond)
- pthread_cond_t *cond;
+__pthread_cond_broadcast (pthread_cond_t *cond)
{
+ LIBC_PROBE (cond_broadcast, 1, 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)
++cond->__data.__broadcast_seq;
/* We are done. */
- lll_mutex_unlock (cond->__data.__lock);
-
- /* Do not use requeue for pshared condvars. */
- if (cond->__data.__mutex == (void *) ~0l)
- goto wake_all;
+ lll_unlock (cond->__data.__lock, pshared);
/* Wake everybody. */
pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
- /* XXX: Kernel so far doesn't support requeue to PI futex. */
- if (__builtin_expect (mut->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP,
- 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), 0))
+#if (defined lll_futex_cmp_requeue_pi \
+ && defined __ASSUME_REQUEUE_PI)
+ if (USE_REQUEUE_PI (mut))
{
- /* The requeue functionality is not available. */
- wake_all:
- lll_futex_wake (&cond->__data.__futex, INT_MAX,
- // XYZ check mutex flag
- LLL_SHARED);
+ 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. */
+ 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);
return 0;
}
/* We are done. */
- lll_mutex_unlock (cond->__data.__lock);
+ lll_unlock (cond->__data.__lock, pshared);
return 0;
}