The POSIX function pthread_cond_wait can have spurious wakeups when
waiting on a condition variable.
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.
typedef struct {
unsigned count;
unsigned waiters;
+ uint64_t sequence;
pipe_mutex mutex;
pipe_condvar condvar;
} pipe_barrier;
{
barrier->count = count;
barrier->waiters = 0;
+ barrier->sequence = 0;
pipe_mutex_init(barrier->mutex);
pipe_condvar_init(barrier->condvar);
}
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);
}