summaryrefslogtreecommitdiff
path: root/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c')
-rw-r--r--libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
index 1f4136e70..4aaf5df75 100644
--- a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
+++ b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
@@ -23,6 +23,7 @@
#include <lowlevellock.h>
#include <pthread.h>
#include <pthreadP.h>
+#include <bits/kernel-features.h>
/* Cleanup handler, defined in pthread_cond_wait.c. */
@@ -51,21 +52,24 @@ __pthread_cond_timedwait (
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
return EINVAL;
+ int pshared = (cond->__data.__mutex == (void *) ~0l)
+ ? LLL_SHARED : LLL_PRIVATE;
+
/* Make sure we are along. */
- lll_mutex_lock (cond->__data.__lock);
+ lll_lock (cond->__data.__lock, pshared);
/* Now we can release the mutex. */
int err = __pthread_mutex_unlock_usercnt (mutex, 0);
if (err)
{
- lll_mutex_unlock (cond->__data.__lock);
+ lll_unlock (cond->__data.__lock, pshared);
return err;
}
/* We have one new user of the condvar. */
++cond->__data.__total_seq;
++cond->__data.__futex;
- cond->__data.__nwaiters += 1 << COND_CLOCK_BITS;
+ cond->__data.__nwaiters += 1 << COND_NWAITERS_SHIFT;
/* Remember the mutex we are using here. If there is already a
different address store this is a bad user bug. Do not store
@@ -98,7 +102,7 @@ __pthread_cond_timedwait (
int ret;
ret = INTERNAL_SYSCALL (clock_gettime, err, 2,
(cond->__data.__nwaiters
- & ((1 << COND_CLOCK_BITS) - 1)),
+ & ((1 << COND_NWAITERS_SHIFT) - 1)),
&rt);
# ifndef __ASSUME_POSIX_TIMERS
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (ret, err), 0))
@@ -144,20 +148,20 @@ __pthread_cond_timedwait (
unsigned int futex_val = cond->__data.__futex;
/* Prepare to wait. Release the condvar futex. */
- lll_mutex_unlock (cond->__data.__lock);
+ lll_unlock (cond->__data.__lock, pshared);
/* Enable asynchronous cancellation. Required by the standard. */
cbuffer.oldtype = __pthread_enable_asynccancel ();
/* Wait until woken by signal or broadcast. */
err = lll_futex_timed_wait (&cond->__data.__futex,
- futex_val, &rt);
+ futex_val, &rt, pshared);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (cbuffer.oldtype);
/* We are going to look at shared data again, so get the lock. */
- lll_mutex_lock(cond->__data.__lock);
+ lll_lock (cond->__data.__lock, pshared);
/* If a broadcast happened, we are done. */
if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
@@ -187,17 +191,17 @@ __pthread_cond_timedwait (
bc_out:
- cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;
+ cond->__data.__nwaiters -= 1 << COND_NWAITERS_SHIFT;
/* If pthread_cond_destroy was called on this variable already,
notify the pthread_cond_destroy caller all waiters have left
and it can be successfully destroyed. */
if (cond->__data.__total_seq == -1ULL
- && cond->__data.__nwaiters < (1 << COND_CLOCK_BITS))
- lll_futex_wake (&cond->__data.__nwaiters, 1);
+ && cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
+ lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
/* We are done with the condvar. */
- lll_mutex_unlock (cond->__data.__lock);
+ lll_unlock (cond->__data.__lock, pshared);
/* The cancellation handling is back to normal, remove the handler. */
__pthread_cleanup_pop (&buffer, 0);
@@ -207,4 +211,5 @@ __pthread_cond_timedwait (
return err ?: result;
}
+
weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait)