]> git.saurik.com Git - apple/libdispatch.git/blob - testing/dispatch_rdlock_bmark.c
libdispatch-84.5.3.tar.gz
[apple/libdispatch.git] / testing / dispatch_rdlock_bmark.c
1 #include <dispatch/dispatch.h>
2 #include <mach/mach.h>
3 #include <pthread.h>
4 #include <stdio.h>
5 #include <assert.h>
6
7 #define LAPS (1024 * 1024)
8 #define THREADS 1
9
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;
14
15 static void
16 reader(void *ctxt __attribute__((unused)))
17 {
18 }
19
20 static void
21 pthr_worker(void *ctxt __attribute__((unused)))
22 {
23 size_t i;
24 int r;
25
26 for (i = 0; i < (LAPS / THREADS); i++) {
27 r = pthread_rwlock_rdlock(&pthr_rwlock);
28 assert(r == 0);
29 r = pthread_rwlock_unlock(&pthr_rwlock);
30 assert(r == 0);
31 }
32 }
33
34 static void
35 gcd_worker(void *ctxt)
36 {
37 dispatch_queue_t dq = ctxt;
38 size_t i;
39
40 for (i = 0; i < (LAPS / THREADS); i++) {
41 dispatch_read_sync_f(dq, NULL, reader);
42 }
43 }
44
45 static void *
46 worker(void *ctxt)
47 {
48 kern_return_t kr;
49
50 __sync_add_and_fetch(&thr_count, 1);
51
52 kr = semaphore_wait(wake_port);
53 assert(kr == 0);
54
55 test_func(ctxt);
56
57 if (__sync_sub_and_fetch(&thr_count, 1) == 0) {
58 kr = semaphore_signal(wake_port);
59 assert(kr == 0);
60 }
61
62 return NULL;
63 }
64
65 static uint64_t
66 benchmark(void *ctxt)
67 {
68 pthread_t pthr[THREADS];
69 uint64_t cycles;
70 void *rval;
71 size_t i;
72 int r;
73
74 for (i = 0; i < THREADS; i++) {
75 r = pthread_create(&pthr[i], NULL, worker, ctxt);
76 assert(r == 0);
77 }
78
79 while (thr_count != THREADS) {
80 sleep(1);
81 }
82
83 sleep(1);
84
85 cycles = dispatch_benchmark(1, ^{
86 kern_return_t kr;
87
88 kr = semaphore_signal_all(wake_port);
89 assert(kr == 0);
90 kr = semaphore_wait(wake_port);
91 assert(kr == 0);
92 });
93
94 for (i = 0; i < THREADS; i++) {
95 r = pthread_join(pthr[i], &rval);
96 assert(r == 0);
97 }
98
99 return cycles;
100 }
101
102 int
103 main(void)
104 {
105 uint64_t pthr_cycles, gcd_cycles;
106 long double ratio;
107 dispatch_queue_t dq;
108 kern_return_t kr;
109 int r;
110
111 dq = dispatch_queue_create("test", NULL);
112 assert(dq);
113
114 // pthreads lazily inits the object
115 // do not benchmark that fact
116 r = pthread_rwlock_rdlock(&pthr_rwlock);
117 assert(r == 0);
118 r = pthread_rwlock_unlock(&pthr_rwlock);
119 assert(r == 0);
120
121 kr = semaphore_create(mach_task_self(), &wake_port, SYNC_POLICY_FIFO, 0);
122 assert(kr == 0);
123
124 test_func = pthr_worker;
125 pthr_cycles = benchmark(NULL);
126
127 test_func = gcd_worker;
128 gcd_cycles = benchmark(dq);
129
130 dispatch_release(dq);
131
132 ratio = pthr_cycles;
133 ratio /= gcd_cycles;
134
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);
138
139 return 0;
140 }