]> git.saurik.com Git - apple/libdispatch.git/blob - testing/dispatch_priority.c
libdispatch-84.5.5.tar.gz
[apple/libdispatch.git] / testing / dispatch_priority.c
1 #include <stdio.h>
2 #include <dispatch/dispatch.h>
3 #include <dispatch/queue_private.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <assert.h>
7 #include <TargetConditionals.h>
8
9 #include "dispatch_test.h"
10
11 int done = 0;
12
13 #define BLOCKS 128
14 #define PRIORITIES 3
15
16 #if TARGET_OS_EMBEDDED
17 #define LOOP_COUNT 2000000
18 #else
19 #define LOOP_COUNT 100000000
20 #endif
21
22 char *labels[PRIORITIES] = { "LOW", "DEFAULT", "HIGH" };
23 int priorities[PRIORITIES] = { DISPATCH_QUEUE_PRIORITY_LOW, DISPATCH_QUEUE_PRIORITY_DEFAULT, DISPATCH_QUEUE_PRIORITY_HIGH };
24
25 union {
26 size_t count;
27 char padding[64];
28 } counts[PRIORITIES];
29
30 #define ITERATIONS (size_t)(PRIORITIES * BLOCKS * 0.50)
31 size_t iterations = ITERATIONS;
32
33 void
34 histogram(void) {
35 size_t maxcount = BLOCKS;
36 size_t sc[PRIORITIES];
37
38 size_t total = 0;
39
40 size_t x,y;
41 for (y = 0; y < PRIORITIES; ++y) {
42 sc[y] = counts[y].count;
43 }
44
45 for (y = 0; y < PRIORITIES; ++y) {
46 printf("%s: %ld\n", labels[y], sc[y]);
47 total += sc[y];
48
49 double fraction = (double)sc[y] / (double)maxcount;
50 double value = fraction * (double)80;
51 for (x = 0; x < 80; ++x) {
52 printf("%s", (value > x) ? "*" : " ");
53 }
54 printf("\n");
55 }
56
57 test_long("blocks completed", total, ITERATIONS);
58 test_long_less_than("high priority precedence", (long)sc[0], (long)sc[2]);
59 }
60
61 void
62 cpubusy(void* context)
63 {
64 size_t *count = context;
65 size_t iterdone;
66
67 size_t idx;
68 for (idx = 0; idx < LOOP_COUNT; ++idx) {
69 if (done) break;
70 }
71
72 if ((iterdone = __sync_sub_and_fetch(&iterations, 1)) == 0) {
73 __sync_add_and_fetch(&done, 1);
74 __sync_add_and_fetch(count, 1);
75 histogram();
76 test_stop();
77 exit(0);
78 } else if (iterdone > 0) {
79 __sync_add_and_fetch(count, 1);
80 }
81 }
82
83 void
84 submit_work(dispatch_queue_t queue, void* context)
85 {
86 int i;
87
88 for (i = 0; i < BLOCKS; ++i) {
89 dispatch_async_f(queue, context, cpubusy);
90 }
91
92 #if USE_SET_TARGET_QUEUE
93 dispatch_release(queue);
94 #endif
95 }
96
97 int
98 main(int argc __attribute__((unused)), char* argv[] __attribute__((unused)))
99 {
100 dispatch_queue_t q[PRIORITIES];
101 int i;
102
103 #if USE_SET_TARGET_QUEUE
104 test_start("Dispatch Priority (Set Target Queue)");
105 for(i = 0; i < PRIORITIES; i++) {
106 q[i] = dispatch_queue_create(labels[i], NULL);
107 test_ptr_notnull("q[i]", q[i]);
108 assert(q[i]);
109 dispatch_set_target_queue(q[i], dispatch_get_global_queue(priorities[i], 0));
110 dispatch_queue_set_width(q[i], DISPATCH_QUEUE_WIDTH_MAX_LOGICAL_CPUS);
111 }
112 #else
113 test_start("Dispatch Priority");
114 for(i = 0; i < PRIORITIES; i++) {
115 q[i] = dispatch_get_global_queue(priorities[i], 0);
116 }
117 #endif
118
119 for(i = 0; i < PRIORITIES; i++) {
120 submit_work(q[i], &counts[i].count);
121 }
122
123 dispatch_main();
124
125 return 0;
126 }