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