remove some stray trailing space characters
[musl] / src / thread / pthread_barrier_wait.c
1 #include "pthread_impl.h"
2
3 struct instance
4 {
5         int count;
6         int last;
7         int waiters;
8         int finished;
9 };
10
11 int pthread_barrier_wait(pthread_barrier_t *b)
12 {
13         int limit = b->_b_limit;
14         struct instance *inst;
15
16         /* Trivial case: count was set at 1 */
17         if (!limit) return PTHREAD_BARRIER_SERIAL_THREAD;
18
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);
22         inst = b->_b_inst;
23
24         /* First thread to enter the barrier becomes the "instance owner" */
25         if (!inst) {
26                 struct instance new_inst = { 0 };
27                 int spins = 10000;
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)
32                         a_spin();
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;
37         }
38
39         /* Last thread to enter the barrier wakes all non-instance-owners */
40         if (++inst->count == limit) {
41                 b->_b_inst = 0;
42                 a_store(&b->_b_lock, 0);
43                 if (b->_b_waiters) __wake(&b->_b_lock, 1, 0);
44                 a_store(&inst->last, 1);
45                 if (inst->waiters)
46                         __wake(&inst->last, -1, 0);
47         } else {
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);
51         }
52
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);
56
57         return 0;
58 }