[ASan/Win] Don't crash when ASAN_OPTIONS have disable_core=1
[blocksruntime.git] / test / tsan / deadlock_detector_stress_test.cc
blobac9fcbd5eef7a555bf77be7d535ce4d8a3bfb372
1 // RUN: %clangxx_tsan %s -o %t -DLockType=PthreadMutex
2 // RUN: TSAN_OPTIONS=detect_deadlocks=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOT-SECOND
3 // TSAN_OPTIONS="detect_deadlocks=1 second_deadlock_stack=1" not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SECOND
4 // RUN: %clangxx_tsan %s -o %t -DLockType=PthreadSpinLock
5 // RUN: TSAN_OPTIONS=detect_deadlocks=1 not %run %t 2>&1 | FileCheck %s
6 // RUN: %clangxx_tsan %s -o %t -DLockType=PthreadRWLock
7 // RUN: TSAN_OPTIONS=detect_deadlocks=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RD
8 // RUN: %clangxx_tsan %s -o %t -DLockType=PthreadRecursiveMutex
9 // RUN: TSAN_OPTIONS=detect_deadlocks=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-REC
10 #include <pthread.h>
11 #undef NDEBUG
12 #include <assert.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <unistd.h>
16 #include <new>
18 #ifndef LockType
19 #define LockType PthreadMutex
20 #endif
22 // You can optionally pass [test_number [iter_count]] on command line.
23 static int test_number = -1;
24 static int iter_count = 100000;
26 class PthreadMutex {
27 public:
28 explicit PthreadMutex(bool recursive = false) {
29 if (recursive) {
30 pthread_mutexattr_t attr;
31 pthread_mutexattr_init(&attr);
32 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
33 assert(0 == pthread_mutex_init(&mu_, &attr));
34 } else {
35 assert(0 == pthread_mutex_init(&mu_, 0));
38 ~PthreadMutex() {
39 assert(0 == pthread_mutex_destroy(&mu_));
40 (void)padding_;
42 static bool supports_read_lock() { return false; }
43 static bool supports_recursive_lock() { return false; }
44 void lock() { assert(0 == pthread_mutex_lock(&mu_)); }
45 void unlock() { assert(0 == pthread_mutex_unlock(&mu_)); }
46 bool try_lock() { return 0 == pthread_mutex_trylock(&mu_); }
47 void rdlock() { assert(0); }
48 void rdunlock() { assert(0); }
49 bool try_rdlock() { assert(0); }
51 private:
52 pthread_mutex_t mu_;
53 char padding_[64 - sizeof(pthread_mutex_t)];
56 class PthreadRecursiveMutex : public PthreadMutex {
57 public:
58 PthreadRecursiveMutex() : PthreadMutex(true) { }
59 static bool supports_recursive_lock() { return true; }
62 class PthreadSpinLock {
63 public:
64 PthreadSpinLock() { assert(0 == pthread_spin_init(&mu_, 0)); }
65 ~PthreadSpinLock() {
66 assert(0 == pthread_spin_destroy(&mu_));
67 (void)padding_;
69 static bool supports_read_lock() { return false; }
70 static bool supports_recursive_lock() { return false; }
71 void lock() { assert(0 == pthread_spin_lock(&mu_)); }
72 void unlock() { assert(0 == pthread_spin_unlock(&mu_)); }
73 bool try_lock() { return 0 == pthread_spin_trylock(&mu_); }
74 void rdlock() { assert(0); }
75 void rdunlock() { assert(0); }
76 bool try_rdlock() { assert(0); }
78 private:
79 pthread_spinlock_t mu_;
80 char padding_[64 - sizeof(pthread_spinlock_t)];
83 class PthreadRWLock {
84 public:
85 PthreadRWLock() { assert(0 == pthread_rwlock_init(&mu_, 0)); }
86 ~PthreadRWLock() {
87 assert(0 == pthread_rwlock_destroy(&mu_));
88 (void)padding_;
90 static bool supports_read_lock() { return true; }
91 static bool supports_recursive_lock() { return false; }
92 void lock() { assert(0 == pthread_rwlock_wrlock(&mu_)); }
93 void unlock() { assert(0 == pthread_rwlock_unlock(&mu_)); }
94 bool try_lock() { return 0 == pthread_rwlock_trywrlock(&mu_); }
95 void rdlock() { assert(0 == pthread_rwlock_rdlock(&mu_)); }
96 void rdunlock() { assert(0 == pthread_rwlock_unlock(&mu_)); }
97 bool try_rdlock() { return 0 == pthread_rwlock_tryrdlock(&mu_); }
99 private:
100 pthread_rwlock_t mu_;
101 char padding_[64 - sizeof(pthread_rwlock_t)];
104 class LockTest {
105 public:
106 LockTest() : n_(), locks_() {}
107 void Init(size_t n) {
108 n_ = n;
109 locks_ = new LockType*[n_];
110 for (size_t i = 0; i < n_; i++)
111 locks_[i] = new LockType;
113 ~LockTest() {
114 for (size_t i = 0; i < n_; i++)
115 delete locks_[i];
116 delete [] locks_;
118 void L(size_t i) {
119 assert(i < n_);
120 locks_[i]->lock();
123 void U(size_t i) {
124 assert(i < n_);
125 locks_[i]->unlock();
128 void RL(size_t i) {
129 assert(i < n_);
130 locks_[i]->rdlock();
133 void RU(size_t i) {
134 assert(i < n_);
135 locks_[i]->rdunlock();
138 void *A(size_t i) {
139 assert(i < n_);
140 return locks_[i];
143 bool T(size_t i) {
144 assert(i < n_);
145 return locks_[i]->try_lock();
148 // Simple lock order onversion.
149 void Test1() {
150 if (test_number > 0 && test_number != 1) return;
151 fprintf(stderr, "Starting Test1\n");
152 // CHECK: Starting Test1
153 Init(5);
154 fprintf(stderr, "Expecting lock inversion: %p %p\n", A(0), A(1));
155 // CHECK: Expecting lock inversion: [[A1:0x[a-f0-9]*]] [[A2:0x[a-f0-9]*]]
156 Lock_0_1();
157 Lock_1_0();
158 // CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
159 // CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ([[A1]]) => [[M2:M[0-9]+]] ([[A2]]) => [[M1]]
160 // CHECK: Mutex [[M2]] acquired here while holding mutex [[M1]]
161 // CHECK: #0 pthread_
162 // CHECK-SECOND: Mutex [[M1]] previously acquired by the same thread here:
163 // CHECK-SECOND: #0 pthread_
164 // CHECK-NOT-SECOND: second_deadlock_stack=1 to get more informative warning message
165 // CHECK-NOT-SECOND-NOT: #0 pthread_
166 // CHECK: Mutex [[M1]] acquired here while holding mutex [[M2]]
167 // CHECK: #0 pthread_
168 // CHECK-SECOND: Mutex [[M2]] previously acquired by the same thread here:
169 // CHECK-SECOND: #0 pthread_
170 // CHECK-NOT-SECOND-NOT: #0 pthread_
171 // CHECK-NOT: WARNING: ThreadSanitizer:
174 // Simple lock order inversion with 3 locks.
175 void Test2() {
176 if (test_number > 0 && test_number != 2) return;
177 fprintf(stderr, "Starting Test2\n");
178 // CHECK: Starting Test2
179 Init(5);
180 fprintf(stderr, "Expecting lock inversion: %p %p %p\n", A(0), A(1), A(2));
181 // CHECK: Expecting lock inversion: [[A1:0x[a-f0-9]*]] [[A2:0x[a-f0-9]*]] [[A3:0x[a-f0-9]*]]
182 Lock2(0, 1);
183 Lock2(1, 2);
184 Lock2(2, 0);
185 // CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
186 // CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ([[A1]]) => [[M2:M[0-9]+]] ([[A2]]) => [[M3:M[0-9]+]] ([[A3]]) => [[M1]]
187 // CHECK-NOT: WARNING: ThreadSanitizer:
190 // Lock order inversion with lots of new locks created (but not used)
191 // between. Since the new locks are not used we should still detect the
192 // deadlock.
193 void Test3() {
194 if (test_number > 0 && test_number != 3) return;
195 fprintf(stderr, "Starting Test3\n");
196 // CHECK: Starting Test3
197 Init(5);
198 Lock_0_1();
199 L(2);
200 CreateAndDestroyManyLocks();
201 U(2);
202 Lock_1_0();
203 // CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
204 // CHECK-NOT: WARNING: ThreadSanitizer:
207 // lock l0=>l1; then create and use lots of locks; then lock l1=>l0.
208 // The deadlock epoch should have changed and we should not report anything.
209 void Test4() {
210 if (test_number > 0 && test_number != 4) return;
211 fprintf(stderr, "Starting Test4\n");
212 // CHECK: Starting Test4
213 Init(5);
214 Lock_0_1();
215 L(2);
216 CreateLockUnlockAndDestroyManyLocks();
217 U(2);
218 Lock_1_0();
219 // CHECK-NOT: WARNING: ThreadSanitizer:
222 void Test5() {
223 if (test_number > 0 && test_number != 5) return;
224 fprintf(stderr, "Starting Test5\n");
225 // CHECK: Starting Test5
226 Init(5);
227 RunThreads(&LockTest::Lock_0_1, &LockTest::Lock_1_0);
228 // CHECK: WARNING: ThreadSanitizer: lock-order-inversion
229 // CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ({{.*}}) => [[M2:M[0-9]+]] ({{.*}}) => [[M1]]
230 // CHECK: Mutex [[M2]] acquired here while holding mutex [[M1]] in thread [[T1:T[0-9]+]]
231 // CHECK: Mutex [[M1]] acquired here while holding mutex [[M2]] in thread [[T2:T[0-9]+]]
232 // CHECK: Thread [[T1]] {{.*}} created by main thread
233 // CHECK: Thread [[T2]] {{.*}} created by main thread
234 // CHECK-NOT: WARNING: ThreadSanitizer:
237 void Test6() {
238 if (test_number > 0 && test_number != 6) return;
239 fprintf(stderr, "Starting Test6: 3 threads lock/unlock private mutexes\n");
240 // CHECK: Starting Test6
241 Init(100);
242 // CHECK-NOT: WARNING: ThreadSanitizer:
243 RunThreads(&LockTest::Lock1_Loop_0, &LockTest::Lock1_Loop_1,
244 &LockTest::Lock1_Loop_2);
247 void Test7() {
248 if (test_number > 0 && test_number != 7) return;
249 fprintf(stderr, "Starting Test7\n");
250 // CHECK: Starting Test7
251 Init(10);
252 L(0); T(1); U(1); U(0);
253 T(1); L(0); U(1); U(0);
254 // CHECK-NOT: WARNING: ThreadSanitizer:
255 fprintf(stderr, "No cycle: 0=>1\n");
256 // CHECK: No cycle: 0=>1
258 T(2); L(3); U(3); U(2);
259 L(3); T(2); U(3); U(2);
260 // CHECK-NOT: WARNING: ThreadSanitizer:
261 fprintf(stderr, "No cycle: 2=>3\n");
262 // CHECK: No cycle: 2=>3
264 T(4); L(5); U(4); U(5);
265 L(5); L(4); U(4); U(5);
266 // CHECK: WARNING: ThreadSanitizer: lock-order-inversion
267 fprintf(stderr, "Have cycle: 4=>5\n");
268 // CHECK: Have cycle: 4=>5
270 L(7); L(6); U(6); U(7);
271 T(6); L(7); U(6); U(7);
272 // CHECK: WARNING: ThreadSanitizer: lock-order-inversion
273 fprintf(stderr, "Have cycle: 6=>7\n");
274 // CHECK: Have cycle: 6=>7
277 void Test8() {
278 if (test_number > 0 && test_number != 8) return;
279 if (!LockType::supports_read_lock()) return;
280 fprintf(stderr, "Starting Test8\n");
281 Init(5);
282 // CHECK-RD: Starting Test8
283 RL(0); L(1); RU(0); U(1);
284 L(1); RL(0); RU(0); U(1);
285 // CHECK-RD: WARNING: ThreadSanitizer: lock-order-inversion
286 fprintf(stderr, "Have cycle: 0=>1\n");
287 // CHECK-RD: Have cycle: 0=>1
289 RL(2); RL(3); RU(2); RU(3);
290 RL(3); RL(2); RU(2); RU(3);
291 // CHECK-RD: WARNING: ThreadSanitizer: lock-order-inversion
292 fprintf(stderr, "Have cycle: 2=>3\n");
293 // CHECK-RD: Have cycle: 2=>3
296 void Test9() {
297 if (test_number > 0 && test_number != 9) return;
298 if (!LockType::supports_recursive_lock()) return;
299 fprintf(stderr, "Starting Test9\n");
300 // CHECK-REC: Starting Test9
301 Init(5);
302 L(0); L(0); L(0); L(1); U(1); U(0); U(0); U(0);
303 L(1); L(1); L(1); L(0); U(0); U(1); U(1); U(1);
304 // CHECK-REC: WARNING: ThreadSanitizer: lock-order-inversion
307 void Test10() {
308 if (test_number > 0 && test_number != 10) return;
309 fprintf(stderr, "Starting Test10: 4 threads lock/unlock 4 private mutexes, one under another\n");
310 // CHECK: Starting Test10
311 Init(100);
312 // CHECK-NOT: WARNING: ThreadSanitizer:
313 RunThreads(&LockTest::Test10_Thread1, &LockTest::Test10_Thread2,
314 &LockTest::Test10_Thread3, &LockTest::Test10_Thread4);
316 void Test10_Thread1() { Test10_Thread(0); }
317 void Test10_Thread2() { Test10_Thread(10); }
318 void Test10_Thread3() { Test10_Thread(20); }
319 void Test10_Thread4() { Test10_Thread(30); }
320 void Test10_Thread(size_t m) {
321 for (int i = 0; i < iter_count; i++) {
322 L(m + 0);
323 L(m + 1);
324 L(m + 2);
325 L(m + 3);
326 U(m + 3);
327 U(m + 2);
328 U(m + 1);
329 U(m + 0);
333 void Test11() {
334 if (test_number > 0 && test_number != 11) return;
335 fprintf(stderr, "Starting Test11: 4 threads lock/unlock 4 private mutexes, all under another private mutex\n");
336 // CHECK: Starting Test11
337 Init(500);
338 // CHECK-NOT: WARNING: ThreadSanitizer:
339 RunThreads(&LockTest::Test11_Thread1, &LockTest::Test11_Thread2,
340 &LockTest::Test11_Thread3, &LockTest::Test11_Thread4);
342 void Test11_Thread1() { Test10_Thread(0); }
343 void Test11_Thread2() { Test10_Thread(10); }
344 void Test11_Thread3() { Test10_Thread(20); }
345 void Test11_Thread4() { Test10_Thread(30); }
346 void Test11_Thread(size_t m) {
347 for (int i = 0; i < iter_count; i++) {
348 L(m);
349 L(m + 100);
350 U(m + 100);
351 L(m + 200);
352 U(m + 200);
353 L(m + 300);
354 U(m + 300);
355 L(m + 400);
356 U(m + 500);
357 U(m);
361 void Test12() {
362 if (test_number > 0 && test_number != 12) return;
363 if (!LockType::supports_read_lock()) return;
364 fprintf(stderr, "Starting Test12: 4 threads read lock/unlock 4 shared mutexes, one under another\n");
365 // CHECK-RD: Starting Test12
366 Init(500);
367 // CHECK-RD-NOT: WARNING: ThreadSanitizer:
368 RunThreads(&LockTest::Test12_Thread, &LockTest::Test12_Thread,
369 &LockTest::Test12_Thread, &LockTest::Test12_Thread);
371 void Test12_Thread() {
372 for (int i = 0; i < iter_count; i++) {
373 RL(000);
374 RL(100);
375 RL(200);
376 RL(300);
377 RU(300);
378 RU(200);
379 RU(100);
380 RU(000);
384 void Test13() {
385 if (test_number > 0 && test_number != 13) return;
386 if (!LockType::supports_read_lock()) return;
387 fprintf(stderr, "Starting Test13: 4 threads read lock/unlock 4 shared mutexes, all under another shared mutex\n");
388 // CHECK-RD: Starting Test13
389 Init(500);
390 // CHECK-RD-NOT: WARNING: ThreadSanitizer:
391 RunThreads(&LockTest::Test13_Thread, &LockTest::Test13_Thread,
392 &LockTest::Test13_Thread, &LockTest::Test13_Thread);
394 void Test13_Thread() {
395 for (int i = 0; i < iter_count; i++) {
396 RL(0);
397 RL(100);
398 RU(100);
399 RL(200);
400 RU(200);
401 RL(300);
402 RU(300);
403 RL(400);
404 RU(400);
405 RU(0);
409 void Test14() {
410 if (test_number > 0 && test_number != 14) return;
411 fprintf(stderr, "Starting Test14: create lots of locks in 4 threads\n");
412 Init(10);
413 // CHECK-RD: Starting Test14
414 RunThreads(&LockTest::CreateAndDestroyLocksLoop,
415 &LockTest::CreateAndDestroyLocksLoop,
416 &LockTest::CreateAndDestroyLocksLoop,
417 &LockTest::CreateAndDestroyLocksLoop);
420 void Test15() {
421 if (test_number > 0 && test_number != 15) return;
422 if (!LockType::supports_read_lock()) return;
423 fprintf(stderr, "Starting Test15: recursive rlock\n");
424 // DISABLEDCHECK-RD: Starting Test15
425 Init(5);
426 RL(0); RL(0); RU(0); RU(0); // Recusrive reader lock.
427 RL(0); RL(0); RL(0); RU(0); RU(0); RU(0); // Recusrive reader lock.
430 // More detailed output test.
431 void Test16() {
432 if (test_number > 0 && test_number != 16) return;
433 fprintf(stderr, "Starting Test16: detailed output test with two locks\n");
434 // CHECK: Starting Test16
435 // CHECK: WARNING: ThreadSanitizer: lock-order-inversion
436 // CHECK: acquired here while holding mutex
437 // CHECK: LockTest::Acquire1
438 // CHECK-NEXT: LockTest::Acquire_0_then_1
439 // CHECK-SECOND: previously acquired by the same thread here
440 // CHECK-SECOND: LockTest::Acquire0
441 // CHECK-SECOND-NEXT: LockTest::Acquire_0_then_1
442 // CHECK: acquired here while holding mutex
443 // CHECK: LockTest::Acquire0
444 // CHECK-NEXT: LockTest::Acquire_1_then_0
445 // CHECK-SECOND: previously acquired by the same thread here
446 // CHECK-SECOND: LockTest::Acquire1
447 // CHECK-SECOND-NEXT: LockTest::Acquire_1_then_0
448 Init(5);
449 Acquire_0_then_1();
450 U(0); U(1);
451 Acquire_1_then_0();
452 U(0); U(1);
455 // More detailed output test.
456 void Test17() {
457 if (test_number > 0 && test_number != 17) return;
458 fprintf(stderr, "Starting Test17: detailed output test with three locks\n");
459 // CHECK: Starting Test17
460 // CHECK: WARNING: ThreadSanitizer: lock-order-inversion
461 // CHECK: LockTest::Acquire1
462 // CHECK-NEXT: LockTest::Acquire_0_then_1
463 // CHECK: LockTest::Acquire2
464 // CHECK-NEXT: LockTest::Acquire_1_then_2
465 // CHECK: LockTest::Acquire0
466 // CHECK-NEXT: LockTest::Acquire_2_then_0
467 Init(5);
468 Acquire_0_then_1();
469 U(0); U(1);
470 Acquire_1_then_2();
471 U(1); U(2);
472 Acquire_2_then_0();
473 U(0); U(2);
476 __attribute__((noinline)) void Acquire2() { L(2); }
477 __attribute__((noinline)) void Acquire1() { L(1); }
478 __attribute__((noinline)) void Acquire0() { L(0); }
479 __attribute__((noinline)) void Acquire_1_then_0() { Acquire1(); Acquire0(); }
480 __attribute__((noinline)) void Acquire_0_then_1() { Acquire0(); Acquire1(); }
481 __attribute__((noinline)) void Acquire_1_then_2() { Acquire1(); Acquire2(); }
482 __attribute__((noinline)) void Acquire_2_then_0() { Acquire2(); Acquire0(); }
484 // This test creates, locks, unlocks and destroys lots of mutexes.
485 void Test18() {
486 if (test_number > 0 && test_number != 18) return;
487 fprintf(stderr, "Starting Test18: create, lock and destroy 4 locks; all in "
488 "4 threads in a loop\n");
489 RunThreads(&LockTest::Test18_Thread, &LockTest::Test18_Thread,
490 &LockTest::Test18_Thread, &LockTest::Test18_Thread);
493 void Test18_Thread() {
494 LockType *l = new LockType[4];
495 for (size_t i = 0; i < iter_count / 100; i++) {
496 for (int i = 0; i < 4; i++) l[i].lock();
497 for (int i = 0; i < 4; i++) l[i].unlock();
498 for (int i = 0; i < 4; i++) l[i].~LockType();
499 for (int i = 0; i < 4; i++) new ((void*)&l[i]) LockType();
501 delete [] l;
504 private:
505 void Lock2(size_t l1, size_t l2) { L(l1); L(l2); U(l2); U(l1); }
506 void Lock_0_1() { Lock2(0, 1); }
507 void Lock_1_0() { sleep(1); Lock2(1, 0); }
508 void Lock1_Loop(size_t i, size_t n_iter) {
509 for (size_t it = 0; it < n_iter; it++) {
510 // if ((it & (it - 1)) == 0) fprintf(stderr, "%zd", i);
511 L(i);
512 U(i);
514 // fprintf(stderr, "\n");
516 void Lock1_Loop_0() { Lock1_Loop(0, iter_count); }
517 void Lock1_Loop_1() { Lock1_Loop(10, iter_count); }
518 void Lock1_Loop_2() { Lock1_Loop(20, iter_count); }
520 void CreateAndDestroyManyLocks() {
521 LockType *create_many_locks_but_never_acquire =
522 new LockType[kDeadlockGraphSize];
523 (void)create_many_locks_but_never_acquire;
524 delete [] create_many_locks_but_never_acquire;
527 void CreateAndDestroyLocksLoop() {
528 for (size_t it = 0; it <= iter_count; it++) {
529 LockType some_locks[10];
530 (void)some_locks;
534 void CreateLockUnlockAndDestroyManyLocks() {
535 LockType many_locks[kDeadlockGraphSize];
536 for (size_t i = 0; i < kDeadlockGraphSize; i++) {
537 many_locks[i].lock();
538 many_locks[i].unlock();
542 // LockTest Member function callback.
543 struct CB {
544 void (LockTest::*f)();
545 LockTest *lt;
548 // Thread function with CB.
549 static void *Thread(void *param) {
550 CB *cb = (CB*)param;
551 (cb->lt->*cb->f)();
552 return NULL;
555 void RunThreads(void (LockTest::*f1)(), void (LockTest::*f2)(),
556 void (LockTest::*f3)() = 0, void (LockTest::*f4)() = 0) {
557 const int kNumThreads = 4;
558 pthread_t t[kNumThreads];
559 CB cb[kNumThreads] = {{f1, this}, {f2, this}, {f3, this}, {f4, this}};
560 for (int i = 0; i < kNumThreads && cb[i].f; i++)
561 pthread_create(&t[i], 0, Thread, &cb[i]);
562 for (int i = 0; i < kNumThreads && cb[i].f; i++)
563 pthread_join(t[i], 0);
566 static const size_t kDeadlockGraphSize = 4096;
567 size_t n_;
568 LockType **locks_;
571 int main(int argc, char **argv) {
572 if (argc > 1)
573 test_number = atoi(argv[1]);
574 if (argc > 2)
575 iter_count = atoi(argv[2]);
576 LockTest().Test1();
577 LockTest().Test2();
578 LockTest().Test3();
579 LockTest().Test4();
580 LockTest().Test5();
581 LockTest().Test6();
582 LockTest().Test7();
583 LockTest().Test8();
584 LockTest().Test9();
585 LockTest().Test10();
586 LockTest().Test11();
587 LockTest().Test12();
588 LockTest().Test13();
589 LockTest().Test14();
590 LockTest().Test15();
591 LockTest().Test16();
592 LockTest().Test17();
593 LockTest().Test18();
594 fprintf(stderr, "ALL-DONE\n");
595 // CHECK: ALL-DONE