blob: ade99da7a6364d36255c5143c67f6976ef977434 [file] [log] [blame]
Kostya Serebryanyff15ef02012-05-10 14:18:22 +00001#include <pthread.h>
2#include <stdio.h>
3#include <unistd.h>
4
5int Global;
6
7void __attribute__((noinline)) foo1() {
8 Global = 42;
9}
10
11void __attribute__((noinline)) bar1() {
12 volatile int tmp = 42; (void)tmp;
13 foo1();
14}
15
16void __attribute__((noinline)) foo2() {
17 volatile int v = Global; (void)v;
18}
19
20void __attribute__((noinline)) bar2() {
21 volatile int tmp = 42; (void)tmp;
22 foo2();
23}
24
25void *Thread1(void *x) {
26 usleep(1000000);
27 bar1();
28 return NULL;
29}
30
31void *Thread2(void *x) {
32 bar2();
33 return NULL;
34}
35
36void StartThread(pthread_t *t, void *(*f)(void*)) {
37 pthread_create(t, NULL, f, NULL);
38}
39
40int main() {
41 pthread_t t[2];
42 StartThread(&t[0], Thread1);
43 StartThread(&t[1], Thread2);
44 pthread_join(t[0], NULL);
45 pthread_join(t[1], NULL);
46 return 0;
47}
48
49// CHECK: WARNING: ThreadSanitizer: data race
50// CHECK-NEXT: Write of size 4 at {{.*}} by thread 1:
51// CHECK-NEXT: #0 foo1 {{.*}}simple_stack.c:8 ({{.*}})
52// CHECK-NEXT: #1 bar1 {{.*}}simple_stack.c:13 ({{.*}})
53// CHECK-NEXT: #2 Thread1 {{.*}}simple_stack.c:27 ({{.*}})
54// CHECK-NEXT: Previous read of size 4 at {{.*}} by thread 2:
55// CHECK-NEXT: #0 foo2 {{.*}}simple_stack.c:17 ({{.*}})
56// CHECK-NEXT: #1 bar2 {{.*}}simple_stack.c:22 ({{.*}})
57// CHECK-NEXT: #2 Thread2 {{.*}}simple_stack.c:32 ({{.*}})
58// CHECK-NEXT: Thread 1 (running) created at:
59// CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}})
60// CHECK-NEXT: #1 StartThread {{.*}}simple_stack.c:37 ({{.*}})
61// CHECK-NEXT: #2 main {{.*}}simple_stack.c:42 ({{.*}})
62// CHECK-NEXT: Thread 2 ({{.*}}) created at:
63// CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}})
64// CHECK-NEXT: #1 StartThread {{.*}}simple_stack.c:37 ({{.*}})
65// CHECK-NEXT: #2 main {{.*}}simple_stack.c:43 ({{.*}})
66