diff options
author | Ulrich Drepper <drepper@redhat.com> | 2004-02-19 04:10:16 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2004-02-19 04:10:16 +0000 |
commit | 37c054c7c4a969816d2bc3c8284bdcadf68ebeec (patch) | |
tree | ec0a8cc53830ddb66445be30615fd15b894495fa /nptl/DESIGN-barrier.txt | |
parent | dc39124662b25ce2db28454f1749d67550e4de31 (diff) | |
download | glibc-37c054c7c4a969816d2bc3c8284bdcadf68ebeec.tar.gz glibc-37c054c7c4a969816d2bc3c8284bdcadf68ebeec.tar.xz glibc-37c054c7c4a969816d2bc3c8284bdcadf68ebeec.zip |
Update.
* sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S (pthread_barrier_wait): After wakeup, release lock only when the last thread stopped using the barrier object. * sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S (pthread_barrier_wait): Likewise. * sysdeps/pthread/pthread_barrier_wait.c (pthread_barrier_wait): Likewise. * Makefile (tests): Add tst-barrier4. * tst-barrier4.c: New file.
Diffstat (limited to 'nptl/DESIGN-barrier.txt')
-rw-r--r-- | nptl/DESIGN-barrier.txt | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/nptl/DESIGN-barrier.txt b/nptl/DESIGN-barrier.txt index 782377f0c5..754e4712e1 100644 --- a/nptl/DESIGN-barrier.txt +++ b/nptl/DESIGN-barrier.txt @@ -1,7 +1,7 @@ Barriers pseudocode =================== - int pthread_barrier_wait(barrier_t * barrier); + int pthread_barrier_wait(barrier_t *barrier); struct barrier_t { @@ -21,29 +21,27 @@ struct barrier_t { pthread_barrier_wait(barrier_t *barrier) { unsigned int event; + result = 0; lll_lock(barrier->lock); if (!--barrier->left) { - barrier->left = barrier->init_count; barrier->curr_event++; futex_wake(&barrier->curr_event, INT_MAX) - lll_unlock(barrier->lock); - - return BARRIER_SERIAL_THREAD; - } - event = barrier->curr_event; - for (;;) { - lll_unlock(barrier->lock); + result = BARRIER_SERIAL_THREAD; + } else { + event = barrier->curr_event; + do { + lll_unlock(barrier->lock); - futex_wait(&barrier->curr_event, event) + futex_wait(&barrier->curr_event, event) - lll_lock(barrier->lock); - if (event != barrier->curr_event) - break; + lll_lock(barrier->lock); + } while (event == barrier->curr_event); } - lll_unlock(barrier->lock); - return 0; -} + if (atomic_exchange_and_add (barrier->left, 1) == barrier->init_count - 1) + lll_unlock(barrier->lock); + return result; +} |