about summary refs log tree commit diff
path: root/nptl/DESIGN-barrier.txt
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-02-19 04:10:16 +0000
committerUlrich Drepper <drepper@redhat.com>2004-02-19 04:10:16 +0000
commit37c054c7c4a969816d2bc3c8284bdcadf68ebeec (patch)
treeec0a8cc53830ddb66445be30615fd15b894495fa /nptl/DESIGN-barrier.txt
parentdc39124662b25ce2db28454f1749d67550e4de31 (diff)
downloadglibc-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.txt30
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;
+}