mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-20 17:30:24 +01:00
os: Check for spurious wakeups in pipe_barrier_wait.
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.
This commit is contained in:
parent
59fcbc0ac5
commit
31db310be4
1 changed files with 8 additions and 1 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue