1cac25e40SDan Liew // RUN: %clangxx_tsan -O1 %s -o %t
2*7de546e9SDmitry Vyukov // RUN: %env_tsan_opts=flush_memory_ms=1:flush_symbolizer_ms=1:memory_limit_mb=1 not %run %t 2>&1 | FileCheck %s
3ad890aa2SDmitry Vyukov #include "test.h"
4ad890aa2SDmitry Vyukov
5ad890aa2SDmitry Vyukov long X, Y;
6ad890aa2SDmitry Vyukov
Thread(void * arg)7ad890aa2SDmitry Vyukov void *Thread(void *arg) {
8ad890aa2SDmitry Vyukov __atomic_fetch_add(&X, 1, __ATOMIC_SEQ_CST);
9ad890aa2SDmitry Vyukov barrier_wait(&barrier);
10ad890aa2SDmitry Vyukov barrier_wait(&barrier);
11ad890aa2SDmitry Vyukov Y = 1;
12ad890aa2SDmitry Vyukov return &Y;
13ad890aa2SDmitry Vyukov }
14ad890aa2SDmitry Vyukov
main()15ad890aa2SDmitry Vyukov int main() {
16ad890aa2SDmitry Vyukov __tsan_flush_memory();
17ad890aa2SDmitry Vyukov barrier_init(&barrier, 2);
18ad890aa2SDmitry Vyukov __atomic_fetch_add(&X, 1, __ATOMIC_SEQ_CST);
19ad890aa2SDmitry Vyukov pthread_t t;
20ad890aa2SDmitry Vyukov pthread_create(&t, NULL, Thread, NULL);
21ad890aa2SDmitry Vyukov barrier_wait(&barrier);
22ad890aa2SDmitry Vyukov __tsan_flush_memory();
23ad890aa2SDmitry Vyukov // Trigger a race to test flushing of the symbolizer cache.
24ad890aa2SDmitry Vyukov Y = 2;
25ad890aa2SDmitry Vyukov barrier_wait(&barrier);
26ad890aa2SDmitry Vyukov pthread_join(t, NULL);
27ad890aa2SDmitry Vyukov __atomic_fetch_add(&X, 1, __ATOMIC_SEQ_CST);
28ad890aa2SDmitry Vyukov // Background runtime thread should do some flushes meanwhile.
29ad890aa2SDmitry Vyukov sleep(2);
30ad890aa2SDmitry Vyukov __tsan_flush_memory();
31ad890aa2SDmitry Vyukov fprintf(stderr, "DONE\n");
32*7de546e9SDmitry Vyukov // The race may not be detected since we are doing aggressive flushes
33*7de546e9SDmitry Vyukov // (if the state flush happens between racing accesses, tsan won't
34*7de546e9SDmitry Vyukov // detect the race). So return 1 to make the test deterministic.
35*7de546e9SDmitry Vyukov return 1;
36ad890aa2SDmitry Vyukov }
37ad890aa2SDmitry Vyukov
38ad890aa2SDmitry Vyukov // CHECK: DONE
39