wq_block_handoff.c [plain text]
#include <dispatch/dispatch.h>
#include <sys/sysctl.h>
#include <stdio.h>
static int x = 0;
static int y = 0;
int main(void)
{
printf("[TEST] barrier_sync -> async @ ncpu threads\n");
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
int ncpu = 1;
size_t sz = sizeof(ncpu);
sysctlbyname("hw.ncpu", &ncpu, &sz, NULL, 0);
printf("starting up %d waiters.\n", ncpu);
dispatch_queue_t q = dispatch_queue_create("moo", DISPATCH_QUEUE_CONCURRENT);
dispatch_barrier_sync(q, ^{
dispatch_async(q, ^{
printf("async.\n");
dispatch_semaphore_signal(sema);
});
for (int i=0; i<ncpu-1; i++) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
printf("waiter %d* up.\n", i);
while (y == 0) { };
});
}
dispatch_async(dispatch_get_global_queue(0, 0), ^{
printf("waiter %d up.\n", ncpu-1);
while (x == 0) { };
printf("waiter %d idle.\n", ncpu-1);
usleep(1000);
dispatch_sync(q, ^{ printf("quack %d\n", ncpu-1); });
});
printf("waiting...\n");
sleep(1);
printf("done.\n");
});
x = 1;
int rv = dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 2ull * NSEC_PER_SEC));
printf("[%s] barrier_sync -> async completed\n", rv == 0 ? "PASS" : "FAIL");
return rv;
}