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
8static const long kNumThreads = 4;
9
10long global;
11long global2;
12
13static dispatch_once_t once_token;
14static dispatch_once_t once_token2;
15
16void f(void *a) {
17 global2 = 42;
18 usleep(useconds: 100000);
19}
20
21void *Thread(void *a) {
22 barrier_wait(barrier: &barrier);
23
24 dispatch_once(&once_token, ^{
25 global = 42;
26 usleep(useconds: 100000);
27 });
28 long x = global;
29
30 dispatch_once_f(&once_token2, NULL, f);
31 long x2 = global2;
32
33 fprintf(stderr, format: "global = %ld\n", x);
34 fprintf(stderr, format: "global2 = %ld\n", x2);
35 return 0;
36}
37
38int main() {
39 fprintf(stderr, format: "Hello world.\n");
40 barrier_init(barrier: &barrier, count: kNumThreads);
41
42 pthread_t t[kNumThreads];
43 for (int i = 0; i < kNumThreads; i++) {
44 pthread_create(newthread: &t[i], attr: 0, start_routine: Thread, arg: 0);
45 }
46 for (int i = 0; i < kNumThreads; i++) {
47 pthread_join(th: t[i], thread_return: 0);
48 }
49
50 fprintf(stderr, format: "Done.\n");
51}
52
53// CHECK: Hello world.
54// CHECK: Done.
55

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