1 #include "iwth.h"
2 #include <errno.h>
3
4 #ifdef __APPLE__
5
6 #ifndef __unused
7 #define __unused __attribute__((unused))
8 #endif
9
10 int
pthread_barrierattr_init(pthread_barrierattr_t * attr __unused)11 pthread_barrierattr_init(pthread_barrierattr_t *attr __unused) {
12 return 0;
13 }
14
15 int
pthread_barrierattr_destroy(pthread_barrierattr_t * attr __unused)16 pthread_barrierattr_destroy(pthread_barrierattr_t *attr __unused) {
17 return 0;
18 }
19
20 int
pthread_barrierattr_getpshared(const pthread_barrierattr_t * restrict attr __unused,int * restrict pshared)21 pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr __unused,
22 int *restrict pshared) {
23 *pshared = PTHREAD_PROCESS_PRIVATE;
24 return 0;
25 }
26
27 int
pthread_barrierattr_setpshared(pthread_barrierattr_t * attr __unused,int pshared)28 pthread_barrierattr_setpshared(pthread_barrierattr_t *attr __unused,
29 int pshared) {
30 if (pshared != PTHREAD_PROCESS_PRIVATE) {
31 errno = EINVAL;
32 return -1;
33 }
34 return 0;
35 }
36
37 int
pthread_barrier_init(pthread_barrier_t * restrict barrier,const pthread_barrierattr_t * restrict attr __unused,unsigned count)38 pthread_barrier_init(pthread_barrier_t *restrict barrier,
39 const pthread_barrierattr_t *restrict attr __unused,
40 unsigned count) {
41 if (count == 0) {
42 errno = EINVAL;
43 return -1;
44 }
45
46 if (pthread_mutex_init(&barrier->mutex, 0) < 0) {
47 return -1;
48 }
49 if (pthread_cond_init(&barrier->cond, 0) < 0) {
50 int errno_save = errno;
51 pthread_mutex_destroy(&barrier->mutex);
52 errno = errno_save;
53 return -1;
54 }
55
56 barrier->limit = count;
57 barrier->count = 0;
58 barrier->phase = 0;
59
60 return 0;
61 }
62
63 int
pthread_barrier_destroy(pthread_barrier_t * barrier)64 pthread_barrier_destroy(pthread_barrier_t *barrier) {
65 pthread_mutex_destroy(&barrier->mutex);
66 pthread_cond_destroy(&barrier->cond);
67 return 0;
68 }
69
70 int
pthread_barrier_wait(pthread_barrier_t * barrier)71 pthread_barrier_wait(pthread_barrier_t *barrier) {
72 pthread_mutex_lock(&barrier->mutex);
73 barrier->count++;
74 if (barrier->count >= barrier->limit) {
75 barrier->phase++;
76 barrier->count = 0;
77 pthread_cond_broadcast(&barrier->cond);
78 pthread_mutex_unlock(&barrier->mutex);
79 return PTHREAD_BARRIER_SERIAL_THREAD;
80 } else {
81 unsigned phase = barrier->phase;
82 do
83 pthread_cond_wait(&barrier->cond, &barrier->mutex);
84 while (phase == barrier->phase);
85 pthread_mutex_unlock(&barrier->mutex);
86 return 0;
87 }
88 }
89
90 #endif /* __APPLE__ */
91
92