1 | // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s |
2 | #include "test.h" |
3 | |
4 | /* |
5 | Annotations usage example. |
6 | |
7 | Tsan does not see synchronization in barrier_wait. |
8 | ANNOTATE_HAPPENS_BEFORE/AFTER communicate the synchronization to tsan |
9 | and prevent the race report. |
10 | |
11 | If the compiler does not support __has_feature macro, then you can build with |
12 | CFLAGS="-fsanitize=thread -DTHREAD_SANITIZER" and then use |
13 | #ifdef THREAD_SANITIZER to enabled annotations. |
14 | */ |
15 | |
16 | #if defined(__has_feature) && __has_feature(thread_sanitizer) |
17 | # define ANNOTATE_HAPPENS_BEFORE(addr) \ |
18 | AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr)) |
19 | # define ANNOTATE_HAPPENS_AFTER(addr) \ |
20 | AnnotateHappensAfter(__FILE__, __LINE__, (void*)(addr)) |
21 | extern "C" void AnnotateHappensBefore(const char *f, int l, void *addr); |
22 | extern "C" void AnnotateHappensAfter(const char *f, int l, void *addr); |
23 | #else |
24 | # define ANNOTATE_HAPPENS_BEFORE(addr) |
25 | # define ANNOTATE_HAPPENS_AFTER(addr) |
26 | #endif |
27 | |
28 | int Global; |
29 | |
30 | void *Thread1(void *x) { |
31 | barrier_wait(&barrier); |
32 | ANNOTATE_HAPPENS_AFTER(&barrier); |
33 | Global++; |
34 | return NULL; |
35 | } |
36 | |
37 | void *Thread2(void *x) { |
38 | Global--; |
39 | ANNOTATE_HAPPENS_BEFORE(&barrier); |
40 | barrier_wait(&barrier); |
41 | return NULL; |
42 | } |
43 | |
44 | int main() { |
45 | barrier_init(&barrier, 2); |
46 | pthread_t t[2]; |
47 | pthread_create(&t[0], NULL, Thread1, NULL); |
48 | pthread_create(&t[1], NULL, Thread2, NULL); |
49 | pthread_join(t[0], NULL); |
50 | pthread_join(t[1], NULL); |
51 | fprintf(stderr, "DONE\n" ); |
52 | return 0; |
53 | } |
54 | |
55 | // CHECK-NOT: WARNING: ThreadSanitizer: data race |
56 | // CHECK: DONE |
57 | |
58 | |