]>
Commit | Line | Data |
---|---|---|
964d3577 A |
1 | #include <dispatch/dispatch.h> |
2 | #include <sys/sysctl.h> | |
3 | #include <stdio.h> | |
4 | ||
5 | static int x = 0; | |
6 | static int y = 0; | |
7 | ||
8 | int main(void) | |
9 | { | |
10 | /* found in <rdar://problem/16326400> 12A216: Spotlight takes a long time to show results */ | |
11 | ||
12 | /* we need to start up NCPU-1 threads in a given bucket, then fire up one more at a separate | |
13 | * priority. | |
14 | * | |
15 | * each of these waiters needs to be non-blocked until the point where dispatch wants to | |
16 | * request a new thread. | |
17 | * | |
18 | * if dispatch ever fixes sync_barrier -> sync handoff to not require an extra thread, | |
19 | * then this test will never fail and will be invalid. | |
20 | */ | |
21 | ||
22 | printf("[TEST] barrier_sync -> async @ ncpu threads\n"); | |
23 | ||
24 | dispatch_semaphore_t sema = dispatch_semaphore_create(0); | |
25 | ||
26 | int ncpu = 1; | |
27 | size_t sz = sizeof(ncpu); | |
28 | sysctlbyname("hw.ncpu", &ncpu, &sz, NULL, 0); | |
29 | printf("starting up %d waiters.\n", ncpu); | |
30 | ||
31 | dispatch_queue_t q = dispatch_queue_create("moo", DISPATCH_QUEUE_CONCURRENT); | |
32 | dispatch_barrier_sync(q, ^{ | |
33 | dispatch_async(q, ^{ | |
34 | printf("async.\n"); | |
35 | dispatch_semaphore_signal(sema); | |
36 | }); | |
37 | for (int i=0; i<ncpu-1; i++) { | |
38 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ | |
39 | printf("waiter %d* up.\n", i); | |
40 | while (y == 0) { }; | |
41 | }); | |
42 | } | |
43 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ | |
44 | printf("waiter %d up.\n", ncpu-1); | |
45 | while (x == 0) { }; | |
46 | printf("waiter %d idle.\n", ncpu-1); | |
47 | usleep(1000); | |
48 | dispatch_sync(q, ^{ printf("quack %d\n", ncpu-1); }); | |
49 | }); | |
50 | printf("waiting...\n"); | |
51 | sleep(1); | |
52 | printf("done.\n"); | |
53 | }); | |
54 | ||
55 | x = 1; | |
56 | int rv = dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 2ull * NSEC_PER_SEC)); | |
57 | printf("[%s] barrier_sync -> async completed\n", rv == 0 ? "PASS" : "FAIL"); | |
58 | ||
59 | return rv; | |
60 | } |