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