1 // RUN: %clang_tsan %s -o %t
2 // RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer'
3 
4 #include <dispatch/dispatch.h>
5 
6 #include "../test.h"
7 
8 dispatch_semaphore_t sem;
9 
10 long global;
11 long global2;
12 
callback(void * context)13 void callback(void *context) {
14   global2 = 48;
15   barrier_wait(&barrier);
16 
17   dispatch_semaphore_signal(sem);
18 }
19 
main()20 int main() {
21   fprintf(stderr, "Hello world.\n");
22   barrier_init(&barrier, 2);
23 
24   dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
25   dispatch_group_t g = dispatch_group_create();
26   sem = dispatch_semaphore_create(0);
27 
28   dispatch_group_enter(g);
29   dispatch_async(q, ^{
30     global = 47;
31     dispatch_group_leave(g);
32     barrier_wait(&barrier);
33   });
34   dispatch_group_notify(g, q, ^{
35     global = 48;
36     barrier_wait(&barrier);
37 
38     dispatch_semaphore_signal(sem);
39   });
40   dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
41 
42   dispatch_group_enter(g);
43   dispatch_async(q, ^{
44     global2 = 47;
45     dispatch_group_leave(g);
46     barrier_wait(&barrier);
47   });
48   dispatch_group_notify_f(g, q, NULL, &callback);
49   dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
50 
51   fprintf(stderr, "Done.\n");
52 }
53 
54 // CHECK: Hello world.
55 // CHECK: Done.
56