1*bcaeed49SFangrui Song // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
2*bcaeed49SFangrui Song #include <pthread.h>
3*bcaeed49SFangrui Song #include <stdlib.h>
4*bcaeed49SFangrui Song #include <stdio.h>
5*bcaeed49SFangrui Song #include <sched.h>
6*bcaeed49SFangrui Song
7*bcaeed49SFangrui Song struct Cache {
8*bcaeed49SFangrui Song int x;
9*bcaeed49SFangrui Song };
10*bcaeed49SFangrui Song
11*bcaeed49SFangrui Song Cache g_cache;
12*bcaeed49SFangrui Song
CreateCache()13*bcaeed49SFangrui Song Cache *CreateCache() {
14*bcaeed49SFangrui Song g_cache.x = rand();
15*bcaeed49SFangrui Song return &g_cache;
16*bcaeed49SFangrui Song }
17*bcaeed49SFangrui Song
18*bcaeed49SFangrui Song _Atomic(Cache*) queue;
19*bcaeed49SFangrui Song
Thread1(void * x)20*bcaeed49SFangrui Song void *Thread1(void *x) {
21*bcaeed49SFangrui Song static Cache *c = CreateCache();
22*bcaeed49SFangrui Song __c11_atomic_store(&queue, c, 0);
23*bcaeed49SFangrui Song return 0;
24*bcaeed49SFangrui Song }
25*bcaeed49SFangrui Song
Thread2(void * x)26*bcaeed49SFangrui Song void *Thread2(void *x) {
27*bcaeed49SFangrui Song Cache *c = 0;
28*bcaeed49SFangrui Song for (;;) {
29*bcaeed49SFangrui Song c = __c11_atomic_load(&queue, 0);
30*bcaeed49SFangrui Song if (c)
31*bcaeed49SFangrui Song break;
32*bcaeed49SFangrui Song sched_yield();
33*bcaeed49SFangrui Song }
34*bcaeed49SFangrui Song if (c->x >= RAND_MAX)
35*bcaeed49SFangrui Song exit(1);
36*bcaeed49SFangrui Song return 0;
37*bcaeed49SFangrui Song }
38*bcaeed49SFangrui Song
main()39*bcaeed49SFangrui Song int main() {
40*bcaeed49SFangrui Song pthread_t t[2];
41*bcaeed49SFangrui Song pthread_create(&t[0], 0, Thread1, 0);
42*bcaeed49SFangrui Song pthread_create(&t[1], 0, Thread2, 0);
43*bcaeed49SFangrui Song pthread_join(t[0], 0);
44*bcaeed49SFangrui Song pthread_join(t[1], 0);
45*bcaeed49SFangrui Song }
46*bcaeed49SFangrui Song
47*bcaeed49SFangrui Song // CHECK: WARNING: ThreadSanitizer: data race
48