1 #include <dispatch/dispatch.h>
7 #define LAPS (1024 * 1024)
10 static pthread_rwlock_t pthr_rwlock
= PTHREAD_RWLOCK_INITIALIZER
;
11 static semaphore_t wake_port
;
12 static void (*test_func
)(void *);
13 static unsigned int thr_count
;
16 reader(void *ctxt
__attribute__((unused
)))
21 pthr_worker(void *ctxt
__attribute__((unused
)))
26 for (i
= 0; i
< (LAPS
/ THREADS
); i
++) {
27 r
= pthread_rwlock_rdlock(&pthr_rwlock
);
29 r
= pthread_rwlock_unlock(&pthr_rwlock
);
35 gcd_worker(void *ctxt
)
37 dispatch_queue_t dq
= ctxt
;
40 for (i
= 0; i
< (LAPS
/ THREADS
); i
++) {
41 dispatch_read_sync_f(dq
, NULL
, reader
);
50 __sync_add_and_fetch(&thr_count
, 1);
52 kr
= semaphore_wait(wake_port
);
57 if (__sync_sub_and_fetch(&thr_count
, 1) == 0) {
58 kr
= semaphore_signal(wake_port
);
68 pthread_t pthr
[THREADS
];
74 for (i
= 0; i
< THREADS
; i
++) {
75 r
= pthread_create(&pthr
[i
], NULL
, worker
, ctxt
);
79 while (thr_count
!= THREADS
) {
85 cycles
= dispatch_benchmark(1, ^{
88 kr
= semaphore_signal_all(wake_port
);
90 kr
= semaphore_wait(wake_port
);
94 for (i
= 0; i
< THREADS
; i
++) {
95 r
= pthread_join(pthr
[i
], &rval
);
105 uint64_t pthr_cycles
, gcd_cycles
;
111 dq
= dispatch_queue_create("test", NULL
);
114 // pthreads lazily inits the object
115 // do not benchmark that fact
116 r
= pthread_rwlock_rdlock(&pthr_rwlock
);
118 r
= pthread_rwlock_unlock(&pthr_rwlock
);
121 kr
= semaphore_create(mach_task_self(), &wake_port
, SYNC_POLICY_FIFO
, 0);
124 test_func
= pthr_worker
;
125 pthr_cycles
= benchmark(NULL
);
127 test_func
= gcd_worker
;
128 gcd_cycles
= benchmark(dq
);
130 dispatch_release(dq
);
135 printf("Cycles:\n\tPOSIX\t%llu\n", pthr_cycles
);
136 printf("\tGCD\t%llu\n", gcd_cycles
);
137 printf("Ratio:\t%Lf\n", ratio
);