diff options
Diffstat (limited to 'sysdeps/generic')
-rw-r--r-- | sysdeps/generic/pt-barrier-wait.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/sysdeps/generic/pt-barrier-wait.c b/sysdeps/generic/pt-barrier-wait.c index f1de250..42fbdb0 100644 --- a/sysdeps/generic/pt-barrier-wait.c +++ b/sysdeps/generic/pt-barrier-wait.c @@ -33,16 +33,24 @@ pthread_barrier_wait (pthread_barrier_t *barrier) if (barrier->count > 1) { struct __pthread *wakeup; + unsigned n = 0; - wakeup = barrier->queue; - barrier->queue = NULL; - __pthread_spin_unlock (&barrier->lock); + __pthread_queue_iterate (barrier->queue, wakeup) + n ++; - /* We can safely walk the list of waiting threads without - holding the lock since it is decoupled from the barrier - variable now. */ - __pthread_dequeuing_iterate (wakeup, wakeup) - __pthread_wakeup (wakeup); + { + struct __pthread *wakeups[n]; + unsigned i = 0; + + __pthread_dequeuing_iterate (barrier->queue, wakeup) + wakeups[i ++] = wakeup; + + barrier->queue = NULL; + __pthread_spin_unlock (&barrier->lock); + + for (i = 0; i < n; i ++) + __pthread_wakeup (wakeups[i]); + } } return PTHREAD_BARRIER_SERIAL_THREAD; |