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