]> git.saurik.com Git - apple/libpthread.git/blob - tests/wq_block_handoff.c
libpthread-301.20.1.tar.gz
[apple/libpthread.git] / tests / wq_block_handoff.c
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 }