This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix pthread_barrier_wait on !i?86 !x86_64


Hi!

The lock cannot be reacquired, otherwise it can deadlock
(if the PTHREAD_BARRIER_SERIAL_THREAD thread returns without
unlocking and the other try to reacquire the lock).
i486+ and x86_64 assembly is already doing this, which is why it
works.

2004-02-20  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/pthread/pthread_barrier_wait.c (pthread_barrier_wait):
	Release lock before the loop, don't reacquire it.
	* DESIGN-barrier.txt: Likewise.

--- libc/nptl/sysdeps/pthread/pthread_barrier_wait.c.jj	2004-02-20 16:36:30.000000000 +0100
+++ libc/nptl/sysdeps/pthread/pthread_barrier_wait.c	2004-02-20 19:12:29.731215880 +0100
@@ -55,17 +55,13 @@ pthread_barrier_wait (barrier)
       /* The number of the event we are waiting for.  The barrier's event
 	 number must be bumped before we continue.  */
       unsigned int event = ibarrier->curr_event;
-      do
-	{
-	  /* Before suspending, make the barrier available to others.  */
-	  lll_unlock (ibarrier->lock);
 
-	  /* Wait for the event counter of the barrier to change.  */
-	  lll_futex_wait (&ibarrier->curr_event, event);
+      /* Before suspending, make the barrier available to others.  */
+      lll_unlock (ibarrier->lock);
 
-	  /* We are going to access shared data.  */
-	  lll_lock (ibarrier->lock);
-	}
+      /* Wait for the event counter of the barrier to change.  */
+      do
+	lll_futex_wait (&ibarrier->curr_event, event);
       while (event == ibarrier->curr_event);
     }
 
--- nptl/DESIGN-barrier.txt.jj	2004-02-19 17:50:39.000000000 +0100
+++ nptl/DESIGN-barrier.txt	2004-02-20 19:06:05.957558344 +0100
@@ -31,12 +31,9 @@ pthread_barrier_wait(barrier_t *barrier)
     result = BARRIER_SERIAL_THREAD;
   } else {
     event = barrier->curr_event;
+    lll_unlock(barrier->lock);
     do {
-      lll_unlock(barrier->lock);
-
       futex_wait(&barrier->curr_event, event)
-
-      lll_lock(barrier->lock);
     } while (event == barrier->curr_event);
   }
 

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]