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 const size_t size = 2;
9 long global;
10 long array[size];
11
callback(void * context,size_t i)12 void callback(void *context, size_t i) {
13 long n = global;
14 array[i] = n + i;
15 barrier_wait(&barrier);
16 }
17
main(int argc,const char * argv[])18 int main(int argc, const char *argv[]) {
19 fprintf(stderr, "start\n");
20
21 // Warm up GCD (workaround for macOS Sierra where dispatch_apply might run single-threaded).
22 dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ });
23
24 dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
25
26 global = 42;
27
28 barrier_init(&barrier, size);
29 dispatch_apply(size, q, ^(size_t i) {
30 long n = global;
31 array[i] = n + i;
32 barrier_wait(&barrier);
33 });
34
35 for (size_t i = 0; i < size; i++) {
36 fprintf(stderr, "array[%ld] = %ld\n", i, array[i]);
37 }
38
39 global = 142;
40
41 barrier_init(&barrier, size);
42 dispatch_apply_f(size, q, NULL, &callback);
43
44 for (size_t i = 0; i < size; i++) {
45 fprintf(stderr, "array[%ld] = %ld\n", i, array[i]);
46 }
47
48 fprintf(stderr, "done\n");
49 return 0;
50 }
51
52 // CHECK: start
53 // CHECK: array[0] = 42
54 // CHECK: array[1] = 43
55 // CHECK: array[0] = 142
56 // CHECK: array[1] = 143
57 // CHECK: done
58