diff options
Diffstat (limited to 'libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c')
-rw-r--r-- | libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c | 29 |
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) |