Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libpthread Make pthread_barrier_wait() handle spurious w...



details:   https://anonhg.NetBSD.org/src/rev/88b369dd47bb
branches:  trunk
changeset: 542270:88b369dd47bb
user:      nathanw <nathanw%NetBSD.org@localhost>
date:      Sat Jan 25 00:47:05 2003 +0000

description:
Make pthread_barrier_wait() handle spurious wakeups from pthread__block()
by adding a generation number to the barrier structure and incrementing it
when the barrier fires.

XXX this is an ABI change for anything using barriers, but the library is
new enough and nothing in the tree uses barriers so I'm going to let it
slide. Using the private data pointer for a field that will always be present
would be excessive.

diffstat:

 lib/libpthread/pthread_barrier.c |  41 ++++++++++++++++++++++++---------------
 lib/libpthread/pthread_types.h   |   3 +-
 2 files changed, 27 insertions(+), 17 deletions(-)

diffs (104 lines):

diff -r 0e5de0f53e2e -r 88b369dd47bb lib/libpthread/pthread_barrier.c
--- a/lib/libpthread/pthread_barrier.c  Sat Jan 25 00:43:38 2003 +0000
+++ b/lib/libpthread/pthread_barrier.c  Sat Jan 25 00:47:05 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread_barrier.c,v 1.2 2003/01/18 10:34:15 thorpej Exp $      */
+/*     $NetBSD: pthread_barrier.c,v 1.3 2003/01/25 00:47:06 nathanw Exp $      */
 
 /*-
  * Copyright (c) 2001, 2003 The NetBSD Foundation, Inc.
@@ -87,6 +87,7 @@
 
                barrier->ptb_initcount = count;
                barrier->ptb_curcount = 0;
+               barrier->ptb_generation = 0;
 
                pthread_spinunlock(self, &barrier->ptb_lock);
 
@@ -98,6 +99,7 @@
        PTQ_INIT(&barrier->ptb_waiters);
        barrier->ptb_initcount = count;
        barrier->ptb_curcount = 0;
+       barrier->ptb_generation = 0;
 
        return 0;
 }
@@ -139,6 +141,7 @@
 pthread_barrier_wait(pthread_barrier_t *barrier)
 {
        pthread_t self;
+       unsigned int gen;
 
 #ifdef ERRORCHECK
        if ((barrier == NULL) || (barrier->ptb_magic != _PT_BARRIER_MAGIC))
@@ -168,6 +171,7 @@
                blockedq = barrier->ptb_waiters;
                PTQ_INIT(&barrier->ptb_waiters);
                barrier->ptb_curcount = 0;
+               barrier->ptb_generation++;
 
                PTQ_FOREACH(signaled, &blockedq, pt_sleep)
                        pthread__sched(self, signaled);
@@ -177,25 +181,30 @@
                return PTHREAD_BARRIER_SERIAL_THREAD;
        }
 
-       SDPRINTF(("(barrier wait %p) Waiting on %p\n", self, barrier));
-
-       pthread_spinlock(self, &self->pt_statelock);
+       barrier->ptb_curcount++;
+       gen = barrier->ptb_generation;
+       while (gen == barrier->ptb_generation) {
+               SDPRINTF(("(barrier wait %p) Waiting on %p\n",
+                   self, barrier));
 
-       self->pt_state = PT_STATE_BLOCKED_QUEUE;
-       self->pt_sleepobj = barrier;
-       self->pt_sleepq = &barrier->ptb_waiters;
-       self->pt_sleeplock = &barrier->ptb_lock;
+               pthread_spinlock(self, &self->pt_statelock);
 
-       pthread_spinunlock(self, &self->pt_statelock);
-
-       PTQ_INSERT_TAIL(&barrier->ptb_waiters, self, pt_sleep);
-       barrier->ptb_curcount++;
+               self->pt_state = PT_STATE_BLOCKED_QUEUE;
+               self->pt_sleepobj = barrier;
+               self->pt_sleepq = &barrier->ptb_waiters;
+               self->pt_sleeplock = &barrier->ptb_lock;
+               
+               pthread_spinunlock(self, &self->pt_statelock);
 
-       pthread__block(self, &barrier->ptb_lock);
-       /* Spinlock is unlocked on return */
+               PTQ_INSERT_TAIL(&barrier->ptb_waiters, self, pt_sleep);
 
-       SDPRINTF(("(barrier wait %p) Woke up on %p\n",
-           self, barrier));
+               pthread__block(self, &barrier->ptb_lock);
+               SDPRINTF(("(barrier wait %p) Woke up on %p\n",
+                   self, barrier));
+               /* Spinlock is unlocked on return */
+               pthread_spinlock(self, &barrier->ptb_lock);
+       }
+       pthread_spinunlock(self, &barrier->ptb_lock);
 
        return 0;
 }
diff -r 0e5de0f53e2e -r 88b369dd47bb lib/libpthread/pthread_types.h
--- a/lib/libpthread/pthread_types.h    Sat Jan 25 00:43:38 2003 +0000
+++ b/lib/libpthread/pthread_types.h    Sat Jan 25 00:47:05 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread_types.h,v 1.2 2003/01/18 10:34:17 thorpej Exp $        */
+/*     $NetBSD: pthread_types.h,v 1.3 2003/01/25 00:47:05 nathanw Exp $        */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -224,6 +224,7 @@
        struct pthread_queue_t  ptb_waiters;
        unsigned int    ptb_initcount;
        unsigned int    ptb_curcount;
+       unsigned int    ptb_generation;
 
        void            *ptb_private;
 };



Home | Main Index | Thread Index | Old Index