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
8const size_t size = 2;
9long global;
10long array[size];
11
12void callback(void *context, size_t i) {
13 long n = global;
14 array[i] = n + i;
15 barrier_wait(barrier: &barrier);
16}
17
18int main(int argc, const char *argv[]) {
19 fprintf(stderr, format: "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: &barrier, count: size);
29 dispatch_apply(size, q, ^(size_t i) {
30 long n = global;
31 array[i] = n + i;
32 barrier_wait(barrier: &barrier);
33 });
34
35 for (size_t i = 0; i < size; i++) {
36 fprintf(stderr, format: "array[%ld] = %ld\n", i, array[i]);
37 }
38
39 global = 142;
40
41 barrier_init(barrier: &barrier, count: size);
42 dispatch_apply_f(size, q, NULL, &callback);
43
44 for (size_t i = 0; i < size; i++) {
45 fprintf(stderr, format: "array[%ld] = %ld\n", i, array[i]);
46 }
47
48 fprintf(stderr, format: "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

source code of compiler-rt/test/tsan/libdispatch/apply.c