1 | // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s |
2 | // CHECK-NOT: WARNING: ThreadSanitizer: data race |
3 | // CHECK-NOT: ThreadSanitizer WARNING: double lock |
4 | // CHECK-NOT: ThreadSanitizer WARNING: mutex unlock by another thread |
5 | // CHECK: OK |
6 | |
7 | #include <stdio.h> |
8 | #include <stdlib.h> |
9 | #include <pthread.h> |
10 | |
11 | pthread_mutex_t m; |
12 | pthread_cond_t c; |
13 | int x; |
14 | |
15 | void *thr1(void *p) { |
16 | int i; |
17 | |
18 | for (i = 0; i < 10; i += 2) { |
19 | pthread_mutex_lock(mutex: &m); |
20 | while (x != i) |
21 | pthread_cond_wait(cond: &c, mutex: &m); |
22 | x = i + 1; |
23 | pthread_cond_signal(cond: &c); |
24 | pthread_mutex_unlock(mutex: &m); |
25 | } |
26 | return 0; |
27 | } |
28 | |
29 | void *thr2(void *p) { |
30 | int i; |
31 | |
32 | for (i = 1; i < 10; i += 2) { |
33 | pthread_mutex_lock(mutex: &m); |
34 | while (x != i) |
35 | pthread_cond_wait(cond: &c, mutex: &m); |
36 | x = i + 1; |
37 | pthread_mutex_unlock(mutex: &m); |
38 | pthread_cond_broadcast(cond: &c); |
39 | } |
40 | return 0; |
41 | } |
42 | |
43 | int main() { |
44 | pthread_t th1, th2; |
45 | |
46 | pthread_mutex_init(mutex: &m, mutexattr: 0); |
47 | pthread_cond_init(cond: &c, cond_attr: 0); |
48 | pthread_create(newthread: &th1, attr: 0, start_routine: thr1, arg: 0); |
49 | pthread_create(newthread: &th2, attr: 0, start_routine: thr2, arg: 0); |
50 | pthread_join(th: th1, thread_return: 0); |
51 | pthread_join(th: th2, thread_return: 0); |
52 | fprintf(stderr, format: "OK\n" ); |
53 | } |
54 | |