1 | // RUN: %clangxx_tsan %s -o %t |
---|---|
2 | // RUN: not %run %t 5 2>&1 | FileCheck %s |
3 | // RUN: not %run %t 10 2>&1 | FileCheck %s |
4 | // RUN: not %run %t 15 2>&1 | FileCheck %s |
5 | // RUN: not %run %t 20 2>&1 | FileCheck %s |
6 | // RUN: %run %t 30 2>&1 | FileCheck %s --check-prefix=CHECK-TOO-LONG-CYCLE |
7 | |
8 | #include <pthread.h> |
9 | #include <stdio.h> |
10 | #include <stdlib.h> |
11 | |
12 | int main(int argc, char *argv[]) { |
13 | int num_mutexes = 5; |
14 | if (argc > 1) num_mutexes = atoi(nptr: argv[1]); |
15 | |
16 | pthread_mutex_t m[num_mutexes]; |
17 | for (int i = 0; i < num_mutexes; ++i) |
18 | pthread_mutex_init(mutex: &m[i], NULL); |
19 | |
20 | for (int i = 0; i < num_mutexes - 1; ++i) { |
21 | pthread_mutex_lock(mutex: &m[i]); |
22 | pthread_mutex_lock(mutex: &m[i + 1]); |
23 | |
24 | pthread_mutex_unlock(mutex: &m[i]); |
25 | pthread_mutex_unlock(mutex: &m[i + 1]); |
26 | } |
27 | |
28 | pthread_mutex_lock(mutex: &m[num_mutexes - 1]); |
29 | pthread_mutex_lock(mutex: &m[0]); |
30 | |
31 | pthread_mutex_unlock(mutex: &m[num_mutexes - 1]); |
32 | pthread_mutex_unlock(mutex: &m[0]); |
33 | |
34 | for (int i = 0; i < num_mutexes; ++i) |
35 | pthread_mutex_destroy(mutex: &m[i]); |
36 | |
37 | fprintf(stderr, format: "PASS\n"); |
38 | } |
39 | |
40 | // CHECK: ThreadSanitizer: lock-order-inversion (potential deadlock) |
41 | // CHECK-TOO-LONG-CYCLE: WARNING: too long mutex cycle found |
42 | // CHECK: PASS |
43 |