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