diff options
author | David 'Digit' Turner <digit@google.com> | 2010-03-19 17:59:23 -0700 |
---|---|---|
committer | David 'Digit' Turner <digit@google.com> | 2010-03-22 17:31:50 -0700 |
commit | b5e4a416060aa7f0a1e2a9ad5b8e318d59986852 (patch) | |
tree | 39115a2ef1c6c4084763687a312a67a52c9597c1 | |
parent | 377d4c979dee3dcb5929e8f7a68a53c2407259ab (diff) | |
download | bionic-b5e4a416060aa7f0a1e2a9ad5b8e318d59986852.zip bionic-b5e4a416060aa7f0a1e2a9ad5b8e318d59986852.tar.gz bionic-b5e4a416060aa7f0a1e2a9ad5b8e318d59986852.tar.bz2 |
pthread: Use private futexes by default in condition variables
Now that the system properly uses shared condvars when needed, we
can enable the use of private futexes for them too.
Change-Id: Icf8351fc0a2309f764cba45c65bc3af047720cdf
-rw-r--r-- | libc/bionic/pthread.c | 43 | ||||
-rw-r--r-- | libc/docs/CHANGES.TXT | 11 |
2 files changed, 27 insertions, 27 deletions
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c index 6a2329f..f93a241 100644 --- a/libc/bionic/pthread.c +++ b/libc/bionic/pthread.c @@ -1361,9 +1361,11 @@ int pthread_condattr_destroy(pthread_condattr_t *attr) /* We use one bit in condition variable values as the 'shared' flag * The rest is a counter. */ -#define COND_SHARING_MASK 0x0001 +#define COND_SHARED_MASK 0x0001 #define COND_COUNTER_INCREMENT 0x0002 -#define COND_COUNTER_MASK (~COND_SHARING_MASK) +#define COND_COUNTER_MASK (~COND_SHARED_MASK) + +#define COND_IS_SHARED(c) (((c)->value & COND_SHARED_MASK) != 0) /* XXX *technically* there is a race condition that could allow * XXX a signal to be missed. If thread A is preempted in _wait() @@ -1382,7 +1384,7 @@ int pthread_cond_init(pthread_cond_t *cond, cond->value = 0; if (attr != NULL && *attr == PTHREAD_PROCESS_SHARED) - cond->value |= COND_SHARING_MASK; + cond->value |= COND_SHARED_MASK; return 0; } @@ -1397,13 +1399,19 @@ int pthread_cond_destroy(pthread_cond_t *cond) } /* This function is used by pthread_cond_broadcast and - * pthread_cond_signal to atomically decrement the counter. + * pthread_cond_signal to atomically decrement the counter + * then wake-up 'counter' threads. */ -static void -__pthread_cond_pulse(pthread_cond_t *cond) +static int +__pthread_cond_pulse(pthread_cond_t *cond, int counter) { - long flags = (cond->value & ~COND_COUNTER_MASK); + long flags; + int wake_op; + + if (__unlikely(cond == NULL)) + return EINVAL; + flags = (cond->value & ~COND_COUNTER_MASK); for (;;) { long oldval = cond->value; long newval = ((oldval - COND_COUNTER_INCREMENT) & COND_COUNTER_MASK) @@ -1411,26 +1419,20 @@ __pthread_cond_pulse(pthread_cond_t *cond) if (__atomic_cmpxchg(oldval, newval, &cond->value) == 0) break; } + + wake_op = COND_IS_SHARED(cond) ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE; + __futex_syscall3(&cond->value, wake_op, counter); + return 0; } int pthread_cond_broadcast(pthread_cond_t *cond) { - if (__unlikely(cond == NULL)) - return EINVAL; - - __pthread_cond_pulse(cond); - __futex_wake(&cond->value, INT_MAX); - return 0; + return __pthread_cond_pulse(cond, INT_MAX); } int pthread_cond_signal(pthread_cond_t *cond) { - if (__unlikely(cond == NULL)) - return EINVAL; - - __pthread_cond_pulse(cond); - __futex_wake(&cond->value, 1); - return 0; + return __pthread_cond_pulse(cond, 1); } int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) @@ -1444,9 +1446,10 @@ int __pthread_cond_timedwait_relative(pthread_cond_t *cond, { int status; int oldvalue = cond->value; + int wait_op = COND_IS_SHARED(cond) ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE; pthread_mutex_unlock(mutex); - status = __futex_wait(&cond->value, oldvalue, reltime); + status = __futex_syscall4(&cond->value, wait_op, oldvalue, reltime); pthread_mutex_lock(mutex); if (status == (-ETIMEDOUT)) return ETIMEDOUT; diff --git a/libc/docs/CHANGES.TXT b/libc/docs/CHANGES.TXT index 08b2009..9080685 100644 --- a/libc/docs/CHANGES.TXT +++ b/libc/docs/CHANGES.TXT @@ -83,13 +83,10 @@ Differences between current and Android 2.1: - <pthread.h>: Add pthread_condattr_init/destroy/setpshared/getpshared functions to enable proper shared conditional variable initialization. - Modify the pthread_mutex_t implementation to use private futexes for - performance reasons. Mutexes are no longer shareable between processes - by default anymore, unless you use PTHREAD_PROCESS_SHARED with - pthread_mutexattr_setpshared(). - - XXX: The implementation still always uses shared condvars, independent - of the flags being selected. This will change in a later commit. + Modify the pthread_mutex_t and pthread_cond_t implementation to use private + futexes for performance reasons. Mutexes and Condvars are no longer shareable + between processes by default anymore, unless you use PTHREAD_PROCESS_SHARED + with pthread_mutexattr_setpshared() and/or pthread_condattr_setpshared(). ------------------------------------------------------------------------------- Differences between Android 2.1 and 2.0.1: |