1 #include "test/jemalloc_test.h"
2
3 static witness_lock_error_t *witness_lock_error_orig;
4 static witness_owner_error_t *witness_owner_error_orig;
5 static witness_not_owner_error_t *witness_not_owner_error_orig;
6 static witness_depth_error_t *witness_depth_error_orig;
7
8 static bool saw_lock_error;
9 static bool saw_owner_error;
10 static bool saw_not_owner_error;
11 static bool saw_depth_error;
12
13 static void
witness_lock_error_intercept(const witness_list_t * witnesses,const witness_t * witness)14 witness_lock_error_intercept(const witness_list_t *witnesses,
15 const witness_t *witness) {
16 saw_lock_error = true;
17 }
18
19 static void
witness_owner_error_intercept(const witness_t * witness)20 witness_owner_error_intercept(const witness_t *witness) {
21 saw_owner_error = true;
22 }
23
24 static void
witness_not_owner_error_intercept(const witness_t * witness)25 witness_not_owner_error_intercept(const witness_t *witness) {
26 saw_not_owner_error = true;
27 }
28
29 static void
witness_depth_error_intercept(const witness_list_t * witnesses,witness_rank_t rank_inclusive,unsigned depth)30 witness_depth_error_intercept(const witness_list_t *witnesses,
31 witness_rank_t rank_inclusive, unsigned depth) {
32 saw_depth_error = true;
33 }
34
35 static int
witness_comp(const witness_t * a,void * oa,const witness_t * b,void * ob)36 witness_comp(const witness_t *a, void *oa, const witness_t *b, void *ob) {
37 assert_u_eq(a->rank, b->rank, "Witnesses should have equal rank");
38
39 assert(oa == (void *)a);
40 assert(ob == (void *)b);
41
42 return strcmp(a->name, b->name);
43 }
44
45 static int
witness_comp_reverse(const witness_t * a,void * oa,const witness_t * b,void * ob)46 witness_comp_reverse(const witness_t *a, void *oa, const witness_t *b,
47 void *ob) {
48 assert_u_eq(a->rank, b->rank, "Witnesses should have equal rank");
49
50 assert(oa == (void *)a);
51 assert(ob == (void *)b);
52
53 return -strcmp(a->name, b->name);
54 }
55
TEST_BEGIN(test_witness)56 TEST_BEGIN(test_witness) {
57 witness_t a, b;
58 witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
59
60 test_skip_if(!config_debug);
61
62 witness_assert_lockless(&witness_tsdn);
63 witness_assert_depth(&witness_tsdn, 0);
64 witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)1U, 0);
65
66 witness_init(&a, "a", 1, NULL, NULL);
67 witness_assert_not_owner(&witness_tsdn, &a);
68 witness_lock(&witness_tsdn, &a);
69 witness_assert_owner(&witness_tsdn, &a);
70 witness_assert_depth(&witness_tsdn, 1);
71 witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)1U, 1);
72 witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)2U, 0);
73
74 witness_init(&b, "b", 2, NULL, NULL);
75 witness_assert_not_owner(&witness_tsdn, &b);
76 witness_lock(&witness_tsdn, &b);
77 witness_assert_owner(&witness_tsdn, &b);
78 witness_assert_depth(&witness_tsdn, 2);
79 witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)1U, 2);
80 witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)2U, 1);
81 witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)3U, 0);
82
83 witness_unlock(&witness_tsdn, &a);
84 witness_assert_depth(&witness_tsdn, 1);
85 witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)1U, 1);
86 witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)2U, 1);
87 witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)3U, 0);
88 witness_unlock(&witness_tsdn, &b);
89
90 witness_assert_lockless(&witness_tsdn);
91 witness_assert_depth(&witness_tsdn, 0);
92 witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)1U, 0);
93 }
94 TEST_END
95
TEST_BEGIN(test_witness_comp)96 TEST_BEGIN(test_witness_comp) {
97 witness_t a, b, c, d;
98 witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
99
100 test_skip_if(!config_debug);
101
102 witness_assert_lockless(&witness_tsdn);
103
104 witness_init(&a, "a", 1, witness_comp, &a);
105 witness_assert_not_owner(&witness_tsdn, &a);
106 witness_lock(&witness_tsdn, &a);
107 witness_assert_owner(&witness_tsdn, &a);
108 witness_assert_depth(&witness_tsdn, 1);
109
110 witness_init(&b, "b", 1, witness_comp, &b);
111 witness_assert_not_owner(&witness_tsdn, &b);
112 witness_lock(&witness_tsdn, &b);
113 witness_assert_owner(&witness_tsdn, &b);
114 witness_assert_depth(&witness_tsdn, 2);
115 witness_unlock(&witness_tsdn, &b);
116 witness_assert_depth(&witness_tsdn, 1);
117
118 witness_lock_error_orig = witness_lock_error;
119 witness_lock_error = witness_lock_error_intercept;
120 saw_lock_error = false;
121
122 witness_init(&c, "c", 1, witness_comp_reverse, &c);
123 witness_assert_not_owner(&witness_tsdn, &c);
124 assert_false(saw_lock_error, "Unexpected witness lock error");
125 witness_lock(&witness_tsdn, &c);
126 assert_true(saw_lock_error, "Expected witness lock error");
127 witness_unlock(&witness_tsdn, &c);
128 witness_assert_depth(&witness_tsdn, 1);
129
130 saw_lock_error = false;
131
132 witness_init(&d, "d", 1, NULL, NULL);
133 witness_assert_not_owner(&witness_tsdn, &d);
134 assert_false(saw_lock_error, "Unexpected witness lock error");
135 witness_lock(&witness_tsdn, &d);
136 assert_true(saw_lock_error, "Expected witness lock error");
137 witness_unlock(&witness_tsdn, &d);
138 witness_assert_depth(&witness_tsdn, 1);
139
140 witness_unlock(&witness_tsdn, &a);
141
142 witness_assert_lockless(&witness_tsdn);
143
144 witness_lock_error = witness_lock_error_orig;
145 }
146 TEST_END
147
TEST_BEGIN(test_witness_reversal)148 TEST_BEGIN(test_witness_reversal) {
149 witness_t a, b;
150 witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
151
152 test_skip_if(!config_debug);
153
154 witness_lock_error_orig = witness_lock_error;
155 witness_lock_error = witness_lock_error_intercept;
156 saw_lock_error = false;
157
158 witness_assert_lockless(&witness_tsdn);
159
160 witness_init(&a, "a", 1, NULL, NULL);
161 witness_init(&b, "b", 2, NULL, NULL);
162
163 witness_lock(&witness_tsdn, &b);
164 witness_assert_depth(&witness_tsdn, 1);
165 assert_false(saw_lock_error, "Unexpected witness lock error");
166 witness_lock(&witness_tsdn, &a);
167 assert_true(saw_lock_error, "Expected witness lock error");
168
169 witness_unlock(&witness_tsdn, &a);
170 witness_assert_depth(&witness_tsdn, 1);
171 witness_unlock(&witness_tsdn, &b);
172
173 witness_assert_lockless(&witness_tsdn);
174
175 witness_lock_error = witness_lock_error_orig;
176 }
177 TEST_END
178
TEST_BEGIN(test_witness_recursive)179 TEST_BEGIN(test_witness_recursive) {
180 witness_t a;
181 witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
182
183 test_skip_if(!config_debug);
184
185 witness_not_owner_error_orig = witness_not_owner_error;
186 witness_not_owner_error = witness_not_owner_error_intercept;
187 saw_not_owner_error = false;
188
189 witness_lock_error_orig = witness_lock_error;
190 witness_lock_error = witness_lock_error_intercept;
191 saw_lock_error = false;
192
193 witness_assert_lockless(&witness_tsdn);
194
195 witness_init(&a, "a", 1, NULL, NULL);
196
197 witness_lock(&witness_tsdn, &a);
198 assert_false(saw_lock_error, "Unexpected witness lock error");
199 assert_false(saw_not_owner_error, "Unexpected witness not owner error");
200 witness_lock(&witness_tsdn, &a);
201 assert_true(saw_lock_error, "Expected witness lock error");
202 assert_true(saw_not_owner_error, "Expected witness not owner error");
203
204 witness_unlock(&witness_tsdn, &a);
205
206 witness_assert_lockless(&witness_tsdn);
207
208 witness_owner_error = witness_owner_error_orig;
209 witness_lock_error = witness_lock_error_orig;
210
211 }
212 TEST_END
213
TEST_BEGIN(test_witness_unlock_not_owned)214 TEST_BEGIN(test_witness_unlock_not_owned) {
215 witness_t a;
216 witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
217
218 test_skip_if(!config_debug);
219
220 witness_owner_error_orig = witness_owner_error;
221 witness_owner_error = witness_owner_error_intercept;
222 saw_owner_error = false;
223
224 witness_assert_lockless(&witness_tsdn);
225
226 witness_init(&a, "a", 1, NULL, NULL);
227
228 assert_false(saw_owner_error, "Unexpected owner error");
229 witness_unlock(&witness_tsdn, &a);
230 assert_true(saw_owner_error, "Expected owner error");
231
232 witness_assert_lockless(&witness_tsdn);
233
234 witness_owner_error = witness_owner_error_orig;
235 }
236 TEST_END
237
TEST_BEGIN(test_witness_depth)238 TEST_BEGIN(test_witness_depth) {
239 witness_t a;
240 witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
241
242 test_skip_if(!config_debug);
243
244 witness_depth_error_orig = witness_depth_error;
245 witness_depth_error = witness_depth_error_intercept;
246 saw_depth_error = false;
247
248 witness_assert_lockless(&witness_tsdn);
249 witness_assert_depth(&witness_tsdn, 0);
250
251 witness_init(&a, "a", 1, NULL, NULL);
252
253 assert_false(saw_depth_error, "Unexpected depth error");
254 witness_assert_lockless(&witness_tsdn);
255 witness_assert_depth(&witness_tsdn, 0);
256
257 witness_lock(&witness_tsdn, &a);
258 witness_assert_lockless(&witness_tsdn);
259 witness_assert_depth(&witness_tsdn, 0);
260 assert_true(saw_depth_error, "Expected depth error");
261
262 witness_unlock(&witness_tsdn, &a);
263
264 witness_assert_lockless(&witness_tsdn);
265 witness_assert_depth(&witness_tsdn, 0);
266
267 witness_depth_error = witness_depth_error_orig;
268 }
269 TEST_END
270
271 int
main(void)272 main(void) {
273 return test(
274 test_witness,
275 test_witness_comp,
276 test_witness_reversal,
277 test_witness_recursive,
278 test_witness_unlock_not_owned,
279 test_witness_depth);
280 }
281