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 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 20 witness_owner_error_intercept(const witness_t *witness) { 21 saw_owner_error = true; 22 } 23 24 static void 25 witness_not_owner_error_intercept(const witness_t *witness) { 26 saw_not_owner_error = true; 27 } 28 29 static void 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 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 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 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 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 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 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 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 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 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