1 #include "pthread_impl.h"
11 int pthread_barrier_wait(pthread_barrier_t *b)
13 int limit = b->_b_limit;
14 struct instance *inst;
16 /* Trivial case: count was set at 1 */
17 if (!limit) return PTHREAD_BARRIER_SERIAL_THREAD;
19 /* Otherwise we need a lock on the barrier object */
20 while (a_swap(&b->_b_lock, 1))
21 __wait(&b->_b_lock, &b->_b_waiters, 1, 0);
24 /* First thread to enter the barrier becomes the "instance owner" */
26 struct instance new_inst = { 0 };
28 b->_b_inst = inst = &new_inst;
29 a_store(&b->_b_lock, 0);
30 if (b->_b_waiters) __wake(&b->_b_lock, 1, 0);
31 while (spins-- && !inst->finished)
33 a_inc(&inst->finished);
34 while (inst->finished == 1)
35 __syscall(SYS_futex, &inst->finished, FUTEX_WAIT,1,0);
36 return PTHREAD_BARRIER_SERIAL_THREAD;
39 /* Last thread to enter the barrier wakes all non-instance-owners */
40 if (++inst->count == limit) {
42 a_store(&b->_b_lock, 0);
43 if (b->_b_waiters) __wake(&b->_b_lock, 1, 0);
44 a_store(&inst->last, 1);
46 __wake(&inst->last, -1, 0);
48 a_store(&b->_b_lock, 0);
49 if (b->_b_waiters) __wake(&b->_b_lock, 1, 0);
50 __wait(&inst->last, &inst->waiters, 0, 0);
53 /* Last thread to exit the barrier wakes the instance owner */
54 if (a_fetch_add(&inst->count,-1)==1 && a_fetch_add(&inst->finished,1))
55 __wake(&inst->finished, 1, 0);