11 pthread_barrier_t glow_clock_barrier
;
13 void bench(); // defined by user
14 void start_thread_group(int nth
, void(*f
)(int tid
));
15 void grow_clock_worker(int tid
);
17 int main(int argc
, char **argv
) {
20 bench_nthread
= atoi(argv
[1]);
23 bench_niter
= atoi(argv
[2]);
25 // Grow thread's clock.
29 pthread_barrier_init(&glow_clock_barrier
, 0, clock_size
);
30 start_thread_group(clock_size
, grow_clock_worker
);
31 pthread_barrier_destroy(&glow_clock_barrier
);
32 __atomic_load_n(&grow_clock_var
, __ATOMIC_ACQUIRE
);
35 clock_gettime(CLOCK_MONOTONIC
, &tp0
);
38 clock_gettime(CLOCK_MONOTONIC
, &tp1
);
39 unsigned long long t
=
40 (tp1
.tv_sec
* 1000000000ULL + tp1
.tv_nsec
) -
41 (tp0
.tv_sec
* 1000000000ULL + tp0
.tv_nsec
);
42 fprintf(stderr
, "%llu ns/iter\n", t
/ bench_niter
);
43 fprintf(stderr
, "DONE\n");
46 void start_thread_group(int nth
, void(*f
)(int tid
)) {
47 pthread_t
*th
= (pthread_t
*)malloc(nth
* sizeof(pthread_t
));
48 for (int i
= 0; i
< nth
; i
++)
49 pthread_create(&th
[i
], 0, (void*(*)(void*))f
, (void*)(long)i
);
50 for (int i
= 0; i
< nth
; i
++)
51 pthread_join(th
[i
], 0);
54 void grow_clock_worker(int tid
) {
55 int res
= pthread_barrier_wait(&glow_clock_barrier
);
56 if (res
== PTHREAD_BARRIER_SERIAL_THREAD
)
57 __atomic_store_n(&grow_clock_var
, 0, __ATOMIC_RELEASE
);