• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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