Skip to content

Commit bcc8c31

Browse files
committed
C test case
1 parent 8741010 commit bcc8c31

File tree

3 files changed

+171
-0
lines changed

3 files changed

+171
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| test.c:15:5:15:6 | d1 | Threaded function may be called from a context that uses $@ and $@ which may lead to deadlocks. | test.c:22:3:22:10 | call to mtx_lock | lock 1 | test.c:23:3:23:10 | call to mtx_lock | lock 2 |
2+
| test.c:33:5:33:6 | d2 | Threaded function may be called from a context that uses $@ and $@ which may lead to deadlocks. | test.c:41:3:41:10 | call to mtx_lock | lock 1 | test.c:45:3:45:10 | call to mtx_lock | lock 2 |
3+
| test.c:88:5:88:6 | d4 | Threaded function may be called from a context that uses $@ and $@ which may lead to deadlocks. | test.c:111:3:111:10 | call to mtx_lock | lock 1 | test.c:112:3:112:10 | call to mtx_lock | lock 2 |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.preventdeadlockbylockinginpredefinedorder.PreventDeadlockByLockingInPredefinedOrder
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#include <stdlib.h>
2+
#include <threads.h>
3+
4+
typedef struct {
5+
int sum;
6+
mtx_t mu;
7+
} B;
8+
9+
typedef struct {
10+
B *from;
11+
B *to;
12+
int amount;
13+
} thread_arg;
14+
15+
int d1(void *arg) { // NON_COMPLIANT
16+
thread_arg *targ = (thread_arg *)arg;
17+
18+
B *from = targ->from;
19+
B *to = targ->to;
20+
int amount = targ->amount;
21+
22+
mtx_lock(&from->mu);
23+
mtx_lock(&to->mu);
24+
25+
if (from->sum >= amount) {
26+
from->sum = from->sum - amount;
27+
to->sum = to->sum + amount;
28+
return 0;
29+
}
30+
return -1;
31+
}
32+
33+
int d2(void *arg) { // NON_COMPLIANT
34+
35+
thread_arg *targ = (thread_arg *)arg;
36+
37+
B *from = targ->from;
38+
B *to = targ->to;
39+
int amount = targ->amount;
40+
41+
mtx_lock(&from->mu);
42+
if (from->sum < amount) {
43+
return -1;
44+
}
45+
mtx_lock(&to->mu);
46+
from->sum = (from->sum - amount);
47+
to->sum = (to->sum + amount);
48+
49+
return 0;
50+
}
51+
52+
int getA() { return 0; }
53+
int getARand() { return rand(); }
54+
55+
int d3(void *arg) { // COMPLIANT
56+
57+
thread_arg *targ = (thread_arg *)arg;
58+
59+
B *from = targ->from;
60+
B *to = targ->to;
61+
int amount = targ->amount;
62+
63+
mtx_t *one;
64+
mtx_t *two;
65+
66+
int a = getARand();
67+
68+
// here a may take on multiple different
69+
// values and thus different values may flow
70+
// into the locks
71+
if (a == 9) {
72+
one = &from->mu;
73+
two = &to->mu;
74+
} else {
75+
one = &to->mu;
76+
two = &from->mu;
77+
}
78+
79+
mtx_lock(one);
80+
mtx_lock(two);
81+
82+
from->sum = (from->sum - amount);
83+
to->sum = (to->sum + amount);
84+
85+
return 0;
86+
}
87+
88+
int d4(void *arg) { // NON_COMPLIANT
89+
90+
thread_arg *targ = (thread_arg *)arg;
91+
92+
B *from = targ->from;
93+
B *to = targ->to;
94+
int amount = targ->amount;
95+
96+
mtx_t *one;
97+
mtx_t *two;
98+
int a = getARand();
99+
100+
// here a may take on multiple different
101+
// values and thus different values may flow
102+
// into the locks
103+
if (a == 9) {
104+
one = &from->mu;
105+
two = &to->mu;
106+
} else {
107+
one = &to->mu;
108+
two = &from->mu;
109+
}
110+
111+
mtx_lock(&from->mu);
112+
mtx_lock(&to->mu);
113+
114+
from->sum = (from->sum - amount);
115+
to->sum = (to->sum + amount);
116+
117+
return 0;
118+
}
119+
120+
void f(B *ba1, B *ba2) {
121+
thrd_t t1, t2;
122+
123+
// unsafe - but used for testing
124+
thread_arg a1 = {.from = ba1, .to = ba2, .amount = 100};
125+
126+
thread_arg a2 = {.from = ba2, .to = ba1, .amount = 100};
127+
128+
thrd_create(&t1, d1, &a1);
129+
thrd_create(&t2, d1, &a2);
130+
}
131+
132+
void f2(B *ba1, B *ba2) {
133+
thrd_t t1, t2;
134+
135+
// unsafe - but used for testing
136+
thread_arg a1 = {.from = ba1, .to = ba2, .amount = 100};
137+
138+
thread_arg a2 = {.from = ba2, .to = ba1, .amount = 100};
139+
140+
thrd_create(&t1, d2, &a1);
141+
thrd_create(&t2, d2, &a2);
142+
}
143+
144+
void f3(B *ba1, B *ba2) {
145+
thrd_t t1, t2;
146+
147+
// unsafe - but used for testing
148+
thread_arg a1 = {.from = ba1, .to = ba2, .amount = 100};
149+
150+
thread_arg a2 = {.from = ba2, .to = ba1, .amount = 100};
151+
152+
thrd_create(&t1, d3, &a1);
153+
thrd_create(&t2, d3, &a2);
154+
}
155+
156+
void f4(B *ba1, B *ba2) {
157+
thrd_t t1, t2;
158+
159+
// unsafe - but used for testing
160+
thread_arg a1 = {.from = ba1, .to = ba2, .amount = 100};
161+
162+
thread_arg a2 = {.from = ba2, .to = ba1, .amount = 100};
163+
164+
thrd_create(&t1, d4, &a1);
165+
thrd_create(&t2, d4, &a2);
166+
}

0 commit comments

Comments
 (0)