[Mesa-dev] [PATCH] os: Check for spurious wakeups in pipe_barrier_wait.

Vinson Lee vlee at vmware.com
Tue Apr 20 01:22:36 PDT 2010


I would like this to be reviewed before it is committed.

The current implementation and this patch doesn't address the potential 
existing case where count is erroneously initialized with zero.
That can be a separate patch.


os: Check for spurious wakeups in pipe_barrier_wait.

Add a 64-bit counter that is incremented whenever the barrier becomes full. A woken thread
checks the counter. If the counter has not changed then it has been
spuriously woken and goes back to sleep. If the counter has changed then it was properly
signaled and exits the barrier.

Tested on Mac OS X.

This patch was based on ideas from Luca Barbieri.

diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h
index 07a4268..c09e8a7 100644
--- a/src/gallium/auxiliary/os/os_thread.h
+++ b/src/gallium/auxiliary/os/os_thread.h
@@ -302,6 +302,7 @@ static INLINE void pipe_barrier_wait(pipe_barrier *barrier)
 typedef struct {
    unsigned count;
    unsigned waiters;
+   uint64_t sequence;
    pipe_mutex mutex;
    pipe_condvar condvar;
 } pipe_barrier;
@@ -310,6 +311,7 @@ static INLINE void pipe_barrier_init(pipe_barrier *barrier, unsigned count)
 {
    barrier->count = count;
    barrier->waiters = 0;
+   barrier->sequence = 0;
    pipe_mutex_init(barrier->mutex);
    pipe_condvar_init(barrier->condvar);
 }
@@ -329,9 +331,14 @@ static INLINE void pipe_barrier_wait(pipe_barrier *barrier)
    barrier->waiters++;
 
    if (barrier->waiters < barrier->count) {
-      pipe_condvar_wait(barrier->condvar, barrier->mutex);
+      uint64_t sequence = barrier->sequence;
+
+      do {
+         pipe_condvar_wait(barrier->condvar, barrier->mutex);
+      } while (sequence == barrier->sequence);
    } else {
       barrier->waiters = 0;
+      barrier->sequence++;
       pipe_condvar_broadcast(barrier->condvar);
    }


More information about the mesa-dev mailing list