Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gteissier
GitHub Repository: gteissier/erl-matter
Path: blob/master/barrier.c
271 views
1
// MacOS pthread does not include barrier functions
2
// taken from https://yyshen.github.io/2015/01/18/pthread_barrier_osx.html
3
4
#define PTHREAD_BARRIER_SERIAL_THREAD 1
5
6
typedef struct pthread_barrier {
7
pthread_mutex_t mutex;
8
pthread_cond_t cond;
9
volatile uint32_t flag;
10
size_t count;
11
size_t num;
12
} pthread_barrier_t;
13
14
int pthread_barrier_init(pthread_barrier_t *bar, int attr, int num)
15
{
16
int ret = 0;
17
if ((ret = pthread_mutex_init(&(bar->mutex), 0))) return ret;
18
if ((ret = pthread_cond_init(&(bar->cond), 0))) return ret;
19
bar->flag = 0;
20
bar->count = 0;
21
bar->num = num;
22
return 0;
23
}
24
25
int pthread_barrier_wait(pthread_barrier_t *bar)
26
{
27
int ret = 0;
28
uint32_t flag = 0;
29
30
if ((ret = pthread_mutex_lock(&(bar->mutex)))) return ret;
31
32
flag = bar->flag;
33
bar->count++;
34
35
if (bar->count == bar->num) {
36
bar->count = 0;
37
bar->flag = 1 - bar->flag;
38
if ((ret = pthread_cond_broadcast(&(bar->cond)))) return ret;
39
if ((ret = pthread_mutex_unlock(&(bar->mutex)))) return ret;
40
return PTHREAD_BARRIER_SERIAL_THREAD;
41
}
42
43
while (1) {
44
if (bar->flag == flag) {
45
ret = pthread_cond_wait(&(bar->cond), &(bar->mutex));
46
if (ret) return ret;
47
} else { break; }
48
}
49
50
if ((ret = pthread_mutex_unlock(&(bar->mutex)))) return ret;
51
return 0;
52
}
53
54