Home | History | Annotate | Download | only in tests
      1 /*
      2   This file is part of Valgrind, a dynamic binary instrumentation
      3   framework.
      4 
      5   Copyright (C) 2008-2008 Google Inc
      6      opensource (at) google.com
      7 
      8   This program is free software; you can redistribute it and/or
      9   modify it under the terms of the GNU General Public License as
     10   published by the Free Software Foundation; either version 2 of the
     11   License, or (at your option) any later version.
     12 
     13   This program is distributed in the hope that it will be useful, but
     14   WITHOUT ANY WARRANTY; without even the implied warranty of
     15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16   General Public License for more details.
     17 
     18   You should have received a copy of the GNU General Public License
     19   along with this program; if not, write to the Free Software
     20   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     21   02111-1307, USA.
     22 
     23   The GNU General Public License is contained in the file COPYING.
     24 */
     25 
     26 // Author: Konstantin Serebryany <opensource (at) google.com>
     27 //
     28 // This file contains a set of unit tests for a data race detection tool.
     29 //
     30 //
     31 //
     32 // This test can be compiled with pthreads (default) or
     33 // with any other library that supports threads, locks, cond vars, etc.
     34 //
     35 // To compile with pthreads:
     36 //   g++  racecheck_unittest.cc dynamic_annotations.cc
     37 //        -lpthread -g -DDYNAMIC_ANNOTATIONS=1
     38 //
     39 // To compile with different library:
     40 //   1. cp thread_wrappers_pthread.h thread_wrappers_yourlib.h
     41 //   2. edit thread_wrappers_yourlib.h
     42 //   3. add '-DTHREAD_WRAPPERS="thread_wrappers_yourlib.h"' to your compilation.
     43 //
     44 //
     45 
     46 // This test must not include any other file specific to threading library,
     47 // everything should be inside THREAD_WRAPPERS.
     48 #ifndef THREAD_WRAPPERS
     49 # define THREAD_WRAPPERS "thread_wrappers_pthread.h"
     50 #endif
     51 #include THREAD_WRAPPERS
     52 
     53 #ifndef NEEDS_SEPERATE_RW_LOCK
     54 #define RWLock Mutex // Mutex does work as an rw-lock.
     55 #define WriterLockScoped MutexLock
     56 #define ReaderLockScoped ReaderMutexLock
     57 #endif // !NEEDS_SEPERATE_RW_LOCK
     58 
     59 
     60 // Helgrind memory usage testing stuff
     61 // If not present in dynamic_annotations.h/.cc - ignore
     62 #ifndef ANNOTATE_RESET_STATS
     63 #define ANNOTATE_RESET_STATS() do { } while(0)
     64 #endif
     65 #ifndef ANNOTATE_PRINT_STATS
     66 #define ANNOTATE_PRINT_STATS() do { } while(0)
     67 #endif
     68 #ifndef ANNOTATE_PRINT_MEMORY_USAGE
     69 #define ANNOTATE_PRINT_MEMORY_USAGE(a) do { } while(0)
     70 #endif
     71 //
     72 
     73 // A function that allows to suppress gcc's warnings about
     74 // unused return values in a portable way.
     75 template <typename T>
     76 static inline void IGNORE_RETURN_VALUE(T v)
     77 { }
     78 
     79 #include <vector>
     80 #include <string>
     81 #include <map>
     82 #include <queue>
     83 #include <algorithm>
     84 #include <cstring>      // strlen(), index(), rindex()
     85 #include <ctime>
     86 #include <sys/time.h>
     87 #include <sys/types.h>
     88 #include <sys/stat.h>
     89 #include <fcntl.h>
     90 #include <sys/mman.h>  // mmap
     91 #include <errno.h>
     92 #include <stdint.h>    // uintptr_t
     93 #include <stdlib.h>
     94 #include <dirent.h>
     95 
     96 #ifndef __APPLE__
     97 #include <malloc.h>
     98 #endif
     99 
    100 // The tests are
    101 // - Stability tests (marked STAB)
    102 // - Performance tests (marked PERF)
    103 // - Feature tests
    104 //   - TN (true negative) : no race exists and the tool is silent.
    105 //   - TP (true positive) : a race exists and reported.
    106 //   - FN (false negative): a race exists but not reported.
    107 //   - FP (false positive): no race exists but the tool reports it.
    108 //
    109 // The feature tests are marked according to the behavior of helgrind 3.3.0.
    110 //
    111 // TP and FP tests are annotated with ANNOTATE_EXPECT_RACE,
    112 // so, no error reports should be seen when running under helgrind.
    113 //
    114 // When some of the FP cases are fixed in helgrind we'll need
    115 // to update this test.
    116 //
    117 // Each test resides in its own namespace.
    118 // Namespaces are named test01, test02, ...
    119 // Please, *DO NOT* change the logic of existing tests nor rename them.
    120 // Create a new test instead.
    121 //
    122 // Some tests use sleep()/usleep().
    123 // This is not a synchronization, but a simple way to trigger
    124 // some specific behaviour of the race detector's scheduler.
    125 
    126 // Globals and utilities used by several tests. {{{1
    127 CondVar CV;
    128 int     COND = 0;
    129 
    130 
    131 typedef void (*void_func_void_t)(void);
    132 enum TEST_FLAG {
    133   FEATURE           = 1 << 0,
    134   STABILITY         = 1 << 1,
    135   PERFORMANCE       = 1 << 2,
    136   EXCLUDE_FROM_ALL  = 1 << 3,
    137   NEEDS_ANNOTATIONS = 1 << 4,
    138   RACE_DEMO         = 1 << 5,
    139   MEMORY_USAGE      = 1 << 6,
    140   PRINT_STATS       = 1 << 7
    141 };
    142 
    143 // Put everything into stderr.
    144 Mutex printf_mu;
    145 #define printf(args...) \
    146     do{ \
    147       printf_mu.Lock();\
    148       fprintf(stderr, args);\
    149       printf_mu.Unlock(); \
    150     }while(0)
    151 
    152 long GetTimeInMs() {
    153    struct timeval tv;
    154    gettimeofday(&tv, NULL);
    155    return (tv.tv_sec * 1000L) + (tv.tv_usec / 1000L);
    156 }
    157 
    158 struct Test{
    159   void_func_void_t f_;
    160   int flags_;
    161   Test(void_func_void_t f, int flags)
    162     : f_(f)
    163     , flags_(flags)
    164   {}
    165   Test() : f_(0), flags_(0) {}
    166   void Run() {
    167      ANNOTATE_RESET_STATS();
    168      if (flags_ & PERFORMANCE) {
    169         long start = GetTimeInMs();
    170         f_();
    171         long end = GetTimeInMs();
    172         printf ("Time: %4ldms\n", end-start);
    173      } else
    174         f_();
    175      if (flags_ & PRINT_STATS)
    176         ANNOTATE_PRINT_STATS();
    177      if (flags_ & MEMORY_USAGE)
    178         ANNOTATE_PRINT_MEMORY_USAGE(0);
    179   }
    180 };
    181 std::map<int, Test> TheMapOfTests;
    182 
    183 #define NOINLINE __attribute__ ((noinline))
    184 extern "C" void NOINLINE AnnotateSetVerbosity(const char *, int, int) {};
    185 
    186 
    187 struct TestAdder {
    188   TestAdder(void_func_void_t f, int id, int flags = FEATURE) {
    189     // AnnotateSetVerbosity(__FILE__, __LINE__, 0);
    190     CHECK(TheMapOfTests.count(id) == 0);
    191     TheMapOfTests[id] = Test(f, flags);
    192   }
    193 };
    194 
    195 #define REGISTER_TEST(f, id)         TestAdder add_test_##id (f, id);
    196 #define REGISTER_TEST2(f, id, flags) TestAdder add_test_##id (f, id, flags);
    197 
    198 static bool ArgIsOne(int *arg) { return *arg == 1; };
    199 static bool ArgIsZero(int *arg) { return *arg == 0; };
    200 static bool ArgIsTrue(bool *arg) { return *arg == true; };
    201 
    202 // Call ANNOTATE_EXPECT_RACE only if 'machine' env variable is defined.
    203 // Useful to test against several different machines.
    204 // Supported machines so far:
    205 //   MSM_HYBRID1             -- aka MSMProp1
    206 //   MSM_HYBRID1_INIT_STATE  -- aka MSMProp1 with --initialization-state=yes
    207 //   MSM_THREAD_SANITIZER    -- ThreadSanitizer's state machine
    208 #define ANNOTATE_EXPECT_RACE_FOR_MACHINE(mem, descr, machine) \
    209     while(getenv(machine)) {\
    210       ANNOTATE_EXPECT_RACE(mem, descr); \
    211       break;\
    212     }\
    213 
    214 #define ANNOTATE_EXPECT_RACE_FOR_TSAN(mem, descr) \
    215     ANNOTATE_EXPECT_RACE_FOR_MACHINE(mem, descr, "MSM_THREAD_SANITIZER")
    216 
    217 inline bool Tsan_PureHappensBefore() {
    218   return true;
    219 }
    220 
    221 inline bool Tsan_FastMode()           {
    222   return getenv("TSAN_FAST_MODE") != NULL;
    223 }
    224 
    225 // Initialize *(mem) to 0 if Tsan_FastMode.
    226 #define FAST_MODE_INIT(mem) do { if (Tsan_FastMode()) { *(mem) = 0; } } while(0)
    227 
    228 #ifndef MAIN_INIT_ACTION
    229 #define MAIN_INIT_ACTION
    230 #endif
    231 
    232 
    233 
    234 int main(int argc, char** argv) { // {{{1
    235   MAIN_INIT_ACTION;
    236   printf("FLAGS [phb=%i, fm=%i]\n", Tsan_PureHappensBefore(), Tsan_FastMode());
    237   if (argc == 2 && !strcmp(argv[1], "benchmark")) {
    238      for (std::map<int,Test>::iterator it = TheMapOfTests.begin();
    239          it != TheMapOfTests.end(); ++it) {
    240        if(!(it->second.flags_ & PERFORMANCE)) continue;
    241        it->second.Run();
    242      }
    243   } else if (argc == 2 && !strcmp(argv[1], "demo")) {
    244      for (std::map<int,Test>::iterator it = TheMapOfTests.begin();
    245          it != TheMapOfTests.end();  ++it) {
    246        if(!(it->second.flags_ & RACE_DEMO)) continue;
    247        it->second.Run();
    248      }
    249   } else if (argc > 1) {
    250     // the tests are listed in command line flags
    251     for (int i = 1; i < argc; i++) {
    252       int f_num = atoi(argv[i]);
    253       CHECK(TheMapOfTests.count(f_num));
    254       TheMapOfTests[f_num].Run();
    255     }
    256   } else {
    257     bool run_tests_with_annotations = false;
    258     if (getenv("DRT_ALLOW_ANNOTATIONS")) {
    259       run_tests_with_annotations = true;
    260     }
    261     for (std::map<int,Test>::iterator it = TheMapOfTests.begin();
    262         it != TheMapOfTests.end();
    263         ++it) {
    264       if(it->second.flags_ & EXCLUDE_FROM_ALL) continue;
    265       if(it->second.flags_ & RACE_DEMO) continue;
    266       if((it->second.flags_ & NEEDS_ANNOTATIONS)
    267          && run_tests_with_annotations == false) continue;
    268       it->second.Run();
    269     }
    270   }
    271 }
    272 
    273 #ifdef THREAD_WRAPPERS_PTHREAD_H
    274 #endif
    275 
    276 
    277 // An array of threads. Create/start/join all elements at once. {{{1
    278 class MyThreadArray {
    279  public:
    280   static const int kSize = 5;
    281   typedef void (*F) (void);
    282   MyThreadArray(F f1, F f2 = NULL, F f3 = NULL, F f4 = NULL, F f5 = NULL) {
    283     ar_[0] = new MyThread(f1);
    284     ar_[1] = f2 ? new MyThread(f2) : NULL;
    285     ar_[2] = f3 ? new MyThread(f3) : NULL;
    286     ar_[3] = f4 ? new MyThread(f4) : NULL;
    287     ar_[4] = f5 ? new MyThread(f5) : NULL;
    288   }
    289   void Start() {
    290     for(int i = 0; i < kSize; i++) {
    291       if(ar_[i]) {
    292         ar_[i]->Start();
    293         usleep(10);
    294       }
    295     }
    296   }
    297 
    298   void Join() {
    299     for(int i = 0; i < kSize; i++) {
    300       if(ar_[i]) {
    301         ar_[i]->Join();
    302       }
    303     }
    304   }
    305 
    306   ~MyThreadArray() {
    307     for(int i = 0; i < kSize; i++) {
    308       delete ar_[i];
    309     }
    310   }
    311  private:
    312   MyThread *ar_[kSize];
    313 };
    314 
    315 
    316 
    317 // test00: {{{1
    318 namespace test00 {
    319 int     GLOB = 0;
    320 void Run() {
    321   printf("test00: negative\n");
    322   printf("\tGLOB=%d\n", GLOB);
    323 }
    324 REGISTER_TEST(Run, 00)
    325 }  // namespace test00
    326 
    327 
    328 // test01: TP. Simple race (write vs write). {{{1
    329 namespace test01 {
    330 int     GLOB = 0;
    331 void Worker() {
    332   GLOB = 1;
    333 }
    334 
    335 void Parent() {
    336   MyThread t(Worker);
    337   t.Start();
    338   GLOB = 2;
    339   t.Join();
    340 }
    341 void Run() {
    342   FAST_MODE_INIT(&GLOB);
    343   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test01. TP.");
    344   ANNOTATE_TRACE_MEMORY(&GLOB);
    345   printf("test01: positive\n");
    346   Parent();
    347   const int tmp = GLOB;
    348   printf("\tGLOB=%d\n", tmp);
    349 }
    350 REGISTER_TEST(Run, 1);
    351 }  // namespace test01
    352 
    353 
    354 // test02: TN. Synchronization via CondVar. {{{1
    355 namespace test02 {
    356 int     GLOB = 0;
    357 // Two write accesses to GLOB are synchronized because
    358 // the pair of CV.Signal() and CV.Wait() establish happens-before relation.
    359 //
    360 // Waiter:                      Waker:
    361 // 1. COND = 0
    362 // 2. Start(Waker)
    363 // 3. MU.Lock()                 a. write(GLOB)
    364 //                              b. MU.Lock()
    365 //                              c. COND = 1
    366 //                         /--- d. CV.Signal()
    367 //  4. while(COND)        /     e. MU.Unlock()
    368 //       CV.Wait(MU) <---/
    369 //  5. MU.Unlock()
    370 //  6. write(GLOB)
    371 Mutex   MU;
    372 
    373 void Waker() {
    374   usleep(100000);  // Make sure the waiter blocks.
    375   GLOB = 1;
    376 
    377   MU.Lock();
    378   COND = 1;
    379   CV.Signal();
    380   MU.Unlock();
    381 }
    382 
    383 void Waiter() {
    384   ThreadPool pool(1);
    385   pool.StartWorkers();
    386   COND = 0;
    387   pool.Add(NewCallback(Waker));
    388   MU.Lock();
    389   while(COND != 1)
    390     CV.Wait(&MU);
    391   MU.Unlock();
    392   GLOB = 2;
    393 }
    394 void Run() {
    395   printf("test02: negative\n");
    396   Waiter();
    397   printf("\tGLOB=%d\n", GLOB);
    398 }
    399 REGISTER_TEST(Run, 2);
    400 }  // namespace test02
    401 
    402 
    403 // test03: TN. Synchronization via LockWhen, signaller gets there first. {{{1
    404 namespace test03 {
    405 int     GLOB = 0;
    406 // Two write accesses to GLOB are synchronized via conditional critical section.
    407 // Note that LockWhen() happens first (we use sleep(1) to make sure)!
    408 //
    409 // Waiter:                           Waker:
    410 // 1. COND = 0
    411 // 2. Start(Waker)
    412 //                                   a. write(GLOB)
    413 //                                   b. MU.Lock()
    414 //                                   c. COND = 1
    415 //                              /--- d. MU.Unlock()
    416 // 3. MU.LockWhen(COND==1) <---/
    417 // 4. MU.Unlock()
    418 // 5. write(GLOB)
    419 Mutex   MU;
    420 
    421 void Waker() {
    422   usleep(100000);  // Make sure the waiter blocks.
    423   GLOB = 1;
    424 
    425   MU.Lock();
    426   COND = 1; // We are done! Tell the Waiter.
    427   MU.Unlock(); // calls ANNOTATE_CONDVAR_SIGNAL;
    428 }
    429 void Waiter() {
    430   ThreadPool pool(1);
    431   pool.StartWorkers();
    432   COND = 0;
    433   pool.Add(NewCallback(Waker));
    434   MU.LockWhen(Condition(&ArgIsOne, &COND));  // calls ANNOTATE_CONDVAR_WAIT
    435   MU.Unlock();  // Waker is done!
    436 
    437   GLOB = 2;
    438 }
    439 void Run() {
    440   printf("test03: negative\n");
    441   Waiter();
    442   printf("\tGLOB=%d\n", GLOB);
    443 }
    444 REGISTER_TEST2(Run, 3, FEATURE|NEEDS_ANNOTATIONS);
    445 }  // namespace test03
    446 
    447 // test04: TN. Synchronization via PCQ. {{{1
    448 namespace test04 {
    449 int     GLOB = 0;
    450 ProducerConsumerQueue Q(INT_MAX);
    451 // Two write accesses to GLOB are separated by PCQ Put/Get.
    452 //
    453 // Putter:                        Getter:
    454 // 1. write(GLOB)
    455 // 2. Q.Put() ---------\          .
    456 //                      \-------> a. Q.Get()
    457 //                                b. write(GLOB)
    458 
    459 
    460 void Putter() {
    461   GLOB = 1;
    462   Q.Put(NULL);
    463 }
    464 
    465 void Getter() {
    466   Q.Get();
    467   GLOB = 2;
    468 }
    469 
    470 void Run() {
    471   printf("test04: negative\n");
    472   MyThreadArray t(Putter, Getter);
    473   t.Start();
    474   t.Join();
    475   printf("\tGLOB=%d\n", GLOB);
    476 }
    477 REGISTER_TEST(Run, 4);
    478 }  // namespace test04
    479 
    480 
    481 // test05: FP. Synchronization via CondVar, but waiter does not block. {{{1
    482 // Since CondVar::Wait() is not called, we get a false positive.
    483 namespace test05 {
    484 int     GLOB = 0;
    485 // Two write accesses to GLOB are synchronized via CondVar.
    486 // But race detector can not see it.
    487 // See this for details:
    488 // http://www.valgrind.org/docs/manual/hg-manual.html#hg-manual.effective-use.
    489 //
    490 // Waiter:                                  Waker:
    491 // 1. COND = 0
    492 // 2. Start(Waker)
    493 // 3. MU.Lock()                             a. write(GLOB)
    494 //                                          b. MU.Lock()
    495 //                                          c. COND = 1
    496 //                                          d. CV.Signal()
    497 //  4. while(COND)                          e. MU.Unlock()
    498 //       CV.Wait(MU) <<< not called
    499 //  5. MU.Unlock()
    500 //  6. write(GLOB)
    501 Mutex   MU;
    502 
    503 void Waker() {
    504   GLOB = 1;
    505   MU.Lock();
    506   COND = 1;
    507   CV.Signal();
    508   MU.Unlock();
    509 }
    510 
    511 void Waiter() {
    512   ThreadPool pool(1);
    513   pool.StartWorkers();
    514   COND = 0;
    515   pool.Add(NewCallback(Waker));
    516   usleep(100000);  // Make sure the signaller gets first.
    517   MU.Lock();
    518   while(COND != 1)
    519     CV.Wait(&MU);
    520   MU.Unlock();
    521   GLOB = 2;
    522 }
    523 void Run() {
    524   FAST_MODE_INIT(&GLOB);
    525   if (!Tsan_PureHappensBefore())
    526     ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test05. FP. Unavoidable in hybrid scheme.");
    527   printf("test05: unavoidable false positive\n");
    528   Waiter();
    529   printf("\tGLOB=%d\n", GLOB);
    530 }
    531 REGISTER_TEST(Run, 5);
    532 }  // namespace test05
    533 
    534 
    535 // test06: TN. Synchronization via CondVar, but Waker gets there first.  {{{1
    536 namespace test06 {
    537 int     GLOB = 0;
    538 // Same as test05 but we annotated the Wait() loop.
    539 //
    540 // Waiter:                                            Waker:
    541 // 1. COND = 0
    542 // 2. Start(Waker)
    543 // 3. MU.Lock()                                       a. write(GLOB)
    544 //                                                    b. MU.Lock()
    545 //                                                    c. COND = 1
    546 //                                           /------- d. CV.Signal()
    547 //  4. while(COND)                          /         e. MU.Unlock()
    548 //       CV.Wait(MU) <<< not called        /
    549 //  6. ANNOTATE_CONDVAR_WAIT(CV, MU) <----/
    550 //  5. MU.Unlock()
    551 //  6. write(GLOB)
    552 
    553 Mutex   MU;
    554 
    555 void Waker() {
    556   GLOB = 1;
    557   MU.Lock();
    558   COND = 1;
    559   CV.Signal();
    560   MU.Unlock();
    561 }
    562 
    563 void Waiter() {
    564   ThreadPool pool(1);
    565   pool.StartWorkers();
    566   COND = 0;
    567   pool.Add(NewCallback(Waker));
    568   usleep(100000);  // Make sure the signaller gets first.
    569   MU.Lock();
    570   while(COND != 1)
    571     CV.Wait(&MU);
    572   ANNOTATE_CONDVAR_LOCK_WAIT(&CV, &MU);
    573 
    574   MU.Unlock();
    575   GLOB = 2;
    576 }
    577 void Run() {
    578   printf("test06: negative\n");
    579   Waiter();
    580   printf("\tGLOB=%d\n", GLOB);
    581 }
    582 REGISTER_TEST2(Run, 6, FEATURE|NEEDS_ANNOTATIONS);
    583 }  // namespace test06
    584 
    585 
    586 // test07: TN. Synchronization via LockWhen(), Signaller is observed first. {{{1
    587 namespace test07 {
    588 int     GLOB = 0;
    589 bool    COND = 0;
    590 // Two write accesses to GLOB are synchronized via conditional critical section.
    591 // LockWhen() is observed after COND has been set (due to sleep).
    592 // Unlock() calls ANNOTATE_CONDVAR_SIGNAL().
    593 //
    594 // Waiter:                           Signaller:
    595 // 1. COND = 0
    596 // 2. Start(Signaller)
    597 //                                   a. write(GLOB)
    598 //                                   b. MU.Lock()
    599 //                                   c. COND = 1
    600 //                              /--- d. MU.Unlock calls ANNOTATE_CONDVAR_SIGNAL
    601 // 3. MU.LockWhen(COND==1) <---/
    602 // 4. MU.Unlock()
    603 // 5. write(GLOB)
    604 
    605 Mutex   MU;
    606 void Signaller() {
    607   GLOB = 1;
    608   MU.Lock();
    609   COND = true; // We are done! Tell the Waiter.
    610   MU.Unlock(); // calls ANNOTATE_CONDVAR_SIGNAL;
    611 }
    612 void Waiter() {
    613   COND = false;
    614   MyThread t(Signaller);
    615   t.Start();
    616   usleep(100000);  // Make sure the signaller gets there first.
    617 
    618   MU.LockWhen(Condition(&ArgIsTrue, &COND));  // calls ANNOTATE_CONDVAR_WAIT
    619   MU.Unlock();  // Signaller is done!
    620 
    621   GLOB = 2; // If LockWhen didn't catch the signal, a race may be reported here.
    622   t.Join();
    623 }
    624 void Run() {
    625   printf("test07: negative\n");
    626   Waiter();
    627   printf("\tGLOB=%d\n", GLOB);
    628 }
    629 REGISTER_TEST2(Run, 7, FEATURE|NEEDS_ANNOTATIONS);
    630 }  // namespace test07
    631 
    632 // test08: TN. Synchronization via thread start/join. {{{1
    633 namespace test08 {
    634 int     GLOB = 0;
    635 // Three accesses to GLOB are separated by thread start/join.
    636 //
    637 // Parent:                        Worker:
    638 // 1. write(GLOB)
    639 // 2. Start(Worker) ------------>
    640 //                                a. write(GLOB)
    641 // 3. Join(Worker) <------------
    642 // 4. write(GLOB)
    643 void Worker() {
    644   GLOB = 2;
    645 }
    646 
    647 void Parent() {
    648   MyThread t(Worker);
    649   GLOB = 1;
    650   t.Start();
    651   t.Join();
    652   GLOB = 3;
    653 }
    654 void Run() {
    655   printf("test08: negative\n");
    656   Parent();
    657   printf("\tGLOB=%d\n", GLOB);
    658 }
    659 REGISTER_TEST(Run, 8);
    660 }  // namespace test08
    661 
    662 
    663 // test09: TP. Simple race (read vs write). {{{1
    664 namespace test09 {
    665 int     GLOB = 0;
    666 // A simple data race between writer and reader.
    667 // Write happens after read (enforced by sleep).
    668 // Usually, easily detectable by a race detector.
    669 void Writer() {
    670   usleep(100000);
    671   GLOB = 3;
    672 }
    673 void Reader() {
    674   CHECK(GLOB != -777);
    675 }
    676 
    677 void Run() {
    678   ANNOTATE_TRACE_MEMORY(&GLOB);
    679   FAST_MODE_INIT(&GLOB);
    680   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test09. TP.");
    681   printf("test09: positive\n");
    682   MyThreadArray t(Writer, Reader);
    683   t.Start();
    684   t.Join();
    685   printf("\tGLOB=%d\n", GLOB);
    686 }
    687 REGISTER_TEST(Run, 9);
    688 }  // namespace test09
    689 
    690 
    691 // test10: FN. Simple race (write vs read). {{{1
    692 namespace test10 {
    693 int     GLOB = 0;
    694 // A simple data race between writer and reader.
    695 // Write happens before Read (enforced by sleep),
    696 // otherwise this test is the same as test09.
    697 //
    698 // Writer:                    Reader:
    699 // 1. write(GLOB)             a. sleep(long enough so that GLOB
    700 //                                is most likely initialized by Writer)
    701 //                            b. read(GLOB)
    702 //
    703 //
    704 // Eraser algorithm does not detect the race here,
    705 // see Section 2.2 of http://citeseer.ist.psu.edu/savage97eraser.html.
    706 //
    707 void Writer() {
    708   GLOB = 3;
    709 }
    710 void Reader() {
    711   usleep(100000);
    712   CHECK(GLOB != -777);
    713 }
    714 
    715 void Run() {
    716   FAST_MODE_INIT(&GLOB);
    717   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test10. TP. FN in MSMHelgrind.");
    718   printf("test10: positive\n");
    719   MyThreadArray t(Writer, Reader);
    720   t.Start();
    721   t.Join();
    722   printf("\tGLOB=%d\n", GLOB);
    723 }
    724 REGISTER_TEST(Run, 10);
    725 }  // namespace test10
    726 
    727 
    728 // test11: FP. Synchronization via CondVar, 2 workers. {{{1
    729 // This test is properly synchronized, but currently (Dec 2007)
    730 // helgrind reports a false positive.
    731 //
    732 // Parent:                              Worker1, Worker2:
    733 // 1. Start(workers)                    a. read(GLOB)
    734 // 2. MU.Lock()                         b. MU.Lock()
    735 // 3. while(COND != 2)        /-------- c. CV.Signal()
    736 //      CV.Wait(&MU) <-------/          d. MU.Unlock()
    737 // 4. MU.Unlock()
    738 // 5. write(GLOB)
    739 //
    740 namespace test11 {
    741 int     GLOB = 0;
    742 Mutex   MU;
    743 void Worker() {
    744   usleep(200000);
    745   CHECK(GLOB != 777);
    746 
    747   MU.Lock();
    748   COND++;
    749   CV.Signal();
    750   MU.Unlock();
    751 }
    752 
    753 void Parent() {
    754   COND = 0;
    755 
    756   MyThreadArray t(Worker, Worker);
    757   t.Start();
    758 
    759   MU.Lock();
    760   while(COND != 2) {
    761     CV.Wait(&MU);
    762   }
    763   MU.Unlock();
    764 
    765   GLOB = 2;
    766 
    767   t.Join();
    768 }
    769 
    770 void Run() {
    771 //  ANNOTATE_EXPECT_RACE(&GLOB, "test11. FP. Fixed by MSMProp1.");
    772   printf("test11: negative\n");
    773   Parent();
    774   printf("\tGLOB=%d\n", GLOB);
    775 }
    776 REGISTER_TEST(Run, 11);
    777 }  // namespace test11
    778 
    779 
    780 // test12: FP. Synchronization via Mutex, then via PCQ. {{{1
    781 namespace test12 {
    782 int     GLOB = 0;
    783 // This test is properly synchronized, but currently (Dec 2007)
    784 // helgrind reports a false positive.
    785 //
    786 // First, we write to GLOB under MU, then we synchronize via PCQ,
    787 // which is essentially a semaphore.
    788 //
    789 // Putter:                       Getter:
    790 // 1. MU.Lock()                  a. MU.Lock()
    791 // 2. write(GLOB) <---- MU ----> b. write(GLOB)
    792 // 3. MU.Unlock()                c. MU.Unlock()
    793 // 4. Q.Put()   ---------------> d. Q.Get()
    794 //                               e. write(GLOB)
    795 
    796 ProducerConsumerQueue Q(INT_MAX);
    797 Mutex   MU;
    798 
    799 void Putter() {
    800   MU.Lock();
    801   GLOB++;
    802   MU.Unlock();
    803 
    804   Q.Put(NULL);
    805 }
    806 
    807 void Getter() {
    808   MU.Lock();
    809   GLOB++;
    810   MU.Unlock();
    811 
    812   Q.Get();
    813   GLOB++;
    814 }
    815 
    816 void Run() {
    817 //  ANNOTATE_EXPECT_RACE(&GLOB, "test12. FP. Fixed by MSMProp1.");
    818   printf("test12: negative\n");
    819   MyThreadArray t(Putter, Getter);
    820   t.Start();
    821   t.Join();
    822   printf("\tGLOB=%d\n", GLOB);
    823 }
    824 REGISTER_TEST(Run, 12);
    825 }  // namespace test12
    826 
    827 
    828 // test13: FP. Synchronization via Mutex, then via LockWhen. {{{1
    829 namespace test13 {
    830 int     GLOB = 0;
    831 // This test is essentially the same as test12, but uses LockWhen
    832 // instead of PCQ.
    833 //
    834 // Waker:                                     Waiter:
    835 // 1. MU.Lock()                               a. MU.Lock()
    836 // 2. write(GLOB) <---------- MU ---------->  b. write(GLOB)
    837 // 3. MU.Unlock()                             c. MU.Unlock()
    838 // 4. MU.Lock()                               .
    839 // 5. COND = 1                                .
    840 // 6. ANNOTATE_CONDVAR_SIGNAL -------\        .
    841 // 7. MU.Unlock()                     \       .
    842 //                                     \----> d. MU.LockWhen(COND == 1)
    843 //                                            e. MU.Unlock()
    844 //                                            f. write(GLOB)
    845 Mutex   MU;
    846 
    847 void Waker() {
    848   MU.Lock();
    849   GLOB++;
    850   MU.Unlock();
    851 
    852   MU.Lock();
    853   COND = 1;
    854   ANNOTATE_CONDVAR_SIGNAL(&MU);
    855   MU.Unlock();
    856 }
    857 
    858 void Waiter() {
    859   MU.Lock();
    860   GLOB++;
    861   MU.Unlock();
    862 
    863   MU.LockWhen(Condition(&ArgIsOne, &COND));
    864   MU.Unlock();
    865   GLOB++;
    866 }
    867 
    868 void Run() {
    869 //  ANNOTATE_EXPECT_RACE(&GLOB, "test13. FP. Fixed by MSMProp1.");
    870   printf("test13: negative\n");
    871   COND = 0;
    872 
    873   MyThreadArray t(Waker, Waiter);
    874   t.Start();
    875   t.Join();
    876 
    877   printf("\tGLOB=%d\n", GLOB);
    878 }
    879 REGISTER_TEST2(Run, 13, FEATURE|NEEDS_ANNOTATIONS);
    880 }  // namespace test13
    881 
    882 
    883 // test14: FP. Synchronization via PCQ, reads, 2 workers. {{{1
    884 namespace test14 {
    885 int     GLOB = 0;
    886 // This test is properly synchronized, but currently (Dec 2007)
    887 // helgrind reports a false positive.
    888 //
    889 // This test is similar to test11, but uses PCQ (semaphore).
    890 //
    891 // Putter2:                  Putter1:                     Getter:
    892 // 1. read(GLOB)             a. read(GLOB)
    893 // 2. Q2.Put() ----\         b. Q1.Put() -----\           .
    894 //                  \                          \--------> A. Q1.Get()
    895 //                   \----------------------------------> B. Q2.Get()
    896 //                                                        C. write(GLOB)
    897 ProducerConsumerQueue Q1(INT_MAX), Q2(INT_MAX);
    898 
    899 void Putter1() {
    900   CHECK(GLOB != 777);
    901   Q1.Put(NULL);
    902 }
    903 void Putter2() {
    904   CHECK(GLOB != 777);
    905   Q2.Put(NULL);
    906 }
    907 void Getter() {
    908   Q1.Get();
    909   Q2.Get();
    910   GLOB++;
    911 }
    912 void Run() {
    913 //  ANNOTATE_EXPECT_RACE(&GLOB, "test14. FP. Fixed by MSMProp1.");
    914   printf("test14: negative\n");
    915   MyThreadArray t(Getter, Putter1, Putter2);
    916   t.Start();
    917   t.Join();
    918   printf("\tGLOB=%d\n", GLOB);
    919 }
    920 REGISTER_TEST(Run, 14);
    921 }  // namespace test14
    922 
    923 
    924 // test15: TN. Synchronization via LockWhen. One waker and 2 waiters. {{{1
    925 namespace test15 {
    926 // Waker:                                   Waiter1, Waiter2:
    927 // 1. write(GLOB)
    928 // 2. MU.Lock()
    929 // 3. COND = 1
    930 // 4. ANNOTATE_CONDVAR_SIGNAL ------------> a. MU.LockWhen(COND == 1)
    931 // 5. MU.Unlock()                           b. MU.Unlock()
    932 //                                          c. read(GLOB)
    933 
    934 int     GLOB = 0;
    935 Mutex   MU;
    936 
    937 void Waker() {
    938   GLOB = 2;
    939 
    940   MU.Lock();
    941   COND = 1;
    942   ANNOTATE_CONDVAR_SIGNAL(&MU);
    943   MU.Unlock();
    944 };
    945 
    946 void Waiter() {
    947   MU.LockWhen(Condition(&ArgIsOne, &COND));
    948   MU.Unlock();
    949   CHECK(GLOB != 777);
    950 }
    951 
    952 
    953 void Run() {
    954   COND = 0;
    955   printf("test15: negative\n");
    956   MyThreadArray t(Waker, Waiter, Waiter);
    957   t.Start();
    958   t.Join();
    959   printf("\tGLOB=%d\n", GLOB);
    960 }
    961 REGISTER_TEST(Run, 15);
    962 }  // namespace test15
    963 
    964 
    965 // test16: FP. Barrier (emulated by CV), 2 threads. {{{1
    966 namespace test16 {
    967 // Worker1:                                     Worker2:
    968 // 1. MU.Lock()                                 a. MU.Lock()
    969 // 2. write(GLOB) <------------ MU ---------->  b. write(GLOB)
    970 // 3. MU.Unlock()                               c. MU.Unlock()
    971 // 4. MU2.Lock()                                d. MU2.Lock()
    972 // 5. COND--                                    e. COND--
    973 // 6. ANNOTATE_CONDVAR_SIGNAL(MU2) ---->V       .
    974 // 7. MU2.Await(COND == 0) <------------+------ f. ANNOTATE_CONDVAR_SIGNAL(MU2)
    975 // 8. MU2.Unlock()                      V-----> g. MU2.Await(COND == 0)
    976 // 9. read(GLOB)                                h. MU2.Unlock()
    977 //                                              i. read(GLOB)
    978 //
    979 //
    980 // TODO: This way we may create too many edges in happens-before graph.
    981 // Arndt Mhlenfeld in his PhD (TODO: link) suggests creating special nodes in
    982 // happens-before graph to reduce the total number of edges.
    983 // See figure 3.14.
    984 //
    985 //
    986 int     GLOB = 0;
    987 Mutex   MU;
    988 Mutex MU2;
    989 
    990 void Worker() {
    991   MU.Lock();
    992   GLOB++;
    993   MU.Unlock();
    994 
    995   MU2.Lock();
    996   COND--;
    997   ANNOTATE_CONDVAR_SIGNAL(&MU2);
    998   MU2.Await(Condition(&ArgIsZero, &COND));
    999   MU2.Unlock();
   1000 
   1001   CHECK(GLOB == 2);
   1002 }
   1003 
   1004 void Run() {
   1005 //  ANNOTATE_EXPECT_RACE(&GLOB, "test16. FP. Fixed by MSMProp1 + Barrier support.");
   1006   COND = 2;
   1007   printf("test16: negative\n");
   1008   MyThreadArray t(Worker, Worker);
   1009   t.Start();
   1010   t.Join();
   1011   printf("\tGLOB=%d\n", GLOB);
   1012 }
   1013 REGISTER_TEST2(Run, 16, FEATURE|NEEDS_ANNOTATIONS);
   1014 }  // namespace test16
   1015 
   1016 
   1017 // test17: FP. Barrier (emulated by CV), 3 threads. {{{1
   1018 namespace test17 {
   1019 // Same as test16, but with 3 threads.
   1020 int     GLOB = 0;
   1021 Mutex   MU;
   1022 Mutex MU2;
   1023 
   1024 void Worker() {
   1025   MU.Lock();
   1026   GLOB++;
   1027   MU.Unlock();
   1028 
   1029   MU2.Lock();
   1030   COND--;
   1031   ANNOTATE_CONDVAR_SIGNAL(&MU2);
   1032   MU2.Await(Condition(&ArgIsZero, &COND));
   1033   MU2.Unlock();
   1034 
   1035   CHECK(GLOB == 3);
   1036 }
   1037 
   1038 void Run() {
   1039 //  ANNOTATE_EXPECT_RACE(&GLOB, "test17. FP. Fixed by MSMProp1 + Barrier support.");
   1040   COND = 3;
   1041   printf("test17: negative\n");
   1042   MyThreadArray t(Worker, Worker, Worker);
   1043   t.Start();
   1044   t.Join();
   1045   printf("\tGLOB=%d\n", GLOB);
   1046 }
   1047 REGISTER_TEST2(Run, 17, FEATURE|NEEDS_ANNOTATIONS);
   1048 }  // namespace test17
   1049 
   1050 
   1051 // test18: TN. Synchronization via Await(), signaller gets there first. {{{1
   1052 namespace test18 {
   1053 int     GLOB = 0;
   1054 Mutex   MU;
   1055 // Same as test03, but uses Mutex::Await() instead of Mutex::LockWhen().
   1056 
   1057 void Waker() {
   1058   usleep(100000);  // Make sure the waiter blocks.
   1059   GLOB = 1;
   1060 
   1061   MU.Lock();
   1062   COND = 1; // We are done! Tell the Waiter.
   1063   MU.Unlock(); // calls ANNOTATE_CONDVAR_SIGNAL;
   1064 }
   1065 void Waiter() {
   1066   ThreadPool pool(1);
   1067   pool.StartWorkers();
   1068   COND = 0;
   1069   pool.Add(NewCallback(Waker));
   1070 
   1071   MU.Lock();
   1072   MU.Await(Condition(&ArgIsOne, &COND));  // calls ANNOTATE_CONDVAR_WAIT
   1073   MU.Unlock();  // Waker is done!
   1074 
   1075   GLOB = 2;
   1076 }
   1077 void Run() {
   1078   printf("test18: negative\n");
   1079   Waiter();
   1080   printf("\tGLOB=%d\n", GLOB);
   1081 }
   1082 REGISTER_TEST2(Run, 18, FEATURE|NEEDS_ANNOTATIONS);
   1083 }  // namespace test18
   1084 
   1085 // test19: TN. Synchronization via AwaitWithTimeout(). {{{1
   1086 namespace test19 {
   1087 int     GLOB = 0;
   1088 // Same as test18, but with AwaitWithTimeout. Do not timeout.
   1089 Mutex   MU;
   1090 void Waker() {
   1091   usleep(100000);  // Make sure the waiter blocks.
   1092   GLOB = 1;
   1093 
   1094   MU.Lock();
   1095   COND = 1; // We are done! Tell the Waiter.
   1096   MU.Unlock(); // calls ANNOTATE_CONDVAR_SIGNAL;
   1097 }
   1098 void Waiter() {
   1099   ThreadPool pool(1);
   1100   pool.StartWorkers();
   1101   COND = 0;
   1102   pool.Add(NewCallback(Waker));
   1103 
   1104   MU.Lock();
   1105   CHECK(MU.AwaitWithTimeout(Condition(&ArgIsOne, &COND), INT_MAX));
   1106   MU.Unlock();
   1107 
   1108   GLOB = 2;
   1109 }
   1110 void Run() {
   1111   printf("test19: negative\n");
   1112   Waiter();
   1113   printf("\tGLOB=%d\n", GLOB);
   1114 }
   1115 REGISTER_TEST2(Run, 19, FEATURE|NEEDS_ANNOTATIONS);
   1116 }  // namespace test19
   1117 
   1118 // test20: TP. Incorrect synchronization via AwaitWhen(), timeout. {{{1
   1119 namespace test20 {
   1120 int     GLOB = 0;
   1121 Mutex   MU;
   1122 // True race. We timeout in AwaitWhen.
   1123 void Waker() {
   1124   GLOB = 1;
   1125   usleep(100 * 1000);
   1126 }
   1127 void Waiter() {
   1128   ThreadPool pool(1);
   1129   pool.StartWorkers();
   1130   COND = 0;
   1131   pool.Add(NewCallback(Waker));
   1132 
   1133   MU.Lock();
   1134   CHECK(!MU.AwaitWithTimeout(Condition(&ArgIsOne, &COND), 100));
   1135   MU.Unlock();
   1136 
   1137   GLOB = 2;
   1138 }
   1139 void Run() {
   1140   FAST_MODE_INIT(&GLOB);
   1141   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test20. TP.");
   1142   printf("test20: positive\n");
   1143   Waiter();
   1144   printf("\tGLOB=%d\n", GLOB);
   1145 }
   1146 REGISTER_TEST2(Run, 20, FEATURE|NEEDS_ANNOTATIONS);
   1147 }  // namespace test20
   1148 
   1149 // test21: TP. Incorrect synchronization via LockWhenWithTimeout(). {{{1
   1150 namespace test21 {
   1151 int     GLOB = 0;
   1152 // True race. We timeout in LockWhenWithTimeout().
   1153 Mutex   MU;
   1154 void Waker() {
   1155   GLOB = 1;
   1156   usleep(100 * 1000);
   1157 }
   1158 void Waiter() {
   1159   ThreadPool pool(1);
   1160   pool.StartWorkers();
   1161   COND = 0;
   1162   pool.Add(NewCallback(Waker));
   1163 
   1164   CHECK(!MU.LockWhenWithTimeout(Condition(&ArgIsOne, &COND), 100));
   1165   MU.Unlock();
   1166 
   1167   GLOB = 2;
   1168 }
   1169 void Run() {
   1170   FAST_MODE_INIT(&GLOB);
   1171   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test21. TP.");
   1172   printf("test21: positive\n");
   1173   Waiter();
   1174   printf("\tGLOB=%d\n", GLOB);
   1175 }
   1176 REGISTER_TEST2(Run, 21, FEATURE|NEEDS_ANNOTATIONS);
   1177 }  // namespace test21
   1178 
   1179 // test22: TP. Incorrect synchronization via CondVar::WaitWithTimeout(). {{{1
   1180 namespace test22 {
   1181 int     GLOB = 0;
   1182 Mutex   MU;
   1183 // True race. We timeout in CondVar::WaitWithTimeout().
   1184 void Waker() {
   1185   GLOB = 1;
   1186   usleep(100 * 1000);
   1187 }
   1188 void Waiter() {
   1189   ThreadPool pool(1);
   1190   pool.StartWorkers();
   1191   COND = 0;
   1192   pool.Add(NewCallback(Waker));
   1193 
   1194   int64_t ms_left_to_wait = 100;
   1195   int64_t deadline_ms = GetCurrentTimeMillis() + ms_left_to_wait;
   1196   MU.Lock();
   1197   while(COND != 1 && ms_left_to_wait > 0) {
   1198     CV.WaitWithTimeout(&MU, ms_left_to_wait);
   1199     ms_left_to_wait = deadline_ms - GetCurrentTimeMillis();
   1200   }
   1201   MU.Unlock();
   1202 
   1203   GLOB = 2;
   1204 }
   1205 void Run() {
   1206   FAST_MODE_INIT(&GLOB);
   1207   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test22. TP.");
   1208   printf("test22: positive\n");
   1209   Waiter();
   1210   printf("\tGLOB=%d\n", GLOB);
   1211 }
   1212 REGISTER_TEST(Run, 22);
   1213 }  // namespace test22
   1214 
   1215 // test23: TN. TryLock, ReaderLock, ReaderTryLock. {{{1
   1216 namespace test23 {
   1217 // Correct synchronization with TryLock, Lock, ReaderTryLock, ReaderLock.
   1218 int     GLOB = 0;
   1219 Mutex   MU;
   1220 void Worker_TryLock() {
   1221   for (int i = 0; i < 20; i++) {
   1222     while (true) {
   1223       if (MU.TryLock()) {
   1224         GLOB++;
   1225         MU.Unlock();
   1226         break;
   1227       }
   1228       usleep(1000);
   1229     }
   1230   }
   1231 }
   1232 
   1233 void Worker_ReaderTryLock() {
   1234   for (int i = 0; i < 20; i++) {
   1235     while (true) {
   1236       if (MU.ReaderTryLock()) {
   1237         CHECK(GLOB != 777);
   1238         MU.ReaderUnlock();
   1239         break;
   1240       }
   1241       usleep(1000);
   1242     }
   1243   }
   1244 }
   1245 
   1246 void Worker_ReaderLock() {
   1247   for (int i = 0; i < 20; i++) {
   1248     MU.ReaderLock();
   1249     CHECK(GLOB != 777);
   1250     MU.ReaderUnlock();
   1251     usleep(1000);
   1252   }
   1253 }
   1254 
   1255 void Worker_Lock() {
   1256   for (int i = 0; i < 20; i++) {
   1257     MU.Lock();
   1258     GLOB++;
   1259     MU.Unlock();
   1260     usleep(1000);
   1261   }
   1262 }
   1263 
   1264 void Run() {
   1265   printf("test23: negative\n");
   1266   MyThreadArray t(Worker_TryLock,
   1267                   Worker_ReaderTryLock,
   1268                   Worker_ReaderLock,
   1269                   Worker_Lock
   1270                   );
   1271   t.Start();
   1272   t.Join();
   1273   printf("\tGLOB=%d\n", GLOB);
   1274 }
   1275 REGISTER_TEST(Run, 23);
   1276 }  // namespace test23
   1277 
   1278 // test24: TN. Synchronization via ReaderLockWhen(). {{{1
   1279 namespace test24 {
   1280 int     GLOB = 0;
   1281 Mutex   MU;
   1282 // Same as test03, but uses ReaderLockWhen().
   1283 
   1284 void Waker() {
   1285   usleep(100000);  // Make sure the waiter blocks.
   1286   GLOB = 1;
   1287 
   1288   MU.Lock();
   1289   COND = 1; // We are done! Tell the Waiter.
   1290   MU.Unlock(); // calls ANNOTATE_CONDVAR_SIGNAL;
   1291 }
   1292 void Waiter() {
   1293   ThreadPool pool(1);
   1294   pool.StartWorkers();
   1295   COND = 0;
   1296   pool.Add(NewCallback(Waker));
   1297   MU.ReaderLockWhen(Condition(&ArgIsOne, &COND));
   1298   MU.ReaderUnlock();
   1299 
   1300   GLOB = 2;
   1301 }
   1302 void Run() {
   1303   printf("test24: negative\n");
   1304   Waiter();
   1305   printf("\tGLOB=%d\n", GLOB);
   1306 }
   1307 REGISTER_TEST2(Run, 24, FEATURE|NEEDS_ANNOTATIONS);
   1308 }  // namespace test24
   1309 
   1310 // test25: TN. Synchronization via ReaderLockWhenWithTimeout(). {{{1
   1311 namespace test25 {
   1312 int     GLOB = 0;
   1313 Mutex   MU;
   1314 // Same as test24, but uses ReaderLockWhenWithTimeout().
   1315 // We do not timeout.
   1316 
   1317 void Waker() {
   1318   usleep(100000);  // Make sure the waiter blocks.
   1319   GLOB = 1;
   1320 
   1321   MU.Lock();
   1322   COND = 1; // We are done! Tell the Waiter.
   1323   MU.Unlock(); // calls ANNOTATE_CONDVAR_SIGNAL;
   1324 }
   1325 void Waiter() {
   1326   ThreadPool pool(1);
   1327   pool.StartWorkers();
   1328   COND = 0;
   1329   pool.Add(NewCallback(Waker));
   1330   CHECK(MU.ReaderLockWhenWithTimeout(Condition(&ArgIsOne, &COND), INT_MAX));
   1331   MU.ReaderUnlock();
   1332 
   1333   GLOB = 2;
   1334 }
   1335 void Run() {
   1336   printf("test25: negative\n");
   1337   Waiter();
   1338   printf("\tGLOB=%d\n", GLOB);
   1339 }
   1340 REGISTER_TEST2(Run, 25, FEATURE|NEEDS_ANNOTATIONS);
   1341 }  // namespace test25
   1342 
   1343 // test26: TP. Incorrect synchronization via ReaderLockWhenWithTimeout(). {{{1
   1344 namespace test26 {
   1345 int     GLOB = 0;
   1346 Mutex   MU;
   1347 // Same as test25, but we timeout and incorrectly assume happens-before.
   1348 
   1349 void Waker() {
   1350   GLOB = 1;
   1351   usleep(10000);
   1352 }
   1353 void Waiter() {
   1354   ThreadPool pool(1);
   1355   pool.StartWorkers();
   1356   COND = 0;
   1357   pool.Add(NewCallback(Waker));
   1358   CHECK(!MU.ReaderLockWhenWithTimeout(Condition(&ArgIsOne, &COND), 100));
   1359   MU.ReaderUnlock();
   1360 
   1361   GLOB = 2;
   1362 }
   1363 void Run() {
   1364   FAST_MODE_INIT(&GLOB);
   1365   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test26. TP");
   1366   printf("test26: positive\n");
   1367   Waiter();
   1368   printf("\tGLOB=%d\n", GLOB);
   1369 }
   1370 REGISTER_TEST2(Run, 26, FEATURE|NEEDS_ANNOTATIONS);
   1371 }  // namespace test26
   1372 
   1373 
   1374 // test27: TN. Simple synchronization via SpinLock. {{{1
   1375 namespace test27 {
   1376 #ifndef NO_SPINLOCK
   1377 int     GLOB = 0;
   1378 SpinLock MU;
   1379 void Worker() {
   1380   MU.Lock();
   1381   GLOB++;
   1382   MU.Unlock();
   1383   usleep(10000);
   1384 }
   1385 
   1386 void Run() {
   1387   printf("test27: negative\n");
   1388   MyThreadArray t(Worker, Worker, Worker, Worker);
   1389   t.Start();
   1390   t.Join();
   1391   printf("\tGLOB=%d\n", GLOB);
   1392 }
   1393 REGISTER_TEST2(Run, 27, FEATURE|NEEDS_ANNOTATIONS);
   1394 #endif // NO_SPINLOCK
   1395 }  // namespace test27
   1396 
   1397 
   1398 // test28: TN. Synchronization via Mutex, then PCQ. 3 threads {{{1
   1399 namespace test28 {
   1400 // Putter1:                       Getter:                         Putter2:
   1401 // 1. MU.Lock()                                                   A. MU.Lock()
   1402 // 2. write(GLOB)                                                 B. write(GLOB)
   1403 // 3. MU.Unlock()                                                 C. MU.Unlock()
   1404 // 4. Q.Put() ---------\                                 /------- D. Q.Put()
   1405 // 5. MU.Lock()         \-------> a. Q.Get()            /         E. MU.Lock()
   1406 // 6. read(GLOB)                  b. Q.Get() <---------/          F. read(GLOB)
   1407 // 7. MU.Unlock()                   (sleep)                       G. MU.Unlock()
   1408 //                                c. read(GLOB)
   1409 ProducerConsumerQueue Q(INT_MAX);
   1410 int     GLOB = 0;
   1411 Mutex   MU;
   1412 
   1413 void Putter() {
   1414   MU.Lock();
   1415   GLOB++;
   1416   MU.Unlock();
   1417 
   1418   Q.Put(NULL);
   1419 
   1420   MU.Lock();
   1421   CHECK(GLOB != 777);
   1422   MU.Unlock();
   1423 }
   1424 
   1425 void Getter() {
   1426   Q.Get();
   1427   Q.Get();
   1428   usleep(100000);
   1429   CHECK(GLOB == 2);
   1430 }
   1431 
   1432 void Run() {
   1433   printf("test28: negative\n");
   1434   MyThreadArray t(Getter, Putter, Putter);
   1435   t.Start();
   1436   t.Join();
   1437   printf("\tGLOB=%d\n", GLOB);
   1438 }
   1439 REGISTER_TEST(Run, 28);
   1440 }  // namespace test28
   1441 
   1442 
   1443 // test29: TN. Synchronization via Mutex, then PCQ. 4 threads. {{{1
   1444 namespace test29 {
   1445 // Similar to test28, but has two Getters and two PCQs.
   1446 ProducerConsumerQueue *Q1, *Q2;
   1447 Mutex   MU;
   1448 int     GLOB = 0;
   1449 
   1450 void Putter(ProducerConsumerQueue *q) {
   1451   MU.Lock();
   1452   GLOB++;
   1453   MU.Unlock();
   1454 
   1455   q->Put(NULL);
   1456   q->Put(NULL);
   1457 
   1458   MU.Lock();
   1459   CHECK(GLOB != 777);
   1460   MU.Unlock();
   1461 
   1462 }
   1463 
   1464 void Putter1() { Putter(Q1); }
   1465 void Putter2() { Putter(Q2); }
   1466 
   1467 void Getter() {
   1468   Q1->Get();
   1469   Q2->Get();
   1470   usleep(100000);
   1471   CHECK(GLOB == 2);
   1472   usleep(48000); //  TODO: remove this when FP in test32 is fixed.
   1473 }
   1474 
   1475 void Run() {
   1476   printf("test29: negative\n");
   1477   Q1 = new ProducerConsumerQueue(INT_MAX);
   1478   Q2 = new ProducerConsumerQueue(INT_MAX);
   1479   MyThreadArray t(Getter, Getter, Putter1, Putter2);
   1480   t.Start();
   1481   t.Join();
   1482   printf("\tGLOB=%d\n", GLOB);
   1483   delete Q1;
   1484   delete Q2;
   1485 }
   1486 REGISTER_TEST(Run, 29);
   1487 }  // namespace test29
   1488 
   1489 
   1490 // test30: TN. Synchronization via 'safe' race. Writer vs multiple Readers. {{{1
   1491 namespace test30 {
   1492 // This test shows a very risky kind of synchronization which is very easy
   1493 // to get wrong. Actually, I am not sure I've got it right.
   1494 //
   1495 // Writer:                                 Reader1, Reader2, ..., ReaderN:
   1496 // 1. write(GLOB[i]: i >= BOUNDARY)        a. n = BOUNDARY
   1497 // 2. HAPPENS_BEFORE(BOUNDARY+1)  -------> b. HAPPENS_AFTER(n)
   1498 // 3. BOUNDARY++;                          c. read(GLOB[i]: i < n)
   1499 //
   1500 // Here we have a 'safe' race on accesses to BOUNDARY and
   1501 // no actual races on accesses to GLOB[]:
   1502 // Writer writes to GLOB[i] where i>=BOUNDARY and then increments BOUNDARY.
   1503 // Readers read BOUNDARY and read GLOB[i] where i<BOUNDARY.
   1504 //
   1505 // I am not completely sure that this scheme guaranties no race between
   1506 // accesses to GLOB since compilers and CPUs
   1507 // are free to rearrange memory operations.
   1508 // I am actually sure that this scheme is wrong unless we use
   1509 // some smart memory fencing...
   1510 
   1511 
   1512 const int N = 48;
   1513 static int GLOB[N];
   1514 volatile int BOUNDARY = 0;
   1515 
   1516 void Writer() {
   1517   for (int i = 0; i < N; i++) {
   1518     CHECK(BOUNDARY == i);
   1519     for (int j = i; j < N; j++) {
   1520       GLOB[j] = j;
   1521     }
   1522     ANNOTATE_HAPPENS_BEFORE(reinterpret_cast<void*>(BOUNDARY+1));
   1523     BOUNDARY++;
   1524     usleep(1000);
   1525   }
   1526 }
   1527 
   1528 void Reader() {
   1529   int n;
   1530   do {
   1531     n = BOUNDARY;
   1532     if (n == 0) continue;
   1533     ANNOTATE_HAPPENS_AFTER(reinterpret_cast<void*>(n));
   1534     for (int i = 0; i < n; i++) {
   1535       CHECK(GLOB[i] == i);
   1536     }
   1537     usleep(100);
   1538   } while(n < N);
   1539 }
   1540 
   1541 void Run() {
   1542   FAST_MODE_INIT(&BOUNDARY);
   1543   ANNOTATE_EXPECT_RACE((void*)(&BOUNDARY), "test30. Sync via 'safe' race.");
   1544   printf("test30: negative\n");
   1545   MyThreadArray t(Writer, Reader, Reader, Reader);
   1546   t.Start();
   1547   t.Join();
   1548   printf("\tGLOB=%d\n", GLOB[N-1]);
   1549 }
   1550 REGISTER_TEST2(Run, 30, FEATURE|NEEDS_ANNOTATIONS);
   1551 }  // namespace test30
   1552 
   1553 
   1554 // test31: TN. Synchronization via 'safe' race. Writer vs Writer. {{{1
   1555 namespace test31 {
   1556 // This test is similar to test30, but
   1557 // it has one Writer instead of mulitple Readers.
   1558 //
   1559 // Writer1:                                Writer2
   1560 // 1. write(GLOB[i]: i >= BOUNDARY)        a. n = BOUNDARY
   1561 // 2. HAPPENS_BEFORE(BOUNDARY+1)  -------> b. HAPPENS_AFTER(n)
   1562 // 3. BOUNDARY++;                          c. write(GLOB[i]: i < n)
   1563 //
   1564 
   1565 const int N = 48;
   1566 static int GLOB[N];
   1567 volatile int BOUNDARY = 0;
   1568 
   1569 void Writer1() {
   1570   for (int i = 0; i < N; i++) {
   1571     CHECK(BOUNDARY == i);
   1572     for (int j = i; j < N; j++) {
   1573       GLOB[j] = j;
   1574     }
   1575     ANNOTATE_HAPPENS_BEFORE(reinterpret_cast<void*>(BOUNDARY+1));
   1576     BOUNDARY++;
   1577     usleep(1000);
   1578   }
   1579 }
   1580 
   1581 void Writer2() {
   1582   int n;
   1583   do {
   1584     n = BOUNDARY;
   1585     if (n == 0) continue;
   1586     ANNOTATE_HAPPENS_AFTER(reinterpret_cast<void*>(n));
   1587     for (int i = 0; i < n; i++) {
   1588       if(GLOB[i] == i) {
   1589         GLOB[i]++;
   1590       }
   1591     }
   1592     usleep(100);
   1593   } while(n < N);
   1594 }
   1595 
   1596 void Run() {
   1597   FAST_MODE_INIT(&BOUNDARY);
   1598   ANNOTATE_EXPECT_RACE((void*)(&BOUNDARY), "test31. Sync via 'safe' race.");
   1599   printf("test31: negative\n");
   1600   MyThreadArray t(Writer1, Writer2);
   1601   t.Start();
   1602   t.Join();
   1603   printf("\tGLOB=%d\n", GLOB[N-1]);
   1604 }
   1605 REGISTER_TEST2(Run, 31, FEATURE|NEEDS_ANNOTATIONS);
   1606 }  // namespace test31
   1607 
   1608 
   1609 // test32: FP. Synchronization via thread create/join. W/R. {{{1
   1610 namespace test32 {
   1611 // This test is well synchronized but helgrind 3.3.0 reports a race.
   1612 //
   1613 // Parent:                   Writer:               Reader:
   1614 // 1. Start(Reader) -----------------------\       .
   1615 //                                          \      .
   1616 // 2. Start(Writer) ---\                     \     .
   1617 //                      \---> a. MU.Lock()    \--> A. sleep(long enough)
   1618 //                            b. write(GLOB)
   1619 //                      /---- c. MU.Unlock()
   1620 // 3. Join(Writer) <---/
   1621 //                                                 B. MU.Lock()
   1622 //                                                 C. read(GLOB)
   1623 //                                   /------------ D. MU.Unlock()
   1624 // 4. Join(Reader) <----------------/
   1625 // 5. write(GLOB)
   1626 //
   1627 //
   1628 // The call to sleep() in Reader is not part of synchronization,
   1629 // it is required to trigger the false positive in helgrind 3.3.0.
   1630 //
   1631 int     GLOB = 0;
   1632 Mutex   MU;
   1633 
   1634 void Writer() {
   1635   MU.Lock();
   1636   GLOB = 1;
   1637   MU.Unlock();
   1638 }
   1639 
   1640 void Reader() {
   1641   usleep(480000);
   1642   MU.Lock();
   1643   CHECK(GLOB != 777);
   1644   MU.Unlock();
   1645 }
   1646 
   1647 void Parent() {
   1648   MyThread r(Reader);
   1649   MyThread w(Writer);
   1650   r.Start();
   1651   w.Start();
   1652 
   1653   w.Join();  // 'w' joins first.
   1654   r.Join();
   1655 
   1656   GLOB = 2;
   1657 }
   1658 
   1659 void Run() {
   1660 //  ANNOTATE_EXPECT_RACE(&GLOB, "test32. FP. Fixed by MSMProp1.");
   1661   printf("test32: negative\n");
   1662   Parent();
   1663   printf("\tGLOB=%d\n", GLOB);
   1664 }
   1665 
   1666 REGISTER_TEST(Run, 32);
   1667 }  // namespace test32
   1668 
   1669 
   1670 // test33: STAB. Stress test for the number of thread sets (TSETs). {{{1
   1671 namespace test33 {
   1672 int     GLOB = 0;
   1673 // Here we access N memory locations from within log(N) threads.
   1674 // We do it in such a way that helgrind creates nearly all possible TSETs.
   1675 // Then we join all threads and start again (N_iter times).
   1676 const int N_iter = 48;
   1677 const int Nlog  = 15;
   1678 const int N     = 1 << Nlog;
   1679 static int ARR[N];
   1680 Mutex   MU;
   1681 
   1682 void Worker() {
   1683   MU.Lock();
   1684   int n = ++GLOB;
   1685   MU.Unlock();
   1686 
   1687   n %= Nlog;
   1688   for (int i = 0; i < N; i++) {
   1689     // ARR[i] is accessed by threads from i-th subset
   1690     if (i & (1 << n)) {
   1691         CHECK(ARR[i] == 0);
   1692     }
   1693   }
   1694 }
   1695 
   1696 void Run() {
   1697   printf("test33:\n");
   1698 
   1699   std::vector<MyThread*> vec(Nlog);
   1700 
   1701   for (int j = 0; j < N_iter; j++) {
   1702     // Create and start Nlog threads
   1703     for (int i = 0; i < Nlog; i++) {
   1704       vec[i] = new MyThread(Worker);
   1705     }
   1706     for (int i = 0; i < Nlog; i++) {
   1707       vec[i]->Start();
   1708     }
   1709     // Join all threads.
   1710     for (int i = 0; i < Nlog; i++) {
   1711       vec[i]->Join();
   1712       delete vec[i];
   1713     }
   1714     printf("------------------\n");
   1715   }
   1716 
   1717   printf("\tGLOB=%d; ARR[1]=%d; ARR[7]=%d; ARR[N-1]=%d\n",
   1718          GLOB, ARR[1], ARR[7], ARR[N-1]);
   1719 }
   1720 REGISTER_TEST2(Run, 33, STABILITY|EXCLUDE_FROM_ALL);
   1721 }  // namespace test33
   1722 
   1723 
   1724 // test34: STAB. Stress test for the number of locks sets (LSETs). {{{1
   1725 namespace test34 {
   1726 // Similar to test33, but for lock sets.
   1727 int     GLOB = 0;
   1728 const int N_iter = 48;
   1729 const int Nlog = 10;
   1730 const int N    = 1 << Nlog;
   1731 static int ARR[N];
   1732 static Mutex *MUs[Nlog];
   1733 
   1734 void Worker() {
   1735     for (int i = 0; i < N; i++) {
   1736       // ARR[i] is protected by MUs from i-th subset of all MUs
   1737       for (int j = 0; j < Nlog; j++)  if (i & (1 << j)) MUs[j]->Lock();
   1738       CHECK(ARR[i] == 0);
   1739       for (int j = 0; j < Nlog; j++)  if (i & (1 << j)) MUs[j]->Unlock();
   1740     }
   1741 }
   1742 
   1743 void Run() {
   1744   printf("test34:\n");
   1745   for (int iter = 0; iter < N_iter; iter++) {
   1746     for (int i = 0; i < Nlog; i++) {
   1747       MUs[i] = new Mutex;
   1748     }
   1749     MyThreadArray t(Worker, Worker);
   1750     t.Start();
   1751     t.Join();
   1752     for (int i = 0; i < Nlog; i++) {
   1753       delete MUs[i];
   1754     }
   1755     printf("------------------\n");
   1756   }
   1757   printf("\tGLOB=%d\n", GLOB);
   1758 }
   1759 REGISTER_TEST2(Run, 34, STABILITY|EXCLUDE_FROM_ALL);
   1760 }  // namespace test34
   1761 
   1762 
   1763 // test35: PERF. Lots of mutexes and lots of call to free().  {{{1
   1764 namespace test35 {
   1765 // Helgrind 3.3.0 has very slow in shadow_mem_make_NoAccess(). Fixed locally.
   1766 // With the fix helgrind runs this test about a minute.
   1767 // Without the fix -- about 5 minutes. (on c2d 2.4GHz).
   1768 //
   1769 // TODO: need to figure out the best way for performance testing.
   1770 int **ARR;
   1771 const int N_mu   = 25000;
   1772 const int N_free = 48000;
   1773 
   1774 void Worker() {
   1775   for (int i = 0; i < N_free; i++)
   1776     CHECK(777 == *ARR[i]);
   1777 }
   1778 
   1779 void Run() {
   1780   printf("test35:\n");
   1781   std::vector<Mutex*> mus;
   1782 
   1783   ARR = new int *[N_free];
   1784   for (int i = 0; i < N_free; i++) {
   1785     const int c = N_free / N_mu;
   1786     if ((i % c) == 0) {
   1787       mus.push_back(new Mutex);
   1788       mus.back()->Lock();
   1789       mus.back()->Unlock();
   1790     }
   1791     ARR[i] = new int(777);
   1792   }
   1793 
   1794   // Need to put all ARR[i] into shared state in order
   1795   // to trigger the performance bug.
   1796   MyThreadArray t(Worker, Worker);
   1797   t.Start();
   1798   t.Join();
   1799 
   1800   for (int i = 0; i < N_free; i++) delete ARR[i];
   1801   delete [] ARR;
   1802 
   1803   for (size_t i = 0; i < mus.size(); i++) {
   1804     delete mus[i];
   1805   }
   1806 }
   1807 REGISTER_TEST2(Run, 35, PERFORMANCE|EXCLUDE_FROM_ALL);
   1808 }  // namespace test35
   1809 
   1810 
   1811 // test36: TN. Synchronization via Mutex, then PCQ. 3 threads. W/W {{{1
   1812 namespace test36 {
   1813 // variation of test28 (W/W instead of W/R)
   1814 
   1815 // Putter1:                       Getter:                         Putter2:
   1816 // 1. MU.Lock();                                                  A. MU.Lock()
   1817 // 2. write(GLOB)                                                 B. write(GLOB)
   1818 // 3. MU.Unlock()                                                 C. MU.Unlock()
   1819 // 4. Q.Put() ---------\                                 /------- D. Q.Put()
   1820 // 5. MU1.Lock()        \-------> a. Q.Get()            /         E. MU1.Lock()
   1821 // 6. MU.Lock()                   b. Q.Get() <---------/          F. MU.Lock()
   1822 // 7. write(GLOB)                                                 G. write(GLOB)
   1823 // 8. MU.Unlock()                                                 H. MU.Unlock()
   1824 // 9. MU1.Unlock()                  (sleep)                       I. MU1.Unlock()
   1825 //                                c. MU1.Lock()
   1826 //                                d. write(GLOB)
   1827 //                                e. MU1.Unlock()
   1828 ProducerConsumerQueue Q(INT_MAX);
   1829 int     GLOB = 0;
   1830 Mutex   MU, MU1;
   1831 
   1832 void Putter() {
   1833   MU.Lock();
   1834   GLOB++;
   1835   MU.Unlock();
   1836 
   1837   Q.Put(NULL);
   1838 
   1839   MU1.Lock();
   1840   MU.Lock();
   1841   GLOB++;
   1842   MU.Unlock();
   1843   MU1.Unlock();
   1844 }
   1845 
   1846 void Getter() {
   1847   Q.Get();
   1848   Q.Get();
   1849   usleep(100000);
   1850   MU1.Lock();
   1851   GLOB++;
   1852   MU1.Unlock();
   1853 }
   1854 
   1855 void Run() {
   1856   printf("test36: negative \n");
   1857   MyThreadArray t(Getter, Putter, Putter);
   1858   t.Start();
   1859   t.Join();
   1860   printf("\tGLOB=%d\n", GLOB);
   1861 }
   1862 REGISTER_TEST(Run, 36);
   1863 }  // namespace test36
   1864 
   1865 
   1866 // test37: TN. Simple synchronization (write vs read). {{{1
   1867 namespace test37 {
   1868 int     GLOB = 0;
   1869 Mutex   MU;
   1870 // Similar to test10, but properly locked.
   1871 // Writer:             Reader:
   1872 // 1. MU.Lock()
   1873 // 2. write
   1874 // 3. MU.Unlock()
   1875 //                    a. MU.Lock()
   1876 //                    b. read
   1877 //                    c. MU.Unlock();
   1878 
   1879 void Writer() {
   1880   MU.Lock();
   1881   GLOB = 3;
   1882   MU.Unlock();
   1883 }
   1884 void Reader() {
   1885   usleep(100000);
   1886   MU.Lock();
   1887   CHECK(GLOB != -777);
   1888   MU.Unlock();
   1889 }
   1890 
   1891 void Run() {
   1892   printf("test37: negative\n");
   1893   MyThreadArray t(Writer, Reader);
   1894   t.Start();
   1895   t.Join();
   1896   printf("\tGLOB=%d\n", GLOB);
   1897 }
   1898 REGISTER_TEST(Run, 37);
   1899 }  // namespace test37
   1900 
   1901 
   1902 // test38: TN. Synchronization via Mutexes and PCQ. 4 threads. W/W {{{1
   1903 namespace test38 {
   1904 // Fusion of test29 and test36.
   1905 
   1906 // Putter1:            Putter2:           Getter1:       Getter2:
   1907 //    MU1.Lock()          MU1.Lock()
   1908 //    write(GLOB)         write(GLOB)
   1909 //    MU1.Unlock()        MU1.Unlock()
   1910 //    Q1.Put()            Q2.Put()
   1911 //    Q1.Put()            Q2.Put()
   1912 //    MU1.Lock()          MU1.Lock()
   1913 //    MU2.Lock()          MU2.Lock()
   1914 //    write(GLOB)         write(GLOB)
   1915 //    MU2.Unlock()        MU2.Unlock()
   1916 //    MU1.Unlock()        MU1.Unlock()     sleep          sleep
   1917 //                                         Q1.Get()       Q1.Get()
   1918 //                                         Q2.Get()       Q2.Get()
   1919 //                                         MU2.Lock()     MU2.Lock()
   1920 //                                         write(GLOB)    write(GLOB)
   1921 //                                         MU2.Unlock()   MU2.Unlock()
   1922 //
   1923 
   1924 
   1925 ProducerConsumerQueue *Q1, *Q2;
   1926 int     GLOB = 0;
   1927 Mutex   MU, MU1, MU2;
   1928 
   1929 void Putter(ProducerConsumerQueue *q) {
   1930   MU1.Lock();
   1931   GLOB++;
   1932   MU1.Unlock();
   1933 
   1934   q->Put(NULL);
   1935   q->Put(NULL);
   1936 
   1937   MU1.Lock();
   1938   MU2.Lock();
   1939   GLOB++;
   1940   MU2.Unlock();
   1941   MU1.Unlock();
   1942 
   1943 }
   1944 
   1945 void Putter1() { Putter(Q1); }
   1946 void Putter2() { Putter(Q2); }
   1947 
   1948 void Getter() {
   1949   usleep(100000);
   1950   Q1->Get();
   1951   Q2->Get();
   1952 
   1953   MU2.Lock();
   1954   GLOB++;
   1955   MU2.Unlock();
   1956 
   1957   usleep(48000); //  TODO: remove this when FP in test32 is fixed.
   1958 }
   1959 
   1960 void Run() {
   1961   printf("test38: negative\n");
   1962   Q1 = new ProducerConsumerQueue(INT_MAX);
   1963   Q2 = new ProducerConsumerQueue(INT_MAX);
   1964   MyThreadArray t(Getter, Getter, Putter1, Putter2);
   1965   t.Start();
   1966   t.Join();
   1967   printf("\tGLOB=%d\n", GLOB);
   1968   delete Q1;
   1969   delete Q2;
   1970 }
   1971 REGISTER_TEST(Run, 38);
   1972 }  // namespace test38
   1973 
   1974 // test39: FP. Barrier. {{{1
   1975 namespace test39 {
   1976 #ifndef NO_BARRIER
   1977 // Same as test17 but uses Barrier class (pthread_barrier_t).
   1978 int     GLOB = 0;
   1979 const int N_threads = 3;
   1980 Barrier barrier(N_threads);
   1981 Mutex   MU;
   1982 
   1983 void Worker() {
   1984   MU.Lock();
   1985   GLOB++;
   1986   MU.Unlock();
   1987   barrier.Block();
   1988   CHECK(GLOB == N_threads);
   1989 }
   1990 void Run() {
   1991   ANNOTATE_TRACE_MEMORY(&GLOB);
   1992 //  ANNOTATE_EXPECT_RACE(&GLOB, "test39. FP. Fixed by MSMProp1. Barrier.");
   1993   printf("test39: negative\n");
   1994   {
   1995     ThreadPool pool(N_threads);
   1996     pool.StartWorkers();
   1997     for (int i = 0; i < N_threads; i++) {
   1998       pool.Add(NewCallback(Worker));
   1999     }
   2000   } // all folks are joined here.
   2001   printf("\tGLOB=%d\n", GLOB);
   2002 }
   2003 REGISTER_TEST(Run, 39);
   2004 #endif // NO_BARRIER
   2005 }  // namespace test39
   2006 
   2007 
   2008 // test40: FP. Synchronization via Mutexes and PCQ. 4 threads. W/W {{{1
   2009 namespace test40 {
   2010 // Similar to test38 but with different order of events (due to sleep).
   2011 
   2012 // Putter1:            Putter2:           Getter1:       Getter2:
   2013 //    MU1.Lock()          MU1.Lock()
   2014 //    write(GLOB)         write(GLOB)
   2015 //    MU1.Unlock()        MU1.Unlock()
   2016 //    Q1.Put()            Q2.Put()
   2017 //    Q1.Put()            Q2.Put()
   2018 //                                        Q1.Get()       Q1.Get()
   2019 //                                        Q2.Get()       Q2.Get()
   2020 //                                        MU2.Lock()     MU2.Lock()
   2021 //                                        write(GLOB)    write(GLOB)
   2022 //                                        MU2.Unlock()   MU2.Unlock()
   2023 //
   2024 //    MU1.Lock()          MU1.Lock()
   2025 //    MU2.Lock()          MU2.Lock()
   2026 //    write(GLOB)         write(GLOB)
   2027 //    MU2.Unlock()        MU2.Unlock()
   2028 //    MU1.Unlock()        MU1.Unlock()
   2029 
   2030 
   2031 ProducerConsumerQueue *Q1, *Q2;
   2032 int     GLOB = 0;
   2033 Mutex   MU, MU1, MU2;
   2034 
   2035 void Putter(ProducerConsumerQueue *q) {
   2036   MU1.Lock();
   2037   GLOB++;
   2038   MU1.Unlock();
   2039 
   2040   q->Put(NULL);
   2041   q->Put(NULL);
   2042   usleep(100000);
   2043 
   2044   MU1.Lock();
   2045   MU2.Lock();
   2046   GLOB++;
   2047   MU2.Unlock();
   2048   MU1.Unlock();
   2049 
   2050 }
   2051 
   2052 void Putter1() { Putter(Q1); }
   2053 void Putter2() { Putter(Q2); }
   2054 
   2055 void Getter() {
   2056   Q1->Get();
   2057   Q2->Get();
   2058 
   2059   MU2.Lock();
   2060   GLOB++;
   2061   MU2.Unlock();
   2062 
   2063   usleep(48000); //  TODO: remove this when FP in test32 is fixed.
   2064 }
   2065 
   2066 void Run() {
   2067 //  ANNOTATE_EXPECT_RACE(&GLOB, "test40. FP. Fixed by MSMProp1. Complex Stuff.");
   2068   printf("test40: negative\n");
   2069   Q1 = new ProducerConsumerQueue(INT_MAX);
   2070   Q2 = new ProducerConsumerQueue(INT_MAX);
   2071   MyThreadArray t(Getter, Getter, Putter1, Putter2);
   2072   t.Start();
   2073   t.Join();
   2074   printf("\tGLOB=%d\n", GLOB);
   2075   delete Q1;
   2076   delete Q2;
   2077 }
   2078 REGISTER_TEST(Run, 40);
   2079 }  // namespace test40
   2080 
   2081 // test41: TN. Test for race that appears when loading a dynamic symbol. {{{1
   2082 namespace test41 {
   2083 void Worker() {
   2084   ANNOTATE_NO_OP(NULL); // An empty function, loaded from dll.
   2085 }
   2086 void Run() {
   2087   printf("test41: negative\n");
   2088   MyThreadArray t(Worker, Worker, Worker);
   2089   t.Start();
   2090   t.Join();
   2091 }
   2092 REGISTER_TEST2(Run, 41, FEATURE|NEEDS_ANNOTATIONS);
   2093 }  // namespace test41
   2094 
   2095 
   2096 // test42: TN. Using the same cond var several times. {{{1
   2097 namespace test42 {
   2098 int GLOB = 0;
   2099 int COND = 0;
   2100 int N_threads = 3;
   2101 Mutex   MU;
   2102 
   2103 void Worker1() {
   2104   GLOB=1;
   2105 
   2106   MU.Lock();
   2107   COND = 1;
   2108   CV.Signal();
   2109   MU.Unlock();
   2110 
   2111   MU.Lock();
   2112   while (COND != 0)
   2113     CV.Wait(&MU);
   2114   ANNOTATE_CONDVAR_LOCK_WAIT(&CV, &MU);
   2115   MU.Unlock();
   2116 
   2117   GLOB=3;
   2118 
   2119 }
   2120 
   2121 void Worker2() {
   2122 
   2123   MU.Lock();
   2124   while (COND != 1)
   2125     CV.Wait(&MU);
   2126   ANNOTATE_CONDVAR_LOCK_WAIT(&CV, &MU);
   2127   MU.Unlock();
   2128 
   2129   GLOB=2;
   2130 
   2131   MU.Lock();
   2132   COND = 0;
   2133   CV.Signal();
   2134   MU.Unlock();
   2135 
   2136 }
   2137 
   2138 void Run() {
   2139 //  ANNOTATE_EXPECT_RACE(&GLOB, "test42. TN. debugging.");
   2140   printf("test42: negative\n");
   2141   MyThreadArray t(Worker1, Worker2);
   2142   t.Start();
   2143   t.Join();
   2144   printf("\tGLOB=%d\n", GLOB);
   2145 }
   2146 REGISTER_TEST2(Run, 42, FEATURE|NEEDS_ANNOTATIONS);
   2147 }  // namespace test42
   2148 
   2149 
   2150 
   2151 // test43: TN. {{{1
   2152 namespace test43 {
   2153 //
   2154 // Putter:            Getter:
   2155 // 1. write
   2156 // 2. Q.Put() --\     .
   2157 // 3. read       \--> a. Q.Get()
   2158 //                    b. read
   2159 int     GLOB = 0;
   2160 ProducerConsumerQueue Q(INT_MAX);
   2161 void Putter() {
   2162   GLOB = 1;
   2163   Q.Put(NULL);
   2164   CHECK(GLOB == 1);
   2165 }
   2166 void Getter() {
   2167   Q.Get();
   2168   usleep(100000);
   2169   CHECK(GLOB == 1);
   2170 }
   2171 void Run() {
   2172   printf("test43: negative\n");
   2173   MyThreadArray t(Putter, Getter);
   2174   t.Start();
   2175   t.Join();
   2176   printf("\tGLOB=%d\n", GLOB);
   2177 }
   2178 REGISTER_TEST(Run, 43)
   2179 }  // namespace test43
   2180 
   2181 
   2182 // test44: FP. {{{1
   2183 namespace test44 {
   2184 //
   2185 // Putter:            Getter:
   2186 // 1. read
   2187 // 2. Q.Put() --\     .
   2188 // 3. MU.Lock()  \--> a. Q.Get()
   2189 // 4. write
   2190 // 5. MU.Unlock()
   2191 //                    b. MU.Lock()
   2192 //                    c. write
   2193 //                    d. MU.Unlock();
   2194 int     GLOB = 0;
   2195 Mutex   MU;
   2196 ProducerConsumerQueue Q(INT_MAX);
   2197 void Putter() {
   2198   CHECK(GLOB == 0);
   2199   Q.Put(NULL);
   2200   MU.Lock();
   2201   GLOB = 1;
   2202   MU.Unlock();
   2203 }
   2204 void Getter() {
   2205   Q.Get();
   2206   usleep(100000);
   2207   MU.Lock();
   2208   GLOB = 1;
   2209   MU.Unlock();
   2210 }
   2211 void Run() {
   2212 //  ANNOTATE_EXPECT_RACE(&GLOB, "test44. FP. Fixed by MSMProp1.");
   2213   printf("test44: negative\n");
   2214   MyThreadArray t(Putter, Getter);
   2215   t.Start();
   2216   t.Join();
   2217   printf("\tGLOB=%d\n", GLOB);
   2218 }
   2219 REGISTER_TEST(Run, 44)
   2220 }  // namespace test44
   2221 
   2222 
   2223 // test45: TN. {{{1
   2224 namespace test45 {
   2225 //
   2226 // Putter:            Getter:
   2227 // 1. read
   2228 // 2. Q.Put() --\     .
   2229 // 3. MU.Lock()  \--> a. Q.Get()
   2230 // 4. write
   2231 // 5. MU.Unlock()
   2232 //                    b. MU.Lock()
   2233 //                    c. read
   2234 //                    d. MU.Unlock();
   2235 int     GLOB = 0;
   2236 Mutex   MU;
   2237 ProducerConsumerQueue Q(INT_MAX);
   2238 void Putter() {
   2239   CHECK(GLOB == 0);
   2240   Q.Put(NULL);
   2241   MU.Lock();
   2242   GLOB++;
   2243   MU.Unlock();
   2244 }
   2245 void Getter() {
   2246   Q.Get();
   2247   usleep(100000);
   2248   MU.Lock();
   2249   CHECK(GLOB <= 1);
   2250   MU.Unlock();
   2251 }
   2252 void Run() {
   2253   printf("test45: negative\n");
   2254   MyThreadArray t(Putter, Getter);
   2255   t.Start();
   2256   t.Join();
   2257   printf("\tGLOB=%d\n", GLOB);
   2258 }
   2259 REGISTER_TEST(Run, 45)
   2260 }  // namespace test45
   2261 
   2262 
   2263 // test46: FN. {{{1
   2264 namespace test46 {
   2265 //
   2266 // First:                             Second:
   2267 // 1. write
   2268 // 2. MU.Lock()
   2269 // 3. write
   2270 // 4. MU.Unlock()                      (sleep)
   2271 //                                    a. MU.Lock()
   2272 //                                    b. write
   2273 //                                    c. MU.Unlock();
   2274 int     GLOB = 0;
   2275 Mutex   MU;
   2276 void First() {
   2277   GLOB++;
   2278   MU.Lock();
   2279   GLOB++;
   2280   MU.Unlock();
   2281 }
   2282 void Second() {
   2283   usleep(480000);
   2284   MU.Lock();
   2285   GLOB++;
   2286   MU.Unlock();
   2287 
   2288   // just a print.
   2289   // If we move it to Run()  we will get report in MSMHelgrind
   2290   // due to its false positive (test32).
   2291   MU.Lock();
   2292   printf("\tGLOB=%d\n", GLOB);
   2293   MU.Unlock();
   2294 }
   2295 void Run() {
   2296   ANNOTATE_TRACE_MEMORY(&GLOB);
   2297   MyThreadArray t(First, Second);
   2298   t.Start();
   2299   t.Join();
   2300 }
   2301 REGISTER_TEST(Run, 46)
   2302 }  // namespace test46
   2303 
   2304 
   2305 // test47: TP. Not detected by pure happens-before detectors. {{{1
   2306 namespace test47 {
   2307 // A true race that can not be detected by a pure happens-before
   2308 // race detector.
   2309 //
   2310 // First:                             Second:
   2311 // 1. write
   2312 // 2. MU.Lock()
   2313 // 3. MU.Unlock()                      (sleep)
   2314 //                                    a. MU.Lock()
   2315 //                                    b. MU.Unlock();
   2316 //                                    c. write
   2317 int     GLOB = 0;
   2318 Mutex   MU;
   2319 void First() {
   2320   GLOB=1;
   2321   MU.Lock();
   2322   MU.Unlock();
   2323 }
   2324 void Second() {
   2325   usleep(480000);
   2326   MU.Lock();
   2327   MU.Unlock();
   2328   GLOB++;
   2329 }
   2330 void Run() {
   2331   FAST_MODE_INIT(&GLOB);
   2332   if (!Tsan_PureHappensBefore())
   2333     ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test47. TP. Not detected by pure HB.");
   2334   printf("test47: positive\n");
   2335   MyThreadArray t(First, Second);
   2336   t.Start();
   2337   t.Join();
   2338   printf("\tGLOB=%d\n", GLOB);
   2339 }
   2340 REGISTER_TEST(Run, 47)
   2341 }  // namespace test47
   2342 
   2343 
   2344 // test48: FN. Simple race (single write vs multiple reads). {{{1
   2345 namespace test48 {
   2346 int     GLOB = 0;
   2347 // same as test10 but with single writer and  multiple readers
   2348 // A simple data race between single writer and  multiple readers.
   2349 // Write happens before Reads (enforced by sleep(1)),
   2350 
   2351 //
   2352 // Writer:                    Readers:
   2353 // 1. write(GLOB)             a. sleep(long enough so that GLOB
   2354 //                                is most likely initialized by Writer)
   2355 //                            b. read(GLOB)
   2356 //
   2357 //
   2358 // Eraser algorithm does not detect the race here,
   2359 // see Section 2.2 of http://citeseer.ist.psu.edu/savage97eraser.html.
   2360 //
   2361 void Writer() {
   2362   GLOB = 3;
   2363 }
   2364 void Reader() {
   2365   usleep(100000);
   2366   CHECK(GLOB != -777);
   2367 }
   2368 
   2369 void Run() {
   2370   FAST_MODE_INIT(&GLOB);
   2371   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test48. TP. FN in MSMHelgrind.");
   2372   printf("test48: positive\n");
   2373   MyThreadArray t(Writer, Reader,Reader,Reader);
   2374   t.Start();
   2375   t.Join();
   2376   printf("\tGLOB=%d\n", GLOB);
   2377 }
   2378 REGISTER_TEST(Run, 48)
   2379 }  // namespace test48
   2380 
   2381 
   2382 // test49: FN. Simple race (single write vs multiple reads). {{{1
   2383 namespace test49 {
   2384 int     GLOB = 0;
   2385 // same as test10 but with multiple read operations done by a single reader
   2386 // A simple data race between writer and readers.
   2387 // Write happens before Read (enforced by sleep(1)),
   2388 //
   2389 // Writer:                    Reader:
   2390 // 1. write(GLOB)             a. sleep(long enough so that GLOB
   2391 //                                is most likely initialized by Writer)
   2392 //                            b. read(GLOB)
   2393 //                            c. read(GLOB)
   2394 //                            d. read(GLOB)
   2395 //                            e. read(GLOB)
   2396 //
   2397 //
   2398 // Eraser algorithm does not detect the race here,
   2399 // see Section 2.2 of http://citeseer.ist.psu.edu/savage97eraser.html.
   2400 //
   2401 void Writer() {
   2402   GLOB = 3;
   2403 }
   2404 void Reader() {
   2405   usleep(100000);
   2406   CHECK(GLOB != -777);
   2407   CHECK(GLOB != -777);
   2408   CHECK(GLOB != -777);
   2409   CHECK(GLOB != -777);
   2410 }
   2411 
   2412 void Run() {
   2413   FAST_MODE_INIT(&GLOB);
   2414   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test49. TP. FN in MSMHelgrind.");
   2415   printf("test49: positive\n");
   2416   MyThreadArray t(Writer, Reader);
   2417   t.Start();
   2418   t.Join();
   2419   printf("\tGLOB=%d\n", GLOB);
   2420 }
   2421 REGISTER_TEST(Run, 49);
   2422 }  // namespace test49
   2423 
   2424 
   2425 // test50: TP. Synchronization via CondVar. {{{1
   2426 namespace test50 {
   2427 int     GLOB = 0;
   2428 Mutex   MU;
   2429 // Two last write accesses to GLOB are not synchronized
   2430 //
   2431 // Waiter:                      Waker:
   2432 // 1. COND = 0
   2433 // 2. Start(Waker)
   2434 // 3. MU.Lock()                 a. write(GLOB)
   2435 //                              b. MU.Lock()
   2436 //                              c. COND = 1
   2437 //                         /--- d. CV.Signal()
   2438 //  4. while(COND != 1)   /     e. MU.Unlock()
   2439 //       CV.Wait(MU) <---/
   2440 //  5. MU.Unlock()
   2441 //  6. write(GLOB)              f. MU.Lock()
   2442 //                              g. write(GLOB)
   2443 //                              h. MU.Unlock()
   2444 
   2445 
   2446 void Waker() {
   2447   usleep(100000);  // Make sure the waiter blocks.
   2448 
   2449   GLOB = 1;
   2450 
   2451   MU.Lock();
   2452   COND = 1;
   2453   CV.Signal();
   2454   MU.Unlock();
   2455 
   2456   usleep(100000);
   2457   MU.Lock();
   2458   GLOB = 3;
   2459   MU.Unlock();
   2460 }
   2461 
   2462 void Waiter() {
   2463   ThreadPool pool(1);
   2464   pool.StartWorkers();
   2465   COND = 0;
   2466   pool.Add(NewCallback(Waker));
   2467 
   2468   MU.Lock();
   2469   while(COND != 1)
   2470     CV.Wait(&MU);
   2471   ANNOTATE_CONDVAR_LOCK_WAIT(&CV, &MU);
   2472   MU.Unlock();
   2473 
   2474   GLOB = 2;
   2475 }
   2476 void Run() {
   2477   FAST_MODE_INIT(&GLOB);
   2478   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test50. TP.");
   2479   printf("test50: positive\n");
   2480   Waiter();
   2481   printf("\tGLOB=%d\n", GLOB);
   2482 }
   2483 REGISTER_TEST2(Run, 50, FEATURE|NEEDS_ANNOTATIONS);
   2484 }  // namespace test50
   2485 
   2486 
   2487 // test51: TP. Synchronization via CondVar: problem with several signals. {{{1
   2488 namespace test51 {
   2489 int     GLOB = 0;
   2490 int     COND = 0;
   2491 Mutex   MU;
   2492 
   2493 
   2494 // scheduler dependent results because of several signals
   2495 // second signal will be lost
   2496 //
   2497 // Waiter:                      Waker:
   2498 // 1. Start(Waker)
   2499 // 2. MU.Lock()
   2500 // 3. while(COND)
   2501 //       CV.Wait(MU)<-\         .
   2502 // 4. MU.Unlock()      \        .
   2503 // 5. write(GLOB)       \       a. write(GLOB)
   2504 //                       \      b. MU.Lock()
   2505 //                        \     c. COND = 1
   2506 //                         \--- d. CV.Signal()
   2507 //                              e. MU.Unlock()
   2508 //
   2509 //                              f. write(GLOB)
   2510 //
   2511 //                              g. MU.Lock()
   2512 //                              h. COND = 1
   2513 //                    LOST<---- i. CV.Signal()
   2514 //                              j. MU.Unlock()
   2515 
   2516 void Waker() {
   2517 
   2518   usleep(10000);  // Make sure the waiter blocks.
   2519 
   2520   GLOB = 1;
   2521 
   2522   MU.Lock();
   2523   COND = 1;
   2524   CV.Signal();
   2525   MU.Unlock();
   2526 
   2527   usleep(10000);  // Make sure the waiter is signalled.
   2528 
   2529   GLOB = 2;
   2530 
   2531   MU.Lock();
   2532   COND = 1;
   2533   CV.Signal();   //Lost Signal
   2534   MU.Unlock();
   2535 }
   2536 
   2537 void Waiter() {
   2538 
   2539   ThreadPool pool(1);
   2540   pool.StartWorkers();
   2541   pool.Add(NewCallback(Waker));
   2542 
   2543   MU.Lock();
   2544   while(COND != 1)
   2545     CV.Wait(&MU);
   2546   MU.Unlock();
   2547 
   2548 
   2549   GLOB = 3;
   2550 }
   2551 void Run() {
   2552   FAST_MODE_INIT(&GLOB);
   2553   ANNOTATE_EXPECT_RACE(&GLOB, "test51. TP.");
   2554   printf("test51: positive\n");
   2555   Waiter();
   2556   printf("\tGLOB=%d\n", GLOB);
   2557 }
   2558 REGISTER_TEST(Run, 51);
   2559 }  // namespace test51
   2560 
   2561 
   2562 // test52: TP. Synchronization via CondVar: problem with several signals. {{{1
   2563 namespace test52 {
   2564 int     GLOB = 0;
   2565 int     COND = 0;
   2566 Mutex   MU;
   2567 
   2568 // same as test51 but the first signal will be lost
   2569 // scheduler dependent results because of several signals
   2570 //
   2571 // Waiter:                      Waker:
   2572 // 1. Start(Waker)
   2573 //                              a. write(GLOB)
   2574 //                              b. MU.Lock()
   2575 //                              c. COND = 1
   2576 //                    LOST<---- d. CV.Signal()
   2577 //                              e. MU.Unlock()
   2578 //
   2579 // 2. MU.Lock()
   2580 // 3. while(COND)
   2581 //       CV.Wait(MU)<-\         .
   2582 // 4. MU.Unlock()      \        f. write(GLOB)
   2583 // 5. write(GLOB)       \       .
   2584 //                       \      g. MU.Lock()
   2585 //                        \     h. COND = 1
   2586 //                         \--- i. CV.Signal()
   2587 //                              j. MU.Unlock()
   2588 
   2589 void Waker() {
   2590 
   2591   GLOB = 1;
   2592 
   2593   MU.Lock();
   2594   COND = 1;
   2595   CV.Signal();    //lost signal
   2596   MU.Unlock();
   2597 
   2598   usleep(20000);  // Make sure the waiter blocks
   2599 
   2600   GLOB = 2;
   2601 
   2602   MU.Lock();
   2603   COND = 1;
   2604   CV.Signal();
   2605   MU.Unlock();
   2606 }
   2607 
   2608 void Waiter() {
   2609   ThreadPool pool(1);
   2610   pool.StartWorkers();
   2611   pool.Add(NewCallback(Waker));
   2612 
   2613   usleep(10000);  // Make sure the first signal will be lost
   2614 
   2615   MU.Lock();
   2616   while(COND != 1)
   2617     CV.Wait(&MU);
   2618   MU.Unlock();
   2619 
   2620   GLOB = 3;
   2621 }
   2622 void Run() {
   2623   FAST_MODE_INIT(&GLOB);
   2624   ANNOTATE_EXPECT_RACE(&GLOB, "test52. TP.");
   2625   printf("test52: positive\n");
   2626   Waiter();
   2627   printf("\tGLOB=%d\n", GLOB);
   2628 }
   2629 REGISTER_TEST(Run, 52);
   2630 }  // namespace test52
   2631 
   2632 
   2633 // test53: FP. Synchronization via implicit semaphore. {{{1
   2634 namespace test53 {
   2635 // Correctly synchronized test, but the common lockset is empty.
   2636 // The variable FLAG works as an implicit semaphore.
   2637 // MSMHelgrind still does not complain since it does not maintain the lockset
   2638 // at the exclusive state. But MSMProp1 does complain.
   2639 // See also test54.
   2640 //
   2641 //
   2642 // Initializer:                  Users
   2643 // 1. MU1.Lock()
   2644 // 2. write(GLOB)
   2645 // 3. FLAG = true
   2646 // 4. MU1.Unlock()
   2647 //                               a. MU1.Lock()
   2648 //                               b. f = FLAG;
   2649 //                               c. MU1.Unlock()
   2650 //                               d. if (!f) goto a.
   2651 //                               e. MU2.Lock()
   2652 //                               f. write(GLOB)
   2653 //                               g. MU2.Unlock()
   2654 //
   2655 
   2656 int     GLOB = 0;
   2657 bool    FLAG = false;
   2658 Mutex   MU1, MU2;
   2659 
   2660 void Initializer() {
   2661   MU1.Lock();
   2662   GLOB = 1000;
   2663   FLAG = true;
   2664   MU1.Unlock();
   2665   usleep(100000); // just in case
   2666 }
   2667 
   2668 void User() {
   2669   bool f = false;
   2670   while(!f) {
   2671     MU1.Lock();
   2672     f = FLAG;
   2673     MU1.Unlock();
   2674     usleep(10000);
   2675   }
   2676   // at this point Initializer will not access GLOB again
   2677   MU2.Lock();
   2678   CHECK(GLOB >= 1000);
   2679   GLOB++;
   2680   MU2.Unlock();
   2681 }
   2682 
   2683 void Run() {
   2684   FAST_MODE_INIT(&GLOB);
   2685   if (!Tsan_PureHappensBefore())
   2686     ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test53. FP. Implicit semaphore");
   2687   printf("test53: FP. false positive, Implicit semaphore\n");
   2688   MyThreadArray t(Initializer, User, User);
   2689   t.Start();
   2690   t.Join();
   2691   printf("\tGLOB=%d\n", GLOB);
   2692 }
   2693 REGISTER_TEST(Run, 53)
   2694 }  // namespace test53
   2695 
   2696 
   2697 // test54: TN. Synchronization via implicit semaphore. Annotated {{{1
   2698 namespace test54 {
   2699 // Same as test53, but annotated.
   2700 int     GLOB = 0;
   2701 bool    FLAG = false;
   2702 Mutex   MU1, MU2;
   2703 
   2704 void Initializer() {
   2705   MU1.Lock();
   2706   GLOB = 1000;
   2707   FLAG = true;
   2708   ANNOTATE_CONDVAR_SIGNAL(&GLOB);
   2709   MU1.Unlock();
   2710   usleep(100000); // just in case
   2711 }
   2712 
   2713 void User() {
   2714   bool f = false;
   2715   while(!f) {
   2716     MU1.Lock();
   2717     f = FLAG;
   2718     MU1.Unlock();
   2719     usleep(10000);
   2720   }
   2721   // at this point Initializer will not access GLOB again
   2722   ANNOTATE_CONDVAR_WAIT(&GLOB);
   2723   MU2.Lock();
   2724   CHECK(GLOB >= 1000);
   2725   GLOB++;
   2726   MU2.Unlock();
   2727 }
   2728 
   2729 void Run() {
   2730   printf("test54: negative\n");
   2731   MyThreadArray t(Initializer, User, User);
   2732   t.Start();
   2733   t.Join();
   2734   printf("\tGLOB=%d\n", GLOB);
   2735 }
   2736 REGISTER_TEST2(Run, 54, FEATURE|NEEDS_ANNOTATIONS)
   2737 }  // namespace test54
   2738 
   2739 
   2740 // test55: FP. Synchronization with TryLock. Not easy for race detectors {{{1
   2741 namespace test55 {
   2742 // "Correct" synchronization with TryLock and Lock.
   2743 //
   2744 // This scheme is actually very risky.
   2745 // It is covered in detail in this video:
   2746 // http://youtube.com/watch?v=mrvAqvtWYb4 (slide 36, near 50-th minute).
   2747 int     GLOB = 0;
   2748 Mutex   MU;
   2749 
   2750 void Worker_Lock() {
   2751   GLOB = 1;
   2752   MU.Lock();
   2753 }
   2754 
   2755 void Worker_TryLock() {
   2756   while (true) {
   2757     if (!MU.TryLock()) {
   2758       MU.Unlock();
   2759       break;
   2760     }
   2761     else
   2762       MU.Unlock();
   2763     usleep(100);
   2764   }
   2765   GLOB = 2;
   2766 }
   2767 
   2768 void Run() {
   2769   printf("test55:\n");
   2770   MyThreadArray t(Worker_Lock, Worker_TryLock);
   2771   t.Start();
   2772   t.Join();
   2773   printf("\tGLOB=%d\n", GLOB);
   2774 }
   2775 REGISTER_TEST2(Run, 55, FEATURE|EXCLUDE_FROM_ALL);
   2776 }  // namespace test55
   2777 
   2778 
   2779 
   2780 // test56: TP. Use of ANNOTATE_BENIGN_RACE. {{{1
   2781 namespace test56 {
   2782 // For whatever reason the user wants to treat
   2783 // a race on GLOB as a benign race.
   2784 int     GLOB = 0;
   2785 int     GLOB2 = 0;
   2786 
   2787 void Worker() {
   2788   GLOB++;
   2789 }
   2790 
   2791 void Run() {
   2792   ANNOTATE_BENIGN_RACE(&GLOB, "test56. Use of ANNOTATE_BENIGN_RACE.");
   2793   ANNOTATE_BENIGN_RACE(&GLOB2, "No race. The tool should be silent");
   2794   printf("test56: positive\n");
   2795   MyThreadArray t(Worker, Worker, Worker, Worker);
   2796   t.Start();
   2797   t.Join();
   2798   printf("\tGLOB=%d\n", GLOB);
   2799 }
   2800 REGISTER_TEST2(Run, 56, FEATURE|NEEDS_ANNOTATIONS)
   2801 }  // namespace test56
   2802 
   2803 
   2804 // test57: TN: Correct use of atomics. {{{1
   2805 namespace test57 {
   2806 int     GLOB = 0;
   2807 void Writer() {
   2808   for (int i = 0; i < 10; i++) {
   2809     AtomicIncrement(&GLOB, 1);
   2810     usleep(1000);
   2811   }
   2812 }
   2813 void Reader() {
   2814   while (GLOB < 20) usleep(1000);
   2815 }
   2816 void Run() {
   2817   printf("test57: negative\n");
   2818   MyThreadArray t(Writer, Writer, Reader, Reader);
   2819   t.Start();
   2820   t.Join();
   2821   CHECK(GLOB == 20);
   2822   printf("\tGLOB=%d\n", GLOB);
   2823 }
   2824 REGISTER_TEST(Run, 57)
   2825 }  // namespace test57
   2826 
   2827 
   2828 // test58: TN. User defined synchronization. {{{1
   2829 namespace test58 {
   2830 int     GLOB1 = 1;
   2831 int     GLOB2 = 2;
   2832 int     FLAG1 = 0;
   2833 int     FLAG2 = 0;
   2834 
   2835 // Correctly synchronized test, but the common lockset is empty.
   2836 // The variables FLAG1 and FLAG2 used for synchronization and as
   2837 // temporary variables for swapping two global values.
   2838 // Such kind of synchronization is rarely used (Excluded from all tests??).
   2839 
   2840 void Worker2() {
   2841   FLAG1=GLOB2;
   2842 
   2843   while(!FLAG2)
   2844     ;
   2845   GLOB2=FLAG2;
   2846 }
   2847 
   2848 void Worker1() {
   2849   FLAG2=GLOB1;
   2850 
   2851   while(!FLAG1)
   2852     ;
   2853   GLOB1=FLAG1;
   2854 }
   2855 
   2856 void Run() {
   2857   printf("test58:\n");
   2858   MyThreadArray t(Worker1, Worker2);
   2859   t.Start();
   2860   t.Join();
   2861   printf("\tGLOB1=%d\n", GLOB1);
   2862   printf("\tGLOB2=%d\n", GLOB2);
   2863 }
   2864 REGISTER_TEST2(Run, 58, FEATURE|EXCLUDE_FROM_ALL)
   2865 }  // namespace test58
   2866 
   2867 
   2868 
   2869 // test59: TN. User defined synchronization. Annotated {{{1
   2870 namespace test59 {
   2871 int     COND1 = 0;
   2872 int     COND2 = 0;
   2873 int     GLOB1 = 1;
   2874 int     GLOB2 = 2;
   2875 int     FLAG1 = 0;
   2876 int     FLAG2 = 0;
   2877 // same as test 58 but annotated
   2878 
   2879 void Worker2() {
   2880   FLAG1=GLOB2;
   2881   ANNOTATE_CONDVAR_SIGNAL(&COND2);
   2882   while(!FLAG2) usleep(1);
   2883   ANNOTATE_CONDVAR_WAIT(&COND1);
   2884   GLOB2=FLAG2;
   2885 }
   2886 
   2887 void Worker1() {
   2888   FLAG2=GLOB1;
   2889   ANNOTATE_CONDVAR_SIGNAL(&COND1);
   2890   while(!FLAG1) usleep(1);
   2891   ANNOTATE_CONDVAR_WAIT(&COND2);
   2892   GLOB1=FLAG1;
   2893 }
   2894 
   2895 void Run() {
   2896   printf("test59: negative\n");
   2897   ANNOTATE_BENIGN_RACE(&FLAG1, "synchronization via 'safe' race");
   2898   ANNOTATE_BENIGN_RACE(&FLAG2, "synchronization via 'safe' race");
   2899   MyThreadArray t(Worker1, Worker2);
   2900   t.Start();
   2901   t.Join();
   2902   printf("\tGLOB1=%d\n", GLOB1);
   2903   printf("\tGLOB2=%d\n", GLOB2);
   2904 }
   2905 REGISTER_TEST2(Run, 59, FEATURE|NEEDS_ANNOTATIONS)
   2906 }  // namespace test59
   2907 
   2908 
   2909 // test60: TN. Correct synchronization using signal-wait {{{1
   2910 namespace test60 {
   2911 int     COND1 = 0;
   2912 int     COND2 = 0;
   2913 int     GLOB1 = 1;
   2914 int     GLOB2 = 2;
   2915 int     FLAG2 = 0;
   2916 int     FLAG1 = 0;
   2917 Mutex   MU;
   2918 // same as test 59 but synchronized with signal-wait.
   2919 
   2920 void Worker2() {
   2921   FLAG1=GLOB2;
   2922 
   2923   MU.Lock();
   2924   COND1 = 1;
   2925   CV.Signal();
   2926   MU.Unlock();
   2927 
   2928   MU.Lock();
   2929   while(COND2 != 1)
   2930     CV.Wait(&MU);
   2931   ANNOTATE_CONDVAR_LOCK_WAIT(&CV, &MU);
   2932   MU.Unlock();
   2933 
   2934   GLOB2=FLAG2;
   2935 }
   2936 
   2937 void Worker1() {
   2938   FLAG2=GLOB1;
   2939 
   2940   MU.Lock();
   2941   COND2 = 1;
   2942   CV.Signal();
   2943   MU.Unlock();
   2944 
   2945   MU.Lock();
   2946   while(COND1 != 1)
   2947     CV.Wait(&MU);
   2948   ANNOTATE_CONDVAR_LOCK_WAIT(&CV, &MU);
   2949   MU.Unlock();
   2950 
   2951   GLOB1=FLAG1;
   2952 }
   2953 
   2954 void Run() {
   2955   printf("test60: negative\n");
   2956   MyThreadArray t(Worker1, Worker2);
   2957   t.Start();
   2958   t.Join();
   2959   printf("\tGLOB1=%d\n", GLOB1);
   2960   printf("\tGLOB2=%d\n", GLOB2);
   2961 }
   2962 REGISTER_TEST2(Run, 60, FEATURE|NEEDS_ANNOTATIONS)
   2963 }  // namespace test60
   2964 
   2965 
   2966 // test61: TN. Synchronization via Mutex as in happens-before, annotated. {{{1
   2967 namespace test61 {
   2968 Mutex MU;
   2969 int     GLOB = 0;
   2970 int     *P1 = NULL, *P2 = NULL;
   2971 
   2972 // In this test Mutex lock/unlock operations introduce happens-before relation.
   2973 // We annotate the code so that MU is treated as in pure happens-before detector.
   2974 
   2975 
   2976 void Putter() {
   2977   ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(&MU);
   2978   MU.Lock();
   2979   if (P1 == NULL) {
   2980     P1 = &GLOB;
   2981     *P1 = 1;
   2982   }
   2983   MU.Unlock();
   2984 }
   2985 
   2986 void Getter() {
   2987   bool done  = false;
   2988   while (!done) {
   2989     MU.Lock();
   2990     if (P1) {
   2991       done = true;
   2992       P2 = P1;
   2993       P1 = NULL;
   2994     }
   2995     MU.Unlock();
   2996   }
   2997   *P2 = 2;
   2998 }
   2999 
   3000 
   3001 void Run() {
   3002   printf("test61: negative\n");
   3003   MyThreadArray t(Putter, Getter);
   3004   t.Start();
   3005   t.Join();
   3006   printf("\tGLOB=%d\n", GLOB);
   3007 }
   3008 REGISTER_TEST2(Run, 61, FEATURE|NEEDS_ANNOTATIONS)
   3009 }  // namespace test61
   3010 
   3011 
   3012 // test62: STAB. Create as many segments as possible. {{{1
   3013 namespace test62 {
   3014 // Helgrind 3.3.0 will fail as it has a hard limit of < 2^24 segments.
   3015 // A better scheme is to implement garbage collection for segments.
   3016 ProducerConsumerQueue Q(INT_MAX);
   3017 const int N = 1 << 22;
   3018 
   3019 void Putter() {
   3020   for (int i = 0; i < N; i++){
   3021     if ((i % (N / 8)) == 0) {
   3022       printf("i=%d\n", i);
   3023     }
   3024     Q.Put(NULL);
   3025   }
   3026 }
   3027 
   3028 void Getter() {
   3029   for (int i = 0; i < N; i++)
   3030     Q.Get();
   3031 }
   3032 
   3033 void Run() {
   3034   printf("test62:\n");
   3035   MyThreadArray t(Putter, Getter);
   3036   t.Start();
   3037   t.Join();
   3038 }
   3039 REGISTER_TEST2(Run, 62, STABILITY|EXCLUDE_FROM_ALL)
   3040 }  // namespace test62
   3041 
   3042 
   3043 // test63: STAB. Create as many segments as possible and do it fast. {{{1
   3044 namespace test63 {
   3045 // Helgrind 3.3.0 will fail as it has a hard limit of < 2^24 segments.
   3046 // A better scheme is to implement garbage collection for segments.
   3047 const int N = 1 << 24;
   3048 int C = 0;
   3049 
   3050 void Putter() {
   3051   for (int i = 0; i < N; i++){
   3052     if ((i % (N / 8)) == 0) {
   3053       printf("i=%d\n", i);
   3054     }
   3055     ANNOTATE_CONDVAR_SIGNAL(&C);
   3056   }
   3057 }
   3058 
   3059 void Getter() {
   3060 }
   3061 
   3062 void Run() {
   3063   printf("test63:\n");
   3064   MyThreadArray t(Putter, Getter);
   3065   t.Start();
   3066   t.Join();
   3067 }
   3068 REGISTER_TEST2(Run, 63, STABILITY|EXCLUDE_FROM_ALL)
   3069 }  // namespace test63
   3070 
   3071 
   3072 // test64: TP. T2 happens-before T3, but T1 is independent. Reads in T1/T2. {{{1
   3073 namespace test64 {
   3074 // True race between T1 and T3:
   3075 //
   3076 // T1:                   T2:                   T3:
   3077 // 1. read(GLOB)         (sleep)
   3078 //                       a. read(GLOB)
   3079 //                       b. Q.Put() ----->    A. Q.Get()
   3080 //                                            B. write(GLOB)
   3081 //
   3082 //
   3083 
   3084 int     GLOB = 0;
   3085 ProducerConsumerQueue Q(INT_MAX);
   3086 
   3087 void T1() {
   3088   CHECK(GLOB == 0);
   3089 }
   3090 
   3091 void T2() {
   3092   usleep(100000);
   3093   CHECK(GLOB == 0);
   3094   Q.Put(NULL);
   3095 }
   3096 
   3097 void T3() {
   3098   Q.Get();
   3099   GLOB = 1;
   3100 }
   3101 
   3102 
   3103 void Run() {
   3104   FAST_MODE_INIT(&GLOB);
   3105   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test64: TP.");
   3106   printf("test64: positive\n");
   3107   MyThreadArray t(T1, T2, T3);
   3108   t.Start();
   3109   t.Join();
   3110   printf("\tGLOB=%d\n", GLOB);
   3111 }
   3112 REGISTER_TEST(Run, 64)
   3113 }  // namespace test64
   3114 
   3115 
   3116 // test65: TP. T2 happens-before T3, but T1 is independent. Writes in T1/T2. {{{1
   3117 namespace test65 {
   3118 // Similar to test64.
   3119 // True race between T1 and T3:
   3120 //
   3121 // T1:                   T2:                   T3:
   3122 // 1. MU.Lock()
   3123 // 2. write(GLOB)
   3124 // 3. MU.Unlock()         (sleep)
   3125 //                       a. MU.Lock()
   3126 //                       b. write(GLOB)
   3127 //                       c. MU.Unlock()
   3128 //                       d. Q.Put() ----->    A. Q.Get()
   3129 //                                            B. write(GLOB)
   3130 //
   3131 //
   3132 
   3133 int     GLOB = 0;
   3134 Mutex   MU;
   3135 ProducerConsumerQueue Q(INT_MAX);
   3136 
   3137 void T1() {
   3138   MU.Lock();
   3139   GLOB++;
   3140   MU.Unlock();
   3141 }
   3142 
   3143 void T2() {
   3144   usleep(100000);
   3145   MU.Lock();
   3146   GLOB++;
   3147   MU.Unlock();
   3148   Q.Put(NULL);
   3149 }
   3150 
   3151 void T3() {
   3152   Q.Get();
   3153   GLOB = 1;
   3154 }
   3155 
   3156 
   3157 void Run() {
   3158   FAST_MODE_INIT(&GLOB);
   3159   if (!Tsan_PureHappensBefore())
   3160     ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test65. TP.");
   3161   printf("test65: positive\n");
   3162   MyThreadArray t(T1, T2, T3);
   3163   t.Start();
   3164   t.Join();
   3165   printf("\tGLOB=%d\n", GLOB);
   3166 }
   3167 REGISTER_TEST(Run, 65)
   3168 }  // namespace test65
   3169 
   3170 
   3171 // test66: TN. Two separate pairs of signaller/waiter using the same CV. {{{1
   3172 namespace test66 {
   3173 int     GLOB1 = 0;
   3174 int     GLOB2 = 0;
   3175 int     C1 = 0;
   3176 int     C2 = 0;
   3177 Mutex   MU;
   3178 
   3179 void Signaller1() {
   3180   GLOB1 = 1;
   3181   MU.Lock();
   3182   C1 = 1;
   3183   CV.Signal();
   3184   MU.Unlock();
   3185 }
   3186 
   3187 void Signaller2() {
   3188   GLOB2 = 1;
   3189   usleep(100000);
   3190   MU.Lock();
   3191   C2 = 1;
   3192   CV.Signal();
   3193   MU.Unlock();
   3194 }
   3195 
   3196 void Waiter1() {
   3197   MU.Lock();
   3198   while (C1 != 1) CV.Wait(&MU);
   3199   ANNOTATE_CONDVAR_WAIT(&CV);
   3200   MU.Unlock();
   3201   GLOB1 = 2;
   3202 }
   3203 
   3204 void Waiter2() {
   3205   MU.Lock();
   3206   while (C2 != 1) CV.Wait(&MU);
   3207   ANNOTATE_CONDVAR_WAIT(&CV);
   3208   MU.Unlock();
   3209   GLOB2 = 2;
   3210 }
   3211 
   3212 void Run() {
   3213   printf("test66: negative\n");
   3214   MyThreadArray t(Signaller1, Signaller2, Waiter1, Waiter2);
   3215   t.Start();
   3216   t.Join();
   3217   printf("\tGLOB=%d/%d\n", GLOB1, GLOB2);
   3218 }
   3219 REGISTER_TEST2(Run, 66, FEATURE|NEEDS_ANNOTATIONS)
   3220 }  // namespace test66
   3221 
   3222 
   3223 // test67: FN. Race between Signaller1 and Waiter2 {{{1
   3224 namespace test67 {
   3225 // Similar to test66, but there is a real race here.
   3226 //
   3227 // Here we create a happens-before arc between Signaller1 and Waiter2
   3228 // even though there should be no such arc.
   3229 // However, it's probably improssible (or just very hard) to avoid it.
   3230 int     GLOB = 0;
   3231 int     C1 = 0;
   3232 int     C2 = 0;
   3233 Mutex   MU;
   3234 
   3235 void Signaller1() {
   3236   GLOB = 1;
   3237   MU.Lock();
   3238   C1 = 1;
   3239   CV.Signal();
   3240   MU.Unlock();
   3241 }
   3242 
   3243 void Signaller2() {
   3244   usleep(100000);
   3245   MU.Lock();
   3246   C2 = 1;
   3247   CV.Signal();
   3248   MU.Unlock();
   3249 }
   3250 
   3251 void Waiter1() {
   3252   MU.Lock();
   3253   while (C1 != 1) CV.Wait(&MU);
   3254   ANNOTATE_CONDVAR_WAIT(&CV);
   3255   MU.Unlock();
   3256 }
   3257 
   3258 void Waiter2() {
   3259   MU.Lock();
   3260   while (C2 != 1) CV.Wait(&MU);
   3261   ANNOTATE_CONDVAR_WAIT(&CV);
   3262   MU.Unlock();
   3263   GLOB = 2;
   3264 }
   3265 
   3266 void Run() {
   3267   FAST_MODE_INIT(&GLOB);
   3268   ANNOTATE_EXPECT_RACE(&GLOB, "test67. FN. Race between Signaller1 and Waiter2");
   3269   printf("test67: positive\n");
   3270   MyThreadArray t(Signaller1, Signaller2, Waiter1, Waiter2);
   3271   t.Start();
   3272   t.Join();
   3273   printf("\tGLOB=%d\n", GLOB);
   3274 }
   3275 REGISTER_TEST2(Run, 67, FEATURE|NEEDS_ANNOTATIONS|EXCLUDE_FROM_ALL)
   3276 }  // namespace test67
   3277 
   3278 
   3279 // test68: TP. Writes are protected by MU, reads are not. {{{1
   3280 namespace test68 {
   3281 // In this test, all writes to GLOB are protected by a mutex
   3282 // but some reads go unprotected.
   3283 // This is certainly a race, but in some cases such code could occur in
   3284 // a correct program. For example, the unprotected reads may be used
   3285 // for showing statistics and are not required to be precise.
   3286 int     GLOB = 0;
   3287 int     COND = 0;
   3288 const int N_writers = 3;
   3289 Mutex MU, MU1;
   3290 
   3291 void Writer() {
   3292   for (int i = 0; i < 100; i++) {
   3293     MU.Lock();
   3294     GLOB++;
   3295     MU.Unlock();
   3296   }
   3297 
   3298   // we are done
   3299   MU1.Lock();
   3300   COND++;
   3301   MU1.Unlock();
   3302 }
   3303 
   3304 void Reader() {
   3305   bool cont = true;
   3306   while (cont) {
   3307     CHECK(GLOB >= 0);
   3308 
   3309     // are we done?
   3310     MU1.Lock();
   3311     if (COND == N_writers)
   3312       cont = false;
   3313     MU1.Unlock();
   3314     usleep(100);
   3315   }
   3316 }
   3317 
   3318 void Run() {
   3319   FAST_MODE_INIT(&GLOB);
   3320   ANNOTATE_EXPECT_RACE(&GLOB, "TP. Writes are protected, reads are not.");
   3321   printf("test68: positive\n");
   3322   MyThreadArray t(Reader, Writer, Writer, Writer);
   3323   t.Start();
   3324   t.Join();
   3325   printf("\tGLOB=%d\n", GLOB);
   3326 }
   3327 REGISTER_TEST(Run, 68)
   3328 }  // namespace test68
   3329 
   3330 
   3331 // test69:  {{{1
   3332 namespace test69 {
   3333 // This is the same as test68, but annotated.
   3334 // We do not want to annotate GLOB as a benign race
   3335 // because we want to allow racy reads only in certain places.
   3336 //
   3337 // TODO:
   3338 int     GLOB = 0;
   3339 int     COND = 0;
   3340 const int N_writers = 3;
   3341 int     FAKE_MU = 0;
   3342 Mutex MU, MU1;
   3343 
   3344 void Writer() {
   3345   for (int i = 0; i < 10; i++) {
   3346     MU.Lock();
   3347     GLOB++;
   3348     MU.Unlock();
   3349   }
   3350 
   3351   // we are done
   3352   MU1.Lock();
   3353   COND++;
   3354   MU1.Unlock();
   3355 }
   3356 
   3357 void Reader() {
   3358   bool cont = true;
   3359   while (cont) {
   3360     ANNOTATE_IGNORE_READS_BEGIN();
   3361     CHECK(GLOB >= 0);
   3362     ANNOTATE_IGNORE_READS_END();
   3363 
   3364     // are we done?
   3365     MU1.Lock();
   3366     if (COND == N_writers)
   3367       cont = false;
   3368     MU1.Unlock();
   3369     usleep(100);
   3370   }
   3371 }
   3372 
   3373 void Run() {
   3374   printf("test69: negative\n");
   3375   MyThreadArray t(Reader, Writer, Writer, Writer);
   3376   t.Start();
   3377   t.Join();
   3378   printf("\tGLOB=%d\n", GLOB);
   3379 }
   3380 REGISTER_TEST(Run, 69)
   3381 }  // namespace test69
   3382 
   3383 // test70: STAB. Check that TRACE_MEMORY works. {{{1
   3384 namespace test70 {
   3385 int     GLOB = 0;
   3386 void Run() {
   3387   printf("test70: negative\n");
   3388   ANNOTATE_TRACE_MEMORY(&GLOB);
   3389   GLOB = 1;
   3390   printf("\tGLOB=%d\n", GLOB);
   3391 }
   3392 REGISTER_TEST(Run, 70)
   3393 }  // namespace test70
   3394 
   3395 
   3396 
   3397 // test71: TN. strlen, index. {{{1
   3398 namespace test71 {
   3399 // This test is a reproducer for a benign race in strlen (as well as index, etc).
   3400 // Some implementations of strlen may read up to 7 bytes past the end of the string
   3401 // thus touching memory which may not belong to this string.
   3402 // Such race is benign because the data read past the end of the string is not used.
   3403 //
   3404 // Here, we allocate a 8-byte aligned string str and initialize first 5 bytes.
   3405 // Then one thread calls strlen(str) (as well as index & rindex)
   3406 // and another thread initializes str[5]..str[7].
   3407 //
   3408 // This can be fixed in Helgrind by intercepting strlen and replacing it
   3409 // with a simpler implementation.
   3410 
   3411 char    *str;
   3412 void WorkerX() {
   3413   usleep(100000);
   3414   CHECK(strlen(str) == 4);
   3415   CHECK(index(str, 'X') == str);
   3416   CHECK(index(str, 'x') == str+1);
   3417   CHECK(index(str, 'Y') == NULL);
   3418   CHECK(rindex(str, 'X') == str+2);
   3419   CHECK(rindex(str, 'x') == str+3);
   3420   CHECK(rindex(str, 'Y') == NULL);
   3421 }
   3422 void WorkerY() {
   3423   str[5] = 'Y';
   3424   str[6] = 'Y';
   3425   str[7] = '\0';
   3426 }
   3427 
   3428 void Run() {
   3429   str = new char[8];
   3430   str[0] = 'X';
   3431   str[1] = 'x';
   3432   str[2] = 'X';
   3433   str[3] = 'x';
   3434   str[4] = '\0';
   3435 
   3436   printf("test71: negative (strlen & index)\n");
   3437   MyThread t1(WorkerY);
   3438   MyThread t2(WorkerX);
   3439   t1.Start();
   3440   t2.Start();
   3441   t1.Join();
   3442   t2.Join();
   3443   printf("\tstrX=%s; strY=%s\n", str, str+5);
   3444 }
   3445 REGISTER_TEST(Run, 71)
   3446 }  // namespace test71
   3447 
   3448 
   3449 // test72: STAB. Stress test for the number of segment sets (SSETs). {{{1
   3450 namespace test72 {
   3451 #ifndef NO_BARRIER
   3452 // Variation of test33.
   3453 // Instead of creating Nlog*N_iter threads,
   3454 // we create Nlog threads and do N_iter barriers.
   3455 int     GLOB = 0;
   3456 const int N_iter = 30;
   3457 const int Nlog  = 16;
   3458 const int N     = 1 << Nlog;
   3459 static int64_t ARR1[N];
   3460 static int64_t ARR2[N];
   3461 Barrier *barriers[N_iter];
   3462 Mutex   MU;
   3463 
   3464 void Worker() {
   3465   MU.Lock();
   3466   int n = ++GLOB;
   3467   MU.Unlock();
   3468 
   3469   n %= Nlog;
   3470 
   3471   long t0 = clock();
   3472   long t = t0;
   3473 
   3474   for (int it = 0; it < N_iter; it++) {
   3475     if(n == 0) {
   3476       //printf("Iter: %d; %ld %ld\n", it, clock() - t, clock() - t0);
   3477       t = clock();
   3478     }
   3479     // Iterate N_iter times, block on barrier after each iteration.
   3480     // This way Helgrind will create new segments after each barrier.
   3481 
   3482     for (int x = 0; x < 2; x++) {
   3483       // run the inner loop twice.
   3484       // When a memory location is accessed second time it is likely
   3485       // that the state (SVal) will be unchanged.
   3486       // The memory machine may optimize this case.
   3487       for (int i = 0; i < N; i++) {
   3488         // ARR1[i] and ARR2[N-1-i] are accessed by threads from i-th subset
   3489         if (i & (1 << n)) {
   3490           CHECK(ARR1[i] == 0);
   3491           CHECK(ARR2[N-1-i] == 0);
   3492         }
   3493       }
   3494     }
   3495     barriers[it]->Block();
   3496   }
   3497 }
   3498 
   3499 
   3500 void Run() {
   3501   printf("test72:\n");
   3502 
   3503   std::vector<MyThread*> vec(Nlog);
   3504 
   3505   for (int i = 0; i < N_iter; i++)
   3506     barriers[i] = new Barrier(Nlog);
   3507 
   3508   // Create and start Nlog threads
   3509   for (int i = 0; i < Nlog; i++) {
   3510     vec[i] = new MyThread(Worker);
   3511     vec[i]->Start();
   3512   }
   3513 
   3514   // Join all threads.
   3515   for (int i = 0; i < Nlog; i++) {
   3516     vec[i]->Join();
   3517     delete vec[i];
   3518   }
   3519   for (int i = 0; i < N_iter; i++)
   3520     delete barriers[i];
   3521 
   3522   /*printf("\tGLOB=%d; ARR[1]=%d; ARR[7]=%d; ARR[N-1]=%d\n",
   3523          GLOB, (int)ARR1[1], (int)ARR1[7], (int)ARR1[N-1]);*/
   3524 }
   3525 REGISTER_TEST2(Run, 72, STABILITY|PERFORMANCE|EXCLUDE_FROM_ALL);
   3526 #endif // NO_BARRIER
   3527 }  // namespace test72
   3528 
   3529 
   3530 // test73: STAB. Stress test for the number of (SSETs), different access sizes. {{{1
   3531 namespace test73 {
   3532 #ifndef NO_BARRIER
   3533 // Variation of test72.
   3534 // We perform accesses of different sizes to the same location.
   3535 int     GLOB = 0;
   3536 const int N_iter = 2;
   3537 const int Nlog  = 16;
   3538 const int N     = 1 << Nlog;
   3539 union uint64_union {
   3540   uint64_t u64[1];
   3541   uint32_t u32[2];
   3542   uint16_t u16[4];
   3543   uint8_t  u8 [8];
   3544 };
   3545 static uint64_union ARR1[N];
   3546 union uint32_union {
   3547   uint32_t u32[1];
   3548   uint16_t u16[2];
   3549   uint8_t  u8 [4];
   3550 };
   3551 static uint32_union ARR2[N];
   3552 Barrier *barriers[N_iter];
   3553 Mutex   MU;
   3554 
   3555 void Worker() {
   3556   MU.Lock();
   3557   int n = ++GLOB;
   3558   MU.Unlock();
   3559 
   3560   n %= Nlog;
   3561 
   3562   for (int it = 0; it < N_iter; it++) {
   3563     // Iterate N_iter times, block on barrier after each iteration.
   3564     // This way Helgrind will create new segments after each barrier.
   3565 
   3566     for (int x = 0; x < 4; x++) {
   3567       for (int i = 0; i < N; i++) {
   3568         // ARR1[i] are accessed by threads from i-th subset
   3569         if (i & (1 << n)) {
   3570           for (int off = 0; off < (1 << x); off++) {
   3571             switch(x) {
   3572               case 0: CHECK(ARR1[i].u64[off] == 0); break;
   3573               case 1: CHECK(ARR1[i].u32[off] == 0); break;
   3574               case 2: CHECK(ARR1[i].u16[off] == 0); break;
   3575               case 3: CHECK(ARR1[i].u8 [off] == 0); break;
   3576             }
   3577             switch(x) {
   3578               case 1: CHECK(ARR2[i].u32[off] == 0); break;
   3579               case 2: CHECK(ARR2[i].u16[off] == 0); break;
   3580               case 3: CHECK(ARR2[i].u8 [off] == 0); break;
   3581             }
   3582           }
   3583         }
   3584       }
   3585     }
   3586     barriers[it]->Block();
   3587   }
   3588 }
   3589 
   3590 
   3591 
   3592 void Run() {
   3593   printf("test73:\n");
   3594 
   3595   std::vector<MyThread*> vec(Nlog);
   3596 
   3597   for (int i = 0; i < N_iter; i++)
   3598     barriers[i] = new Barrier(Nlog);
   3599 
   3600   // Create and start Nlog threads
   3601   for (int i = 0; i < Nlog; i++) {
   3602     vec[i] = new MyThread(Worker);
   3603     vec[i]->Start();
   3604   }
   3605 
   3606   // Join all threads.
   3607   for (int i = 0; i < Nlog; i++) {
   3608     vec[i]->Join();
   3609     delete vec[i];
   3610   }
   3611   for (int i = 0; i < N_iter; i++)
   3612     delete barriers[i];
   3613 
   3614   /*printf("\tGLOB=%d; ARR[1]=%d; ARR[7]=%d; ARR[N-1]=%d\n",
   3615          GLOB, (int)ARR1[1], (int)ARR1[7], (int)ARR1[N-1]);*/
   3616 }
   3617 REGISTER_TEST2(Run, 73, STABILITY|PERFORMANCE|EXCLUDE_FROM_ALL);
   3618 #endif // NO_BARRIER
   3619 }  // namespace test73
   3620 
   3621 
   3622 // test74: PERF. A lot of lock/unlock calls. {{{1
   3623 namespace    test74 {
   3624 const int N = 100000;
   3625 Mutex   MU;
   3626 void Run() {
   3627   printf("test74: perf\n");
   3628   for (int i = 0; i < N; i++ ) {
   3629     MU.Lock();
   3630     MU.Unlock();
   3631   }
   3632 }
   3633 REGISTER_TEST(Run, 74)
   3634 }  // namespace test74
   3635 
   3636 
   3637 // test75: TN. Test for sem_post, sem_wait, sem_trywait. {{{1
   3638 namespace test75 {
   3639 int     GLOB = 0;
   3640 sem_t   sem[2];
   3641 
   3642 void Poster() {
   3643   GLOB = 1;
   3644   sem_post(&sem[0]);
   3645   sem_post(&sem[1]);
   3646 }
   3647 
   3648 void Waiter() {
   3649   sem_wait(&sem[0]);
   3650   CHECK(GLOB==1);
   3651 }
   3652 void TryWaiter() {
   3653   usleep(500000);
   3654   sem_trywait(&sem[1]);
   3655   CHECK(GLOB==1);
   3656 }
   3657 
   3658 void Run() {
   3659 #ifndef DRT_NO_SEM
   3660   sem_init(&sem[0], 0, 0);
   3661   sem_init(&sem[1], 0, 0);
   3662 
   3663   printf("test75: negative\n");
   3664   {
   3665     MyThreadArray t(Poster, Waiter);
   3666     t.Start();
   3667     t.Join();
   3668   }
   3669   GLOB = 2;
   3670   {
   3671     MyThreadArray t(Poster, TryWaiter);
   3672     t.Start();
   3673     t.Join();
   3674   }
   3675   printf("\tGLOB=%d\n", GLOB);
   3676 
   3677   sem_destroy(&sem[0]);
   3678   sem_destroy(&sem[1]);
   3679 #endif
   3680 }
   3681 REGISTER_TEST(Run, 75)
   3682 }  // namespace test75
   3683 
   3684 // RefCountedClass {{{1
   3685 struct RefCountedClass {
   3686  public:
   3687   RefCountedClass() {
   3688     annotate_unref_ = false;
   3689     ref_ = 0;
   3690     data_ = 0;
   3691   }
   3692 
   3693   ~RefCountedClass() {
   3694     CHECK(ref_ == 0);     // race may be reported here
   3695     int data_val = data_; // and here
   3696                           // if MU is not annotated
   3697     data_ = 0;
   3698     ref_ = -1;
   3699     printf("\tRefCountedClass::data_ = %d\n", data_val);
   3700   }
   3701 
   3702   void AccessData() {
   3703     this->mu_.Lock();
   3704     this->data_++;
   3705     this->mu_.Unlock();
   3706   }
   3707 
   3708   void Ref() {
   3709     MU.Lock();
   3710     CHECK(ref_ >= 0);
   3711     ref_++;
   3712     MU.Unlock();
   3713   }
   3714 
   3715   void Unref() {
   3716     MU.Lock();
   3717     CHECK(ref_ > 0);
   3718     ref_--;
   3719     bool do_delete = ref_ == 0;
   3720     if (annotate_unref_) {
   3721       ANNOTATE_CONDVAR_SIGNAL(this);
   3722     }
   3723     MU.Unlock();
   3724     if (do_delete) {
   3725       if (annotate_unref_) {
   3726         ANNOTATE_CONDVAR_WAIT(this);
   3727       }
   3728       delete this;
   3729     }
   3730   }
   3731 
   3732   static void Annotate_MU() {
   3733     ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(&MU);
   3734   }
   3735   void AnnotateUnref() {
   3736     annotate_unref_ = true;
   3737   }
   3738   void Annotate_Race() {
   3739     ANNOTATE_BENIGN_RACE(&this->data_, "needs annotation");
   3740     ANNOTATE_BENIGN_RACE(&this->ref_, "needs annotation");
   3741   }
   3742  private:
   3743   bool annotate_unref_;
   3744 
   3745   int data_;
   3746   Mutex mu_; // protects data_
   3747 
   3748   int ref_;
   3749   static Mutex MU; // protects ref_
   3750 };
   3751 
   3752 Mutex RefCountedClass::MU;
   3753 
   3754 // test76: FP. Ref counting, no annotations. {{{1
   3755 namespace test76 {
   3756 #ifndef NO_BARRIER
   3757 int     GLOB = 0;
   3758 Barrier barrier(4);
   3759 RefCountedClass *object = NULL;
   3760 void Worker() {
   3761   object->Ref();
   3762   barrier.Block();
   3763   object->AccessData();
   3764   object->Unref();
   3765 }
   3766 void Run() {
   3767   printf("test76: false positive (ref counting)\n");
   3768   object = new RefCountedClass;
   3769   object->Annotate_Race();
   3770   MyThreadArray t(Worker, Worker, Worker, Worker);
   3771   t.Start();
   3772   t.Join();
   3773 }
   3774 REGISTER_TEST2(Run, 76, FEATURE)
   3775 #endif // NO_BARRIER
   3776 }  // namespace test76
   3777 
   3778 
   3779 
   3780 // test77: TN. Ref counting, MU is annotated. {{{1
   3781 namespace test77 {
   3782 #ifndef NO_BARRIER
   3783 // same as test76, but RefCountedClass::MU is annotated.
   3784 int     GLOB = 0;
   3785 Barrier barrier(4);
   3786 RefCountedClass *object = NULL;
   3787 void Worker() {
   3788   object->Ref();
   3789   barrier.Block();
   3790   object->AccessData();
   3791   object->Unref();
   3792 }
   3793 void Run() {
   3794   printf("test77: true negative (ref counting), mutex is annotated\n");
   3795   RefCountedClass::Annotate_MU();
   3796   object = new RefCountedClass;
   3797   MyThreadArray t(Worker, Worker, Worker, Worker);
   3798   t.Start();
   3799   t.Join();
   3800 }
   3801 REGISTER_TEST(Run, 77)
   3802 #endif // NO_BARRIER
   3803 }  // namespace test77
   3804 
   3805 
   3806 
   3807 // test78: TN. Ref counting, Unref is annotated. {{{1
   3808 namespace test78 {
   3809 #ifndef NO_BARRIER
   3810 // same as test76, but RefCountedClass::Unref is annotated.
   3811 int     GLOB = 0;
   3812 Barrier barrier(4);
   3813 RefCountedClass *object = NULL;
   3814 void Worker() {
   3815   object->Ref();
   3816   barrier.Block();
   3817   object->AccessData();
   3818   object->Unref();
   3819 }
   3820 void Run() {
   3821   printf("test78: true negative (ref counting), Unref is annotated\n");
   3822   RefCountedClass::Annotate_MU();
   3823   object = new RefCountedClass;
   3824   MyThreadArray t(Worker, Worker, Worker, Worker);
   3825   t.Start();
   3826   t.Join();
   3827 }
   3828 REGISTER_TEST(Run, 78)
   3829 #endif // NO_BARRIER
   3830 }  // namespace test78
   3831 
   3832 
   3833 
   3834 // test79 TN. Swap. {{{1
   3835 namespace test79 {
   3836 #if 0
   3837 typedef __gnu_cxx::hash_map<int, int> map_t;
   3838 #else
   3839 typedef std::map<int, int> map_t;
   3840 #endif
   3841 map_t   MAP;
   3842 Mutex   MU;
   3843 
   3844 // Here we use swap to pass MAP between threads.
   3845 // The synchronization is correct, but w/o ANNOTATE_MUTEX_IS_USED_AS_CONDVAR
   3846 // Helgrind will complain.
   3847 
   3848 void Worker1() {
   3849   map_t tmp;
   3850   MU.Lock();
   3851   // We swap the new empty map 'tmp' with 'MAP'.
   3852   MAP.swap(tmp);
   3853   MU.Unlock();
   3854   // tmp (which is the old version of MAP) is destroyed here.
   3855 }
   3856 
   3857 void Worker2() {
   3858   MU.Lock();
   3859   MAP[1]++;  // Just update MAP under MU.
   3860   MU.Unlock();
   3861 }
   3862 
   3863 void Worker3() { Worker1(); }
   3864 void Worker4() { Worker2(); }
   3865 
   3866 void Run() {
   3867   ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(&MU);
   3868   printf("test79: negative\n");
   3869   MyThreadArray t(Worker1, Worker2, Worker3, Worker4);
   3870   t.Start();
   3871   t.Join();
   3872 }
   3873 REGISTER_TEST(Run, 79)
   3874 }  // namespace test79
   3875 
   3876 
   3877 // AtomicRefCountedClass. {{{1
   3878 // Same as RefCountedClass, but using atomic ops instead of mutex.
   3879 struct AtomicRefCountedClass {
   3880  public:
   3881   AtomicRefCountedClass() {
   3882     annotate_unref_ = false;
   3883     ref_ = 0;
   3884     data_ = 0;
   3885   }
   3886 
   3887   ~AtomicRefCountedClass() {
   3888     CHECK(ref_ == 0);     // race may be reported here
   3889     int data_val = data_; // and here
   3890     data_ = 0;
   3891     ref_ = -1;
   3892     printf("\tRefCountedClass::data_ = %d\n", data_val);
   3893   }
   3894 
   3895   void AccessData() {
   3896     this->mu_.Lock();
   3897     this->data_++;
   3898     this->mu_.Unlock();
   3899   }
   3900 
   3901   void Ref() {
   3902     AtomicIncrement(&ref_, 1);
   3903   }
   3904 
   3905   void Unref() {
   3906     // DISCLAIMER: I am not sure I've implemented this correctly
   3907     // (might require some memory barrier, etc).
   3908     // But this implementation of reference counting is enough for
   3909     // the purpose of Helgrind demonstration.
   3910     AtomicIncrement(&ref_, -1);
   3911     if (annotate_unref_) { ANNOTATE_CONDVAR_SIGNAL(this); }
   3912     if (ref_ == 0) {
   3913       if (annotate_unref_) { ANNOTATE_CONDVAR_WAIT(this); }
   3914       delete this;
   3915     }
   3916   }
   3917 
   3918   void AnnotateUnref() {
   3919     annotate_unref_ = true;
   3920   }
   3921   void Annotate_Race() {
   3922     ANNOTATE_BENIGN_RACE(&this->data_, "needs annotation");
   3923   }
   3924  private:
   3925   bool annotate_unref_;
   3926 
   3927   Mutex mu_;
   3928   int data_; // under mu_
   3929 
   3930   int ref_;  // used in atomic ops.
   3931 };
   3932 
   3933 // test80: FP. Ref counting with atomics, no annotations. {{{1
   3934 namespace test80 {
   3935 #ifndef NO_BARRIER
   3936 int     GLOB = 0;
   3937 Barrier barrier(4);
   3938 AtomicRefCountedClass *object = NULL;
   3939 void Worker() {
   3940   object->Ref();
   3941   barrier.Block();
   3942   object->AccessData();
   3943   object->Unref(); // All the tricky stuff is here.
   3944 }
   3945 void Run() {
   3946   printf("test80: false positive (ref counting)\n");
   3947   object = new AtomicRefCountedClass;
   3948   object->Annotate_Race();
   3949   MyThreadArray t(Worker, Worker, Worker, Worker);
   3950   t.Start();
   3951   t.Join();
   3952 }
   3953 REGISTER_TEST2(Run, 80, FEATURE|EXCLUDE_FROM_ALL)
   3954 #endif // NO_BARRIER
   3955 }  // namespace test80
   3956 
   3957 
   3958 // test81: TN. Ref counting with atomics, Unref is annotated. {{{1
   3959 namespace test81 {
   3960 #ifndef NO_BARRIER
   3961 // same as test80, but Unref is annotated.
   3962 int     GLOB = 0;
   3963 Barrier barrier(4);
   3964 AtomicRefCountedClass *object = NULL;
   3965 void Worker() {
   3966   object->Ref();
   3967   barrier.Block();
   3968   object->AccessData();
   3969   object->Unref(); // All the tricky stuff is here.
   3970 }
   3971 void Run() {
   3972   printf("test81: negative (annotated ref counting)\n");
   3973   object = new AtomicRefCountedClass;
   3974   object->AnnotateUnref();
   3975   MyThreadArray t(Worker, Worker, Worker, Worker);
   3976   t.Start();
   3977   t.Join();
   3978 }
   3979 REGISTER_TEST2(Run, 81, FEATURE|EXCLUDE_FROM_ALL)
   3980 #endif // NO_BARRIER
   3981 }  // namespace test81
   3982 
   3983 
   3984 // test82: Object published w/o synchronization. {{{1
   3985 namespace test82 {
   3986 
   3987 // Writer creates a new object and makes the pointer visible to the Reader.
   3988 // Reader waits until the object pointer is non-null and reads the object.
   3989 //
   3990 // On Core 2 Duo this test will sometimes (quite rarely) fail in
   3991 // the CHECK below, at least if compiled with -O2.
   3992 //
   3993 // The sequence of events::
   3994 // Thread1:                  Thread2:
   3995 //   a. arr_[...] = ...
   3996 //   b. foo[i]    = ...
   3997 //                           A. ... = foo[i]; // non NULL
   3998 //                           B. ... = arr_[...];
   3999 //
   4000 //  Since there is no proper synchronization, during the even (B)
   4001 //  Thread2 may not see the result of the event (a).
   4002 //  On x86 and x86_64 this happens due to compiler reordering instructions.
   4003 //  On other arcitectures it may also happen due to cashe inconsistency.
   4004 
   4005 class FOO {
   4006  public:
   4007   FOO() {
   4008     idx_ = rand() % 1024;
   4009     arr_[idx_] = 77777;
   4010   //   __asm__ __volatile__("" : : : "memory"); // this fixes!
   4011   }
   4012   static void check(volatile FOO *foo) {
   4013     CHECK(foo->arr_[foo->idx_] == 77777);
   4014   }
   4015  private:
   4016   int idx_;
   4017   int arr_[1024];
   4018 };
   4019 
   4020 const int N = 100000;
   4021 static volatile FOO *foo[N];
   4022 Mutex   MU;
   4023 
   4024 void Writer() {
   4025   for (int i = 0; i < N; i++) {
   4026     foo[i] = new FOO;
   4027     usleep(100);
   4028   }
   4029 }
   4030 
   4031 void Reader() {
   4032   for (int i = 0; i < N; i++) {
   4033     while (!foo[i]) {
   4034       MU.Lock();   // this is NOT a synchronization,
   4035       MU.Unlock(); // it just helps foo[i] to become visible in Reader.
   4036     }
   4037     if ((i % 100) == 0) {
   4038       printf("rd %d\n", i);
   4039     }
   4040     // At this point Reader() sees the new value of foo[i]
   4041     // but in very rare cases will not see the new value of foo[i]->arr_.
   4042     // Thus this CHECK will sometimes fail.
   4043     FOO::check(foo[i]);
   4044   }
   4045 }
   4046 
   4047 void Run() {
   4048   printf("test82: positive\n");
   4049   MyThreadArray t(Writer, Reader);
   4050   t.Start();
   4051   t.Join();
   4052 }
   4053 REGISTER_TEST2(Run, 82, FEATURE|EXCLUDE_FROM_ALL)
   4054 }  // namespace test82
   4055 
   4056 
   4057 // test83: Object published w/o synchronization (simple version){{{1
   4058 namespace test83 {
   4059 // A simplified version of test83 (example of a wrong code).
   4060 // This test, though incorrect, will almost never fail.
   4061 volatile static int *ptr = NULL;
   4062 Mutex   MU;
   4063 
   4064 void Writer() {
   4065   usleep(100);
   4066   ptr = new int(777);
   4067 }
   4068 
   4069 void Reader() {
   4070   while(!ptr) {
   4071     MU.Lock(); // Not a synchronization!
   4072     MU.Unlock();
   4073   }
   4074   CHECK(*ptr == 777);
   4075 }
   4076 
   4077 void Run() {
   4078 //  printf("test83: positive\n");
   4079   MyThreadArray t(Writer, Reader);
   4080   t.Start();
   4081   t.Join();
   4082 }
   4083 REGISTER_TEST2(Run, 83, FEATURE|EXCLUDE_FROM_ALL)
   4084 }  // namespace test83
   4085 
   4086 
   4087 // test84: TP. True race (regression test for a bug related to atomics){{{1
   4088 namespace test84 {
   4089 // Helgrind should not create HB arcs for the bus lock even when
   4090 // --pure-happens-before=yes is used.
   4091 // Bug found in by Bart Van Assche, the test is taken from
   4092 // valgrind file drd/tests/atomic_var.c.
   4093 static int s_x = 0;
   4094 /* s_dummy[] ensures that s_x and s_y are not in the same cache line. */
   4095 static char s_dummy[512] = {0};
   4096 static int s_y;
   4097 
   4098 void thread_func_1()
   4099 {
   4100   s_y = 1;
   4101   AtomicIncrement(&s_x, 1);
   4102 }
   4103 
   4104 void thread_func_2()
   4105 {
   4106   while (AtomicIncrement(&s_x, 0) == 0)
   4107     ;
   4108   printf("y = %d\n", s_y);
   4109 }
   4110 
   4111 
   4112 void Run() {
   4113   CHECK(s_dummy[0] == 0);  // Avoid compiler warning about 's_dummy unused'.
   4114   printf("test84: positive\n");
   4115   FAST_MODE_INIT(&s_y);
   4116   ANNOTATE_EXPECT_RACE_FOR_TSAN(&s_y, "test84: TP. true race.");
   4117   MyThreadArray t(thread_func_1, thread_func_2);
   4118   t.Start();
   4119   t.Join();
   4120 }
   4121 REGISTER_TEST(Run, 84)
   4122 }  // namespace test84
   4123 
   4124 
   4125 // test85: Test for RunningOnValgrind(). {{{1
   4126 namespace  test85 {
   4127 int     GLOB = 0;
   4128 void Run() {
   4129   printf("test85: RunningOnValgrind() = %d\n", RunningOnValgrind());
   4130 }
   4131 REGISTER_TEST(Run, 85)
   4132 }  // namespace test85
   4133 
   4134 
   4135 // test86: Test for race inside DTOR: racey write to vptr. Benign. {{{1
   4136 namespace test86 {
   4137 // This test shows a racey access to vptr (the pointer to vtbl).
   4138 // We have class A and class B derived from A.
   4139 // Both classes have a virtual function f() and a virtual DTOR.
   4140 // We create an object 'A *a = new B'
   4141 // and pass this object from Thread1 to Thread2.
   4142 // Thread2 calls a->f(). This call reads a->vtpr.
   4143 // Thread1 deletes the object. B::~B waits untill the object can be destroyed
   4144 // (flag_stopped == true) but at the very beginning of B::~B
   4145 // a->vptr is written to.
   4146 // So, we have a race on a->vptr.
   4147 // On this particular test this race is benign, but test87 shows
   4148 // how such race could harm.
   4149 //
   4150 //
   4151 //
   4152 // Threa1:                                            Thread2:
   4153 // 1. A a* = new B;
   4154 // 2. Q.Put(a); ------------\                         .
   4155 //                           \-------------------->   a. a = Q.Get();
   4156 //                                                    b. a->f();
   4157 //                                       /---------   c. flag_stopped = true;
   4158 // 3. delete a;                         /
   4159 //    waits untill flag_stopped <------/
   4160 //    inside the dtor
   4161 //
   4162 
   4163 bool flag_stopped = false;
   4164 Mutex mu;
   4165 
   4166 ProducerConsumerQueue Q(INT_MAX);  // Used to pass A* between threads.
   4167 
   4168 struct A {
   4169   A()  { printf("A::A()\n"); }
   4170   virtual ~A() { printf("A::~A()\n"); }
   4171   virtual void f() { }
   4172 
   4173   uintptr_t padding[15];
   4174 } __attribute__ ((aligned (64)));
   4175 
   4176 struct B: A {
   4177   B()  { printf("B::B()\n"); }
   4178   virtual ~B() {
   4179     // The race is here.    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   4180     printf("B::~B()\n");
   4181     // wait until flag_stopped is true.
   4182     mu.LockWhen(Condition(&ArgIsTrue, &flag_stopped));
   4183     mu.Unlock();
   4184     printf("B::~B() done\n");
   4185   }
   4186   virtual void f() { }
   4187 };
   4188 
   4189 void Waiter() {
   4190   A *a = new B;
   4191   if (!Tsan_FastMode())
   4192     ANNOTATE_EXPECT_RACE(a, "test86: expected race on a->vptr");
   4193   printf("Waiter: B created\n");
   4194   Q.Put(a);
   4195   usleep(100000); // so that Worker calls a->f() first.
   4196   printf("Waiter: deleting B\n");
   4197   delete a;
   4198   printf("Waiter: B deleted\n");
   4199   usleep(100000);
   4200   printf("Waiter: done\n");
   4201 }
   4202 
   4203 void Worker() {
   4204   A *a = reinterpret_cast<A*>(Q.Get());
   4205   printf("Worker: got A\n");
   4206   a->f();
   4207 
   4208   mu.Lock();
   4209   flag_stopped = true;
   4210   mu.Unlock();
   4211   usleep(200000);
   4212   printf("Worker: done\n");
   4213 }
   4214 
   4215 void Run() {
   4216   printf("test86: positive, race inside DTOR\n");
   4217   MyThreadArray t(Waiter, Worker);
   4218   t.Start();
   4219   t.Join();
   4220 }
   4221 REGISTER_TEST(Run, 86)
   4222 }  // namespace test86
   4223 
   4224 
   4225 // test87: Test for race inside DTOR: racey write to vptr. Harmful.{{{1
   4226 namespace test87 {
   4227 // A variation of test86 where the race is harmful.
   4228 // Here we have class C derived from B.
   4229 // We create an object 'A *a = new C' in Thread1 and pass it to Thread2.
   4230 // Thread2 calls a->f().
   4231 // Thread1 calls 'delete a'.
   4232 // It first calls C::~C, then B::~B where it rewrites the vptr to point
   4233 // to B::vtbl. This is a problem because Thread2 might not have called a->f()
   4234 // and now it will call B::f instead of C::f.
   4235 //
   4236 bool flag_stopped = false;
   4237 Mutex mu;
   4238 
   4239 ProducerConsumerQueue Q(INT_MAX);  // Used to pass A* between threads.
   4240 
   4241 struct A {
   4242   A()  { printf("A::A()\n"); }
   4243   virtual ~A() { printf("A::~A()\n"); }
   4244   virtual void f() = 0; // pure virtual.
   4245 };
   4246 
   4247 struct B: A {
   4248   B()  { printf("B::B()\n"); }
   4249   virtual ~B() {
   4250     // The race is here.    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   4251     printf("B::~B()\n");
   4252     // wait until flag_stopped is true.
   4253     mu.LockWhen(Condition(&ArgIsTrue, &flag_stopped));
   4254     mu.Unlock();
   4255     printf("B::~B() done\n");
   4256   }
   4257   virtual void f() = 0; // pure virtual.
   4258 };
   4259 
   4260 struct C: B {
   4261   C()  { printf("C::C()\n"); }
   4262   virtual ~C() { printf("C::~C()\n"); }
   4263   virtual void f() { }
   4264 };
   4265 
   4266 void Waiter() {
   4267   A *a = new C;
   4268   Q.Put(a);
   4269   delete a;
   4270 }
   4271 
   4272 void Worker() {
   4273   A *a = reinterpret_cast<A*>(Q.Get());
   4274   a->f();
   4275 
   4276   mu.Lock();
   4277   flag_stopped = true;
   4278   ANNOTATE_CONDVAR_SIGNAL(&mu);
   4279   mu.Unlock();
   4280 }
   4281 
   4282 void Run() {
   4283   printf("test87: positive, race inside DTOR\n");
   4284   MyThreadArray t(Waiter, Worker);
   4285   t.Start();
   4286   t.Join();
   4287 }
   4288 REGISTER_TEST2(Run, 87, FEATURE|EXCLUDE_FROM_ALL)
   4289 }  // namespace test87
   4290 
   4291 
   4292 // test88: Test for ANNOTATE_IGNORE_WRITES_*{{{1
   4293 namespace test88 {
   4294 // a recey write annotated with ANNOTATE_IGNORE_WRITES_BEGIN/END.
   4295 int     GLOB = 0;
   4296 void Worker() {
   4297   ANNOTATE_IGNORE_WRITES_BEGIN();
   4298   GLOB = 1;
   4299   ANNOTATE_IGNORE_WRITES_END();
   4300 }
   4301 void Run() {
   4302   printf("test88: negative, test for ANNOTATE_IGNORE_WRITES_*\n");
   4303   MyThread t(Worker);
   4304   t.Start();
   4305   GLOB = 1;
   4306   t.Join();
   4307   printf("\tGLOB=%d\n", GLOB);
   4308 }
   4309 REGISTER_TEST(Run, 88)
   4310 }  // namespace test88
   4311 
   4312 
   4313 // test89: Test for debug info. {{{1
   4314 namespace test89 {
   4315 // Simlpe races with different objects (stack, heap globals; scalars, structs).
   4316 // Also, if run with --trace-level=2 this test will show a sequence of
   4317 // CTOR and DTOR calls.
   4318 struct STRUCT {
   4319   int a, b, c;
   4320 };
   4321 
   4322 struct A {
   4323   int a;
   4324   A() {
   4325     ANNOTATE_TRACE_MEMORY(&a);
   4326     a = 1;
   4327   }
   4328   virtual ~A() {
   4329     a = 4;
   4330   }
   4331 };
   4332 
   4333 struct B : A {
   4334   B()  { CHECK(a == 1); }
   4335   virtual ~B() { CHECK(a == 3); }
   4336 };
   4337 struct C : B {
   4338   C()  { a = 2; }
   4339   virtual ~C() { a = 3; }
   4340 };
   4341 
   4342 int            GLOBAL = 0;
   4343 int           *STACK  = 0;
   4344 STRUCT         GLOB_STRUCT;
   4345 STRUCT        *STACK_STRUCT;
   4346 STRUCT        *HEAP_STRUCT;
   4347 
   4348 void Worker() {
   4349   GLOBAL = 1;
   4350   *STACK = 1;
   4351   GLOB_STRUCT.b   = 1;
   4352   STACK_STRUCT->b = 1;
   4353   HEAP_STRUCT->b  = 1;
   4354 }
   4355 
   4356 void Run() {
   4357   int stack_var = 0;
   4358   STACK = &stack_var;
   4359 
   4360   STRUCT stack_struct;
   4361   STACK_STRUCT = &stack_struct;
   4362 
   4363   HEAP_STRUCT = new STRUCT;
   4364 
   4365   printf("test89: negative\n");
   4366   MyThreadArray t(Worker, Worker);
   4367   t.Start();
   4368   t.Join();
   4369 
   4370   delete HEAP_STRUCT;
   4371 
   4372   A *a = new C;
   4373   printf("Using 'a->a':  %d\n", a->a);
   4374   delete a;
   4375 }
   4376 REGISTER_TEST2(Run, 89, FEATURE|EXCLUDE_FROM_ALL)
   4377 }  // namespace test89
   4378 
   4379 
   4380 // test90: FP. Test for a safely-published pointer (read-only). {{{1
   4381 namespace test90 {
   4382 // The Publisher creates an object and safely publishes it under a mutex.
   4383 // Readers access the object read-only.
   4384 // See also test91.
   4385 //
   4386 // Without annotations Helgrind will issue a false positive in Reader().
   4387 //
   4388 // Choices for annotations:
   4389 //   -- ANNOTATE_CONDVAR_SIGNAL/ANNOTATE_CONDVAR_WAIT
   4390 //   -- ANNOTATE_MUTEX_IS_USED_AS_CONDVAR
   4391 //   -- ANNOTATE_PUBLISH_MEMORY_RANGE.
   4392 
   4393 int     *GLOB = 0;
   4394 Mutex   MU;
   4395 
   4396 void Publisher() {
   4397   MU.Lock();
   4398   GLOB = (int*)memalign(64, sizeof(int));
   4399   *GLOB = 777;
   4400   if (!Tsan_PureHappensBefore() && !Tsan_FastMode())
   4401     ANNOTATE_EXPECT_RACE_FOR_TSAN(GLOB, "test90. FP. This is a false positve");
   4402   MU.Unlock();
   4403   usleep(200000);
   4404 }
   4405 
   4406 void Reader() {
   4407   usleep(10000);
   4408   while (true) {
   4409     MU.Lock();
   4410     int *p = GLOB;
   4411     MU.Unlock();
   4412     if (p) {
   4413       CHECK(*p == 777);  // Race is reported here.
   4414       break;
   4415     }
   4416   }
   4417 }
   4418 
   4419 void Run() {
   4420   printf("test90: false positive (safely published pointer).\n");
   4421   MyThreadArray t(Publisher, Reader, Reader, Reader);
   4422   t.Start();
   4423   t.Join();
   4424   printf("\t*GLOB=%d\n", *GLOB);
   4425   free(GLOB);
   4426 }
   4427 REGISTER_TEST(Run, 90)
   4428 }  // namespace test90
   4429 
   4430 
   4431 // test91: FP. Test for a safely-published pointer (read-write). {{{1
   4432 namespace test91 {
   4433 // Similar to test90.
   4434 // The Publisher creates an object and safely publishes it under a mutex MU1.
   4435 // Accessors get the object under MU1 and access it (read/write) under MU2.
   4436 //
   4437 // Without annotations Helgrind will issue a false positive in Accessor().
   4438 //
   4439 
   4440 int     *GLOB = 0;
   4441 Mutex   MU, MU1, MU2;
   4442 
   4443 void Publisher() {
   4444   MU1.Lock();
   4445   GLOB = (int*)memalign(64, sizeof(int));
   4446   *GLOB = 777;
   4447   if (!Tsan_PureHappensBefore() && !Tsan_FastMode())
   4448     ANNOTATE_EXPECT_RACE_FOR_TSAN(GLOB, "test91. FP. This is a false positve");
   4449   MU1.Unlock();
   4450 }
   4451 
   4452 void Accessor() {
   4453   usleep(10000);
   4454   while (true) {
   4455     MU1.Lock();
   4456     int *p = GLOB;
   4457     MU1.Unlock();
   4458     if (p) {
   4459       MU2.Lock();
   4460       (*p)++;  // Race is reported here.
   4461       CHECK(*p >  777);
   4462       MU2.Unlock();
   4463       break;
   4464     }
   4465   }
   4466 }
   4467 
   4468 void Run() {
   4469   printf("test91: false positive (safely published pointer, read/write).\n");
   4470   MyThreadArray t(Publisher, Accessor, Accessor, Accessor);
   4471   t.Start();
   4472   t.Join();
   4473   printf("\t*GLOB=%d\n", *GLOB);
   4474   free(GLOB);
   4475 }
   4476 REGISTER_TEST(Run, 91)
   4477 }  // namespace test91
   4478 
   4479 
   4480 // test92: TN. Test for a safely-published pointer (read-write), annotated. {{{1
   4481 namespace test92 {
   4482 // Similar to test91, but annotated with ANNOTATE_PUBLISH_MEMORY_RANGE.
   4483 //
   4484 //
   4485 // Publisher:                                       Accessors:
   4486 //
   4487 // 1. MU1.Lock()
   4488 // 2. Create GLOB.
   4489 // 3. ANNOTATE_PUBLISH_...(GLOB) -------\            .
   4490 // 4. MU1.Unlock()                       \           .
   4491 //                                        \          a. MU1.Lock()
   4492 //                                         \         b. Get GLOB
   4493 //                                          \        c. MU1.Unlock()
   4494 //                                           \-->    d. Access GLOB
   4495 //
   4496 //  A happens-before arc is created between ANNOTATE_PUBLISH_MEMORY_RANGE and
   4497 //  accesses to GLOB.
   4498 
   4499 struct ObjType {
   4500   int arr[10];
   4501 };
   4502 
   4503 ObjType *GLOB = 0;
   4504 Mutex   MU, MU1, MU2;
   4505 
   4506 void Publisher() {
   4507   MU1.Lock();
   4508   GLOB = new ObjType;
   4509   for (int i = 0; i < 10; i++) {
   4510     GLOB->arr[i] = 777;
   4511   }
   4512   // This annotation should go right before the object is published.
   4513   ANNOTATE_PUBLISH_MEMORY_RANGE(GLOB, sizeof(*GLOB));
   4514   MU1.Unlock();
   4515 }
   4516 
   4517 void Accessor(int index) {
   4518   while (true) {
   4519     MU1.Lock();
   4520     ObjType *p = GLOB;
   4521     MU1.Unlock();
   4522     if (p) {
   4523       MU2.Lock();
   4524       p->arr[index]++;  // W/o the annotations the race will be reported here.
   4525       CHECK(p->arr[index] ==  778);
   4526       MU2.Unlock();
   4527       break;
   4528     }
   4529   }
   4530 }
   4531 
   4532 void Accessor0() { Accessor(0); }
   4533 void Accessor5() { Accessor(5); }
   4534 void Accessor9() { Accessor(9); }
   4535 
   4536 void Run() {
   4537   printf("test92: safely published pointer, read/write, annotated.\n");
   4538   MyThreadArray t(Publisher, Accessor0, Accessor5, Accessor9);
   4539   t.Start();
   4540   t.Join();
   4541   printf("\t*GLOB=%d\n", GLOB->arr[0]);
   4542 }
   4543 REGISTER_TEST(Run, 92)
   4544 }  // namespace test92
   4545 
   4546 
   4547 // test93: TP. Test for incorrect usage of ANNOTATE_PUBLISH_MEMORY_RANGE. {{{1
   4548 namespace test93 {
   4549 int     GLOB = 0;
   4550 
   4551 void Reader() {
   4552   CHECK(GLOB == 0);
   4553 }
   4554 
   4555 void Publisher() {
   4556   usleep(10000);
   4557   // Incorrect, used after the memory has been accessed in another thread.
   4558   ANNOTATE_PUBLISH_MEMORY_RANGE(&GLOB, sizeof(GLOB));
   4559 }
   4560 
   4561 void Run() {
   4562   printf("test93: positive, misuse of ANNOTATE_PUBLISH_MEMORY_RANGE\n");
   4563   MyThreadArray t(Reader, Publisher);
   4564   t.Start();
   4565   t.Join();
   4566   printf("\tGLOB=%d\n", GLOB);
   4567 }
   4568 REGISTER_TEST2(Run, 93, FEATURE|EXCLUDE_FROM_ALL)
   4569 }  // namespace test93
   4570 
   4571 
   4572 // test94: TP. Check do_cv_signal/fake segment logic {{{1
   4573 namespace test94 {
   4574 int     GLOB;
   4575 
   4576 int COND  = 0;
   4577 int COND2 = 0;
   4578 Mutex MU, MU2;
   4579 CondVar CV, CV2;
   4580 
   4581 void Thr1() {
   4582   usleep(10000);  // Make sure the waiter blocks.
   4583 
   4584   GLOB = 1; // WRITE
   4585 
   4586   MU.Lock();
   4587   COND = 1;
   4588   CV.Signal();
   4589   MU.Unlock();
   4590 }
   4591 void Thr2() {
   4592   usleep(1000*1000); // Make sure CV2.Signal() "happens after" CV.Signal()
   4593   usleep(10000);  // Make sure the waiter blocks.
   4594 
   4595   MU2.Lock();
   4596   COND2 = 1;
   4597   CV2.Signal();
   4598   MU2.Unlock();
   4599 }
   4600 void Thr3() {
   4601   MU.Lock();
   4602   while(COND != 1)
   4603     CV.Wait(&MU);
   4604   MU.Unlock();
   4605 }
   4606 void Thr4() {
   4607   MU2.Lock();
   4608   while(COND2 != 1)
   4609     CV2.Wait(&MU2);
   4610   MU2.Unlock();
   4611   GLOB = 2; // READ: no HB-relation between CV.Signal and CV2.Wait !
   4612 }
   4613 void Run() {
   4614   FAST_MODE_INIT(&GLOB);
   4615   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test94: TP.");
   4616   printf("test94: TP. Check do_cv_signal/fake segment logic\n");
   4617   MyThreadArray mta(Thr1, Thr2, Thr3, Thr4);
   4618   mta.Start();
   4619   mta.Join();
   4620   printf("\tGLOB=%d\n", GLOB);
   4621 }
   4622 REGISTER_TEST(Run, 94);
   4623 }  // namespace test94
   4624 
   4625 // test95: TP. Check do_cv_signal/fake segment logic {{{1
   4626 namespace test95 {
   4627 int     GLOB = 0;
   4628 
   4629 int COND  = 0;
   4630 int COND2 = 0;
   4631 Mutex MU, MU2;
   4632 CondVar CV, CV2;
   4633 
   4634 void Thr1() {
   4635   usleep(1000*1000); // Make sure CV2.Signal() "happens before" CV.Signal()
   4636   usleep(10000);  // Make sure the waiter blocks.
   4637 
   4638   GLOB = 1; // WRITE
   4639 
   4640   MU.Lock();
   4641   COND = 1;
   4642   CV.Signal();
   4643   MU.Unlock();
   4644 }
   4645 void Thr2() {
   4646   usleep(10000);  // Make sure the waiter blocks.
   4647 
   4648   MU2.Lock();
   4649   COND2 = 1;
   4650   CV2.Signal();
   4651   MU2.Unlock();
   4652 }
   4653 void Thr3() {
   4654   MU.Lock();
   4655   while(COND != 1)
   4656     CV.Wait(&MU);
   4657   MU.Unlock();
   4658 }
   4659 void Thr4() {
   4660   MU2.Lock();
   4661   while(COND2 != 1)
   4662     CV2.Wait(&MU2);
   4663   MU2.Unlock();
   4664   GLOB = 2; // READ: no HB-relation between CV.Signal and CV2.Wait !
   4665 }
   4666 void Run() {
   4667   FAST_MODE_INIT(&GLOB);
   4668   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test95: TP.");
   4669   printf("test95: TP. Check do_cv_signal/fake segment logic\n");
   4670   MyThreadArray mta(Thr1, Thr2, Thr3, Thr4);
   4671   mta.Start();
   4672   mta.Join();
   4673   printf("\tGLOB=%d\n", GLOB);
   4674 }
   4675 REGISTER_TEST(Run, 95);
   4676 }  // namespace test95
   4677 
   4678 // test96: TN. tricky LockSet behaviour {{{1
   4679 // 3 threads access the same memory with three different
   4680 // locksets: {A, B}, {B, C}, {C, A}.
   4681 // These locksets have empty intersection
   4682 namespace test96 {
   4683 int     GLOB = 0;
   4684 
   4685 Mutex A, B, C;
   4686 
   4687 void Thread1() {
   4688   MutexLock a(&A);
   4689   MutexLock b(&B);
   4690   GLOB++;
   4691 }
   4692 
   4693 void Thread2() {
   4694   MutexLock b(&B);
   4695   MutexLock c(&C);
   4696   GLOB++;
   4697 }
   4698 
   4699 void Thread3() {
   4700   MutexLock a(&A);
   4701   MutexLock c(&C);
   4702   GLOB++;
   4703 }
   4704 
   4705 void Run() {
   4706   printf("test96: FP. tricky LockSet behaviour\n");
   4707   ANNOTATE_TRACE_MEMORY(&GLOB);
   4708   MyThreadArray mta(Thread1, Thread2, Thread3);
   4709   mta.Start();
   4710   mta.Join();
   4711   CHECK(GLOB == 3);
   4712   printf("\tGLOB=%d\n", GLOB);
   4713 }
   4714 REGISTER_TEST(Run, 96);
   4715 }  // namespace test96
   4716 
   4717 // test97: This test shows false negative with --fast-mode=yes {{{1
   4718 namespace test97 {
   4719 const int HG_CACHELINE_SIZE = 64;
   4720 
   4721 Mutex MU;
   4722 
   4723 const int ARRAY_SIZE = HG_CACHELINE_SIZE * 4 / sizeof(int);
   4724 int array[ARRAY_SIZE];
   4725 int * GLOB = &array[ARRAY_SIZE/2];
   4726 /*
   4727   We use sizeof(array) == 4 * HG_CACHELINE_SIZE to be sure that GLOB points
   4728   to a memory inside a CacheLineZ which is inside array's memory range
   4729  */
   4730 
   4731 void Reader() {
   4732   usleep(500000);
   4733   CHECK(777 == *GLOB);
   4734 }
   4735 
   4736 void Run() {
   4737   MyThreadArray t(Reader);
   4738   if (!Tsan_FastMode())
   4739     ANNOTATE_EXPECT_RACE_FOR_TSAN(GLOB, "test97: TP. FN with --fast-mode=yes");
   4740   printf("test97: This test shows false negative with --fast-mode=yes\n");
   4741 
   4742   t.Start();
   4743   *GLOB = 777;
   4744   t.Join();
   4745 }
   4746 
   4747 REGISTER_TEST2(Run, 97, FEATURE)
   4748 }  // namespace test97
   4749 
   4750 // test98: Synchronization via read/write (or send/recv). {{{1
   4751 namespace test98 {
   4752 // The synchronization here is done by a pair of read/write calls
   4753 // that create a happens-before arc. Same may be done with send/recv.
   4754 // Such synchronization is quite unusual in real programs
   4755 // (why would one synchronizae via a file or socket?), but
   4756 // quite possible in unittests where one threads runs for producer
   4757 // and one for consumer.
   4758 //
   4759 // A race detector has to create a happens-before arcs for
   4760 // {read,send}->{write,recv} even if the file descriptors are different.
   4761 //
   4762 int     GLOB = 0;
   4763 int fd_out = -1;
   4764 int fd_in  = -1;
   4765 
   4766 void Writer() {
   4767   usleep(1000);
   4768   GLOB = 1;
   4769   const char *str = "Hey there!\n";
   4770   IGNORE_RETURN_VALUE(write(fd_out, str, strlen(str) + 1));
   4771 }
   4772 
   4773 void Reader() {
   4774   char buff[100];
   4775   while (read(fd_in, buff, 100) == 0)
   4776     sleep(1);
   4777   printf("read: %s\n", buff);
   4778   GLOB = 2;
   4779 }
   4780 
   4781 void Run() {
   4782   printf("test98: negative, synchronization via I/O\n");
   4783   char in_name[100];
   4784   char out_name[100];
   4785   // we open two files, on for reading and one for writing,
   4786   // but the files are actually the same (symlinked).
   4787   sprintf(out_name, "/tmp/racecheck_unittest_out.%d", getpid());
   4788   fd_out = creat(out_name, O_WRONLY | S_IRWXU);
   4789 #ifdef __APPLE__
   4790   // symlink() is not supported on Darwin. Copy the output file name.
   4791   strcpy(in_name, out_name);
   4792 #else
   4793   sprintf(in_name,  "/tmp/racecheck_unittest_in.%d", getpid());
   4794   IGNORE_RETURN_VALUE(symlink(out_name, in_name));
   4795 #endif
   4796   fd_in  = open(in_name, 0, O_RDONLY);
   4797   CHECK(fd_out >= 0);
   4798   CHECK(fd_in  >= 0);
   4799   MyThreadArray t(Writer, Reader);
   4800   t.Start();
   4801   t.Join();
   4802   printf("\tGLOB=%d\n", GLOB);
   4803   // cleanup
   4804   close(fd_in);
   4805   close(fd_out);
   4806   unlink(in_name);
   4807   unlink(out_name);
   4808 }
   4809 REGISTER_TEST(Run, 98)
   4810 }  // namespace test98
   4811 
   4812 
   4813 // test99: TP. Unit test for a bug in LockWhen*. {{{1
   4814 namespace test99 {
   4815 
   4816 
   4817 bool GLOB = false;
   4818 Mutex mu;
   4819 
   4820 static void Thread1() {
   4821   for (int i = 0; i < 100; i++) {
   4822     mu.LockWhenWithTimeout(Condition(&ArgIsTrue, &GLOB), 5);
   4823     GLOB = false;
   4824     mu.Unlock();
   4825     usleep(10000);
   4826   }
   4827 }
   4828 
   4829 static void Thread2() {
   4830   for (int i = 0; i < 100; i++) {
   4831     mu.Lock();
   4832     mu.Unlock();
   4833     usleep(10000);
   4834   }
   4835 }
   4836 
   4837 void Run() {
   4838   printf("test99: regression test for LockWhen*\n");
   4839   MyThreadArray t(Thread1, Thread2);
   4840   t.Start();
   4841   t.Join();
   4842 }
   4843 REGISTER_TEST(Run, 99);
   4844 }  // namespace test99
   4845 
   4846 
   4847 // test100: Test for initialization bit. {{{1
   4848 namespace test100 {
   4849 int     G1 = 0;
   4850 int     G2 = 0;
   4851 int     G3 = 0;
   4852 int     G4 = 0;
   4853 
   4854 void Creator() {
   4855   G1 = 1; CHECK(G1);
   4856   G2 = 1;
   4857   G3 = 1; CHECK(G3);
   4858   G4 = 1;
   4859 }
   4860 
   4861 void Worker1() {
   4862   usleep(100000);
   4863   CHECK(G1);
   4864   CHECK(G2);
   4865   G3 = 3;
   4866   G4 = 3;
   4867 }
   4868 
   4869 void Worker2() {
   4870 
   4871 }
   4872 
   4873 
   4874 void Run() {
   4875   printf("test100: test for initialization bit. \n");
   4876   MyThreadArray t(Creator, Worker1, Worker2);
   4877   ANNOTATE_TRACE_MEMORY(&G1);
   4878   ANNOTATE_TRACE_MEMORY(&G2);
   4879   ANNOTATE_TRACE_MEMORY(&G3);
   4880   ANNOTATE_TRACE_MEMORY(&G4);
   4881   t.Start();
   4882   t.Join();
   4883 }
   4884 REGISTER_TEST2(Run, 100, FEATURE|EXCLUDE_FROM_ALL)
   4885 }  // namespace test100
   4886 
   4887 
   4888 // test101: TN. Two signals and two waits. {{{1
   4889 namespace test101 {
   4890 Mutex MU;
   4891 CondVar CV;
   4892 int     GLOB = 0;
   4893 
   4894 int C1 = 0, C2 = 0;
   4895 
   4896 void Signaller() {
   4897   usleep(100000);
   4898   MU.Lock();
   4899   C1 = 1;
   4900   CV.Signal();
   4901   printf("signal\n");
   4902   MU.Unlock();
   4903 
   4904   GLOB = 1;
   4905 
   4906   usleep(500000);
   4907   MU.Lock();
   4908   C2 = 1;
   4909   CV.Signal();
   4910   printf("signal\n");
   4911   MU.Unlock();
   4912 }
   4913 
   4914 void Waiter() {
   4915   MU.Lock();
   4916   while(!C1)
   4917     CV.Wait(&MU);
   4918   printf("wait\n");
   4919   MU.Unlock();
   4920 
   4921   MU.Lock();
   4922   while(!C2)
   4923     CV.Wait(&MU);
   4924   printf("wait\n");
   4925   MU.Unlock();
   4926 
   4927   GLOB = 2;
   4928 
   4929 }
   4930 
   4931 void Run() {
   4932   printf("test101: negative\n");
   4933   MyThreadArray t(Waiter, Signaller);
   4934   t.Start();
   4935   t.Join();
   4936   printf("\tGLOB=%d\n", GLOB);
   4937 }
   4938 REGISTER_TEST(Run, 101)
   4939 }  // namespace test101
   4940 
   4941 // test102: --fast-mode=yes vs. --initialization-bit=yes {{{1
   4942 namespace test102 {
   4943 const int HG_CACHELINE_SIZE = 64;
   4944 
   4945 Mutex MU;
   4946 
   4947 const int ARRAY_SIZE = HG_CACHELINE_SIZE * 4 / sizeof(int);
   4948 int array[ARRAY_SIZE + 1];
   4949 int * GLOB = &array[ARRAY_SIZE/2];
   4950 /*
   4951   We use sizeof(array) == 4 * HG_CACHELINE_SIZE to be sure that GLOB points
   4952   to a memory inside a CacheLineZ which is inside array's memory range
   4953 */
   4954 
   4955 void Reader() {
   4956   usleep(200000);
   4957   CHECK(777 == GLOB[0]);
   4958   usleep(400000);
   4959   CHECK(777 == GLOB[1]);
   4960 }
   4961 
   4962 void Run() {
   4963   MyThreadArray t(Reader);
   4964   if (!Tsan_FastMode())
   4965     ANNOTATE_EXPECT_RACE_FOR_TSAN(GLOB+0, "test102: TP. FN with --fast-mode=yes");
   4966   ANNOTATE_EXPECT_RACE_FOR_TSAN(GLOB+1, "test102: TP");
   4967   printf("test102: --fast-mode=yes vs. --initialization-bit=yes\n");
   4968 
   4969   t.Start();
   4970   GLOB[0] = 777;
   4971   usleep(400000);
   4972   GLOB[1] = 777;
   4973   t.Join();
   4974 }
   4975 
   4976 REGISTER_TEST2(Run, 102, FEATURE)
   4977 }  // namespace test102
   4978 
   4979 // test103: Access different memory locations with different LockSets {{{1
   4980 namespace test103 {
   4981 const int N_MUTEXES = 6;
   4982 const int LOCKSET_INTERSECTION_SIZE = 3;
   4983 
   4984 int data[1 << LOCKSET_INTERSECTION_SIZE] = {0};
   4985 Mutex MU[N_MUTEXES];
   4986 
   4987 inline int LS_to_idx (int ls) {
   4988   return (ls >> (N_MUTEXES - LOCKSET_INTERSECTION_SIZE))
   4989       & ((1 << LOCKSET_INTERSECTION_SIZE) - 1);
   4990 }
   4991 
   4992 void Worker() {
   4993   for (int ls = 0; ls < (1 << N_MUTEXES); ls++) {
   4994     if (LS_to_idx(ls) == 0)
   4995       continue;
   4996     for (int m = 0; m < N_MUTEXES; m++)
   4997       if (ls & (1 << m))
   4998         MU[m].Lock();
   4999 
   5000     data[LS_to_idx(ls)]++;
   5001 
   5002     for (int m = N_MUTEXES - 1; m >= 0; m--)
   5003       if (ls & (1 << m))
   5004         MU[m].Unlock();
   5005   }
   5006 }
   5007 
   5008 void Run() {
   5009   printf("test103: Access different memory locations with different LockSets\n");
   5010   MyThreadArray t(Worker, Worker, Worker, Worker);
   5011   t.Start();
   5012   t.Join();
   5013 }
   5014 REGISTER_TEST2(Run, 103, FEATURE)
   5015 }  // namespace test103
   5016 
   5017 // test104: TP. Simple race (write vs write). Heap mem. {{{1
   5018 namespace test104 {
   5019 int     *GLOB = NULL;
   5020 void Worker() {
   5021   *GLOB = 1;
   5022 }
   5023 
   5024 void Parent() {
   5025   MyThread t(Worker);
   5026   t.Start();
   5027   usleep(100000);
   5028   *GLOB = 2;
   5029   t.Join();
   5030 }
   5031 void Run() {
   5032   GLOB = (int*)memalign(64, sizeof(int));
   5033   *GLOB = 0;
   5034   ANNOTATE_EXPECT_RACE(GLOB, "test104. TP.");
   5035   ANNOTATE_TRACE_MEMORY(GLOB);
   5036   printf("test104: positive\n");
   5037   Parent();
   5038   printf("\tGLOB=%d\n", *GLOB);
   5039   free(GLOB);
   5040 }
   5041 REGISTER_TEST(Run, 104);
   5042 }  // namespace test104
   5043 
   5044 
   5045 // test105: Checks how stack grows. {{{1
   5046 namespace test105 {
   5047 int     GLOB = 0;
   5048 
   5049 void F1() {
   5050   int ar[32];
   5051 //  ANNOTATE_TRACE_MEMORY(&ar[0]);
   5052 //  ANNOTATE_TRACE_MEMORY(&ar[31]);
   5053   ar[0] = 1;
   5054   ar[31] = 1;
   5055 }
   5056 
   5057 void Worker() {
   5058   int ar[32];
   5059 //  ANNOTATE_TRACE_MEMORY(&ar[0]);
   5060 //  ANNOTATE_TRACE_MEMORY(&ar[31]);
   5061   ar[0] = 1;
   5062   ar[31] = 1;
   5063   F1();
   5064 }
   5065 
   5066 void Run() {
   5067   printf("test105: negative\n");
   5068   Worker();
   5069   MyThread t(Worker);
   5070   t.Start();
   5071   t.Join();
   5072   printf("\tGLOB=%d\n", GLOB);
   5073 }
   5074 REGISTER_TEST(Run, 105)
   5075 }  // namespace test105
   5076 
   5077 
   5078 // test106: TN. pthread_once. {{{1
   5079 namespace test106 {
   5080 int     *GLOB = NULL;
   5081 static pthread_once_t once = PTHREAD_ONCE_INIT;
   5082 void Init() {
   5083   GLOB = new int;
   5084   ANNOTATE_TRACE_MEMORY(GLOB);
   5085   *GLOB = 777;
   5086 }
   5087 
   5088 void Worker0() {
   5089   pthread_once(&once, Init);
   5090 }
   5091 void Worker1() {
   5092   usleep(100000);
   5093   pthread_once(&once, Init);
   5094   CHECK(*GLOB == 777);
   5095 }
   5096 
   5097 
   5098 void Run() {
   5099   printf("test106: negative\n");
   5100   MyThreadArray t(Worker0, Worker1, Worker1, Worker1);
   5101   t.Start();
   5102   t.Join();
   5103   printf("\tGLOB=%d\n", *GLOB);
   5104 }
   5105 REGISTER_TEST2(Run, 106, FEATURE)
   5106 }  // namespace test106
   5107 
   5108 
   5109 // test107: Test for ANNOTATE_EXPECT_RACE {{{1
   5110 namespace test107 {
   5111 int     GLOB = 0;
   5112 void Run() {
   5113   printf("test107: negative\n");
   5114   ANNOTATE_EXPECT_RACE(&GLOB, "No race in fact. Just checking the tool.");
   5115   printf("\tGLOB=%d\n", GLOB);
   5116 }
   5117 REGISTER_TEST2(Run, 107, FEATURE|EXCLUDE_FROM_ALL)
   5118 }  // namespace test107
   5119 
   5120 
   5121 // test108: TN. initialization of static object. {{{1
   5122 namespace test108 {
   5123 // Here we have a function-level static object.
   5124 // Starting from gcc 4 this is therad safe,
   5125 // but is is not thread safe with many other compilers.
   5126 //
   5127 // Helgrind supports this kind of initialization by
   5128 // intercepting __cxa_guard_acquire/__cxa_guard_release
   5129 // and ignoring all accesses between them.
   5130 // Helgrind also intercepts pthread_once in the same manner.
   5131 class Foo {
   5132  public:
   5133   Foo() {
   5134     ANNOTATE_TRACE_MEMORY(&a_);
   5135     a_ = 42;
   5136   }
   5137   void Check() const { CHECK(a_ == 42); }
   5138  private:
   5139   int a_;
   5140 };
   5141 
   5142 const Foo *GetFoo() {
   5143   static const Foo *foo = new Foo();
   5144   return foo;
   5145 }
   5146 void Worker0() {
   5147   GetFoo();
   5148 }
   5149 
   5150 void Worker() {
   5151   usleep(200000);
   5152   const Foo *foo = GetFoo();
   5153   foo->Check();
   5154 }
   5155 
   5156 
   5157 void Run() {
   5158   printf("test108: negative, initialization of static object\n");
   5159   MyThreadArray t(Worker0, Worker, Worker);
   5160   t.Start();
   5161   t.Join();
   5162 }
   5163 REGISTER_TEST2(Run, 108, FEATURE)
   5164 }  // namespace test108
   5165 
   5166 
   5167 // test109: TN. Checking happens before between parent and child threads. {{{1
   5168 namespace test109 {
   5169 // Check that the detector correctly connects
   5170 //   pthread_create with the new thread
   5171 // and
   5172 //   thread exit with pthread_join
   5173 const int N = 32;
   5174 static int GLOB[N];
   5175 
   5176 void Worker(void *a) {
   5177   usleep(10000);
   5178 //  printf("--Worker : %ld %p\n", (int*)a - GLOB, (void*)pthread_self());
   5179   int *arg = (int*)a;
   5180   (*arg)++;
   5181 }
   5182 
   5183 void Run() {
   5184   printf("test109: negative\n");
   5185   MyThread *t[N];
   5186   for (int i  = 0; i < N; i++) {
   5187     t[i] = new MyThread(Worker, &GLOB[i]);
   5188   }
   5189   for (int i  = 0; i < N; i++) {
   5190     ANNOTATE_TRACE_MEMORY(&GLOB[i]);
   5191     GLOB[i] = 1;
   5192     t[i]->Start();
   5193 //    printf("--Started: %p\n", (void*)t[i]->tid());
   5194   }
   5195   for (int i  = 0; i < N; i++) {
   5196 //    printf("--Joining: %p\n", (void*)t[i]->tid());
   5197     t[i]->Join();
   5198 //    printf("--Joined : %p\n", (void*)t[i]->tid());
   5199     GLOB[i]++;
   5200   }
   5201   for (int i  = 0; i < N; i++) delete t[i];
   5202 
   5203   printf("\tGLOB=%d\n", GLOB[13]);
   5204 }
   5205 REGISTER_TEST(Run, 109)
   5206 }  // namespace test109
   5207 
   5208 
   5209 // test110: TP. Simple races with stack, global and heap objects. {{{1
   5210 namespace test110 {
   5211 int        GLOB = 0;
   5212 static int STATIC;
   5213 
   5214 int       *STACK = 0;
   5215 
   5216 int       *MALLOC;
   5217 int       *CALLOC;
   5218 int       *REALLOC;
   5219 int       *VALLOC;
   5220 int       *PVALLOC;
   5221 int       *MEMALIGN;
   5222 union pi_pv_union { int* pi; void* pv; } POSIX_MEMALIGN;
   5223 int       *MMAP;
   5224 
   5225 int       *NEW;
   5226 int       *NEW_ARR;
   5227 
   5228 void Worker() {
   5229   GLOB++;
   5230   STATIC++;
   5231 
   5232   (*STACK)++;
   5233 
   5234   (*MALLOC)++;
   5235   (*CALLOC)++;
   5236   (*REALLOC)++;
   5237   (*VALLOC)++;
   5238   (*PVALLOC)++;
   5239   (*MEMALIGN)++;
   5240   (*(POSIX_MEMALIGN.pi))++;
   5241   (*MMAP)++;
   5242 
   5243   (*NEW)++;
   5244   (*NEW_ARR)++;
   5245 }
   5246 void Run() {
   5247   int x = 0;
   5248   STACK = &x;
   5249 
   5250   MALLOC = (int*)malloc(sizeof(int));
   5251   CALLOC = (int*)calloc(1, sizeof(int));
   5252   REALLOC = (int*)realloc(NULL, sizeof(int));
   5253   VALLOC = (int*)valloc(sizeof(int));
   5254   PVALLOC = (int*)valloc(sizeof(int));  // TODO: pvalloc breaks helgrind.
   5255   MEMALIGN = (int*)memalign(64, sizeof(int));
   5256   CHECK(0 == posix_memalign(&POSIX_MEMALIGN.pv, 64, sizeof(int)));
   5257   MMAP = (int*)mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE,
   5258                     MAP_PRIVATE | MAP_ANON, -1, 0);
   5259 
   5260   NEW     = new int;
   5261   NEW_ARR = new int[10];
   5262 
   5263 
   5264   FAST_MODE_INIT(STACK);
   5265   ANNOTATE_EXPECT_RACE(STACK, "real race on stack object");
   5266   FAST_MODE_INIT(&GLOB);
   5267   ANNOTATE_EXPECT_RACE(&GLOB, "real race on global object");
   5268   FAST_MODE_INIT(&STATIC);
   5269   ANNOTATE_EXPECT_RACE(&STATIC, "real race on a static global object");
   5270   FAST_MODE_INIT(MALLOC);
   5271   ANNOTATE_EXPECT_RACE(MALLOC, "real race on a malloc-ed object");
   5272   FAST_MODE_INIT(CALLOC);
   5273   ANNOTATE_EXPECT_RACE(CALLOC, "real race on a calloc-ed object");
   5274   FAST_MODE_INIT(REALLOC);
   5275   ANNOTATE_EXPECT_RACE(REALLOC, "real race on a realloc-ed object");
   5276   FAST_MODE_INIT(VALLOC);
   5277   ANNOTATE_EXPECT_RACE(VALLOC, "real race on a valloc-ed object");
   5278   FAST_MODE_INIT(PVALLOC);
   5279   ANNOTATE_EXPECT_RACE(PVALLOC, "real race on a pvalloc-ed object");
   5280   FAST_MODE_INIT(MEMALIGN);
   5281   ANNOTATE_EXPECT_RACE(MEMALIGN, "real race on a memalign-ed object");
   5282   FAST_MODE_INIT(POSIX_MEMALIGN.pi);
   5283   ANNOTATE_EXPECT_RACE(POSIX_MEMALIGN.pi, "real race on a posix_memalign-ed object");
   5284   FAST_MODE_INIT(MMAP);
   5285   ANNOTATE_EXPECT_RACE(MMAP, "real race on a mmap-ed object");
   5286 
   5287   FAST_MODE_INIT(NEW);
   5288   ANNOTATE_EXPECT_RACE(NEW, "real race on a new-ed object");
   5289   FAST_MODE_INIT(NEW_ARR);
   5290   ANNOTATE_EXPECT_RACE(NEW_ARR, "real race on a new[]-ed object");
   5291 
   5292   MyThreadArray t(Worker, Worker, Worker);
   5293   t.Start();
   5294   t.Join();
   5295   printf("test110: positive (race on a stack object)\n");
   5296   printf("\tSTACK=%d\n", *STACK);
   5297   CHECK(GLOB <= 3);
   5298   CHECK(STATIC <= 3);
   5299 
   5300   free(MALLOC);
   5301   free(CALLOC);
   5302   free(REALLOC);
   5303   free(VALLOC);
   5304   free(PVALLOC);
   5305   free(MEMALIGN);
   5306   free(POSIX_MEMALIGN.pv);
   5307   munmap(MMAP, sizeof(int));
   5308   delete NEW;
   5309   delete [] NEW_ARR;
   5310 }
   5311 REGISTER_TEST(Run, 110)
   5312 }  // namespace test110
   5313 
   5314 
   5315 // test111: TN. Unit test for a bug related to stack handling. {{{1
   5316 namespace test111 {
   5317 char     *GLOB = 0;
   5318 bool COND = false;
   5319 Mutex mu;
   5320 const int N = 3000;
   5321 
   5322 void write_to_p(char *p, int val) {
   5323   for (int i = 0; i < N; i++)
   5324     p[i] = val;
   5325 }
   5326 
   5327 static bool ArgIsTrue(bool *arg) {
   5328 //  printf("ArgIsTrue: %d tid=%d\n", *arg, (int)pthread_self());
   5329   return *arg == true;
   5330 }
   5331 
   5332 void f1() {
   5333   char some_stack[N];
   5334   write_to_p(some_stack, 1);
   5335   mu.LockWhen(Condition(&ArgIsTrue, &COND));
   5336   mu.Unlock();
   5337 }
   5338 
   5339 void f2() {
   5340   char some_stack[N];
   5341   char some_more_stack[N];
   5342   write_to_p(some_stack, 2);
   5343   write_to_p(some_more_stack, 2);
   5344 }
   5345 
   5346 void f0() { f2(); }
   5347 
   5348 void Worker1() {
   5349   f0();
   5350   f1();
   5351   f2();
   5352 }
   5353 
   5354 void Worker2() {
   5355   usleep(100000);
   5356   mu.Lock();
   5357   COND = true;
   5358   mu.Unlock();
   5359 }
   5360 
   5361 void Run() {
   5362   printf("test111: regression test\n");
   5363   MyThreadArray t(Worker1, Worker1, Worker2);
   5364 //  AnnotateSetVerbosity(__FILE__, __LINE__, 3);
   5365   t.Start();
   5366   t.Join();
   5367 //  AnnotateSetVerbosity(__FILE__, __LINE__, 1);
   5368 }
   5369 REGISTER_TEST2(Run, 111, FEATURE)
   5370 }  // namespace test111
   5371 
   5372 // test112: STAB. Test for ANNOTATE_PUBLISH_MEMORY_RANGE{{{1
   5373 namespace test112 {
   5374 char     *GLOB = 0;
   5375 const int N = 64 * 5;
   5376 Mutex mu;
   5377 bool ready = false; // under mu
   5378 int beg, end; // under mu
   5379 
   5380 Mutex mu1;
   5381 
   5382 void Worker() {
   5383 
   5384   bool is_ready = false;
   5385   int b, e;
   5386   while (!is_ready) {
   5387     mu.Lock();
   5388     is_ready = ready;
   5389     b = beg;
   5390     e = end;
   5391     mu.Unlock();
   5392     usleep(1000);
   5393   }
   5394 
   5395   mu1.Lock();
   5396   for (int i = b; i < e; i++) {
   5397     GLOB[i]++;
   5398   }
   5399   mu1.Unlock();
   5400 }
   5401 
   5402 void PublishRange(int b, int e) {
   5403   MyThreadArray t(Worker, Worker);
   5404   ready = false; // runs before other threads
   5405   t.Start();
   5406 
   5407   ANNOTATE_NEW_MEMORY(GLOB + b, e - b);
   5408   ANNOTATE_TRACE_MEMORY(GLOB + b);
   5409   for (int j = b; j < e; j++) {
   5410     GLOB[j] = 0;
   5411   }
   5412   ANNOTATE_PUBLISH_MEMORY_RANGE(GLOB + b, e - b);
   5413 
   5414   // hand off
   5415   mu.Lock();
   5416   ready = true;
   5417   beg = b;
   5418   end = e;
   5419   mu.Unlock();
   5420 
   5421   t.Join();
   5422 }
   5423 
   5424 void Run() {
   5425   printf("test112: stability (ANNOTATE_PUBLISH_MEMORY_RANGE)\n");
   5426   GLOB = new char [N];
   5427 
   5428   PublishRange(0, 10);
   5429   PublishRange(3, 5);
   5430 
   5431   PublishRange(12, 13);
   5432   PublishRange(10, 14);
   5433 
   5434   PublishRange(15, 17);
   5435   PublishRange(16, 18);
   5436 
   5437   // do few more random publishes.
   5438   for (int i = 0; i < 20; i++) {
   5439     const int begin = rand() % N;
   5440     const int size = (rand() % (N - begin)) + 1;
   5441     CHECK(size > 0);
   5442     CHECK(begin + size <= N);
   5443     PublishRange(begin, begin + size);
   5444   }
   5445 
   5446   printf("GLOB = %d\n", (int)GLOB[0]);
   5447 }
   5448 REGISTER_TEST2(Run, 112, STABILITY)
   5449 }  // namespace test112
   5450 
   5451 
   5452 // test113: PERF. A lot of lock/unlock calls. Many locks {{{1
   5453 namespace    test113 {
   5454 const int kNumIter = 100000;
   5455 const int kNumLocks = 7;
   5456 Mutex   MU[kNumLocks];
   5457 void Run() {
   5458   printf("test113: perf\n");
   5459   for (int i = 0; i < kNumIter; i++ ) {
   5460     for (int j = 0; j < kNumLocks; j++) {
   5461       if (i & (1 << j)) MU[j].Lock();
   5462     }
   5463     for (int j = kNumLocks - 1; j >= 0; j--) {
   5464       if (i & (1 << j)) MU[j].Unlock();
   5465     }
   5466   }
   5467 }
   5468 REGISTER_TEST(Run, 113)
   5469 }  // namespace test113
   5470 
   5471 
   5472 // test114: STAB. Recursive lock. {{{1
   5473 namespace    test114 {
   5474 int Bar() {
   5475   static int bar = 1;
   5476   return bar;
   5477 }
   5478 int Foo() {
   5479   static int foo = Bar();
   5480   return foo;
   5481 }
   5482 void Worker() {
   5483   static int x = Foo();
   5484   CHECK(x == 1);
   5485 }
   5486 void Run() {
   5487   printf("test114: stab\n");
   5488   MyThreadArray t(Worker, Worker);
   5489   t.Start();
   5490   t.Join();
   5491 }
   5492 REGISTER_TEST(Run, 114)
   5493 }  // namespace test114
   5494 
   5495 
   5496 // test115: TN. sem_open. {{{1
   5497 namespace    test115 {
   5498 int tid = 0;
   5499 Mutex mu;
   5500 const char *kSemName = "drt-test-sem";
   5501 
   5502 int GLOB = 0;
   5503 
   5504 sem_t *DoSemOpen() {
   5505   // TODO: there is some race report inside sem_open
   5506   // for which suppressions do not work... (???)
   5507   ANNOTATE_IGNORE_WRITES_BEGIN();
   5508   sem_t *sem = sem_open(kSemName, O_CREAT, 0600, 3);
   5509   ANNOTATE_IGNORE_WRITES_END();
   5510   return sem;
   5511 }
   5512 
   5513 void Worker() {
   5514   mu.Lock();
   5515   int my_tid = tid++;
   5516   mu.Unlock();
   5517 
   5518   if (my_tid == 0) {
   5519     GLOB = 1;
   5520   }
   5521 
   5522   // if the detector observes a happens-before arc between
   5523   // sem_open and sem_wait, it will be silent.
   5524   sem_t *sem = DoSemOpen();
   5525   usleep(100000);
   5526   CHECK(sem != SEM_FAILED);
   5527   CHECK(sem_wait(sem) == 0);
   5528 
   5529   if (my_tid > 0) {
   5530     CHECK(GLOB == 1);
   5531   }
   5532 }
   5533 
   5534 void Run() {
   5535   printf("test115: stab (sem_open())\n");
   5536 
   5537   // just check that sem_open is not completely broken
   5538   sem_unlink(kSemName);
   5539   sem_t* sem = DoSemOpen();
   5540   CHECK(sem != SEM_FAILED);
   5541   CHECK(sem_wait(sem) == 0);
   5542   sem_unlink(kSemName);
   5543 
   5544   // check that sem_open and sem_wait create a happens-before arc.
   5545   MyThreadArray t(Worker, Worker, Worker);
   5546   t.Start();
   5547   t.Join();
   5548   // clean up
   5549   sem_unlink(kSemName);
   5550 }
   5551 REGISTER_TEST(Run, 115)
   5552 }  // namespace test115
   5553 
   5554 
   5555 // test116: TN. some operations with string<> objects. {{{1
   5556 namespace test116 {
   5557 
   5558 void Worker() {
   5559   string A[10], B[10], C[10];
   5560   for (int i = 0; i < 1000; i++) {
   5561     for (int j = 0; j < 10; j++) {
   5562       string &a = A[j];
   5563       string &b = B[j];
   5564       string &c = C[j];
   5565       a = "sdl;fkjhasdflksj df";
   5566       b = "sdf sdf;ljsd ";
   5567       c = "'sfdf df";
   5568       c = b;
   5569       a = c;
   5570       b = a;
   5571       swap(a,b);
   5572       swap(b,c);
   5573     }
   5574     for (int j = 0; j < 10; j++) {
   5575       string &a = A[j];
   5576       string &b = B[j];
   5577       string &c = C[j];
   5578       a.clear();
   5579       b.clear();
   5580       c.clear();
   5581     }
   5582   }
   5583 }
   5584 
   5585 void Run() {
   5586   printf("test116: negative (strings)\n");
   5587   MyThreadArray t(Worker, Worker, Worker);
   5588   t.Start();
   5589   t.Join();
   5590 }
   5591 REGISTER_TEST2(Run, 116, FEATURE|EXCLUDE_FROM_ALL)
   5592 }  // namespace test116
   5593 
   5594 // test117: TN. Many calls to function-scope static init. {{{1
   5595 namespace test117 {
   5596 const int N = 50;
   5597 
   5598 int Foo() {
   5599   usleep(20000);
   5600   return 1;
   5601 }
   5602 
   5603 void Worker(void *a) {
   5604   static int foo = Foo();
   5605   CHECK(foo == 1);
   5606 }
   5607 
   5608 void Run() {
   5609   printf("test117: negative\n");
   5610   MyThread *t[N];
   5611   for (int i  = 0; i < N; i++) {
   5612     t[i] = new MyThread(Worker);
   5613   }
   5614   for (int i  = 0; i < N; i++) {
   5615     t[i]->Start();
   5616   }
   5617   for (int i  = 0; i < N; i++) {
   5618     t[i]->Join();
   5619   }
   5620   for (int i  = 0; i < N; i++) delete t[i];
   5621 }
   5622 REGISTER_TEST(Run, 117)
   5623 }  // namespace test117
   5624 
   5625 
   5626 
   5627 // test118 PERF: One signal, multiple waits. {{{1
   5628 namespace   test118 {
   5629 int     GLOB = 0;
   5630 const int kNumIter = 2000000;
   5631 void Signaller() {
   5632   usleep(50000);
   5633   ANNOTATE_CONDVAR_SIGNAL(&GLOB);
   5634 }
   5635 void Waiter() {
   5636   for (int i = 0; i < kNumIter; i++) {
   5637     ANNOTATE_CONDVAR_WAIT(&GLOB);
   5638     if (i == kNumIter / 2)
   5639       usleep(100000);
   5640   }
   5641 }
   5642 void Run() {
   5643   printf("test118: perf\n");
   5644   MyThreadArray t(Signaller, Waiter, Signaller, Waiter);
   5645   t.Start();
   5646   t.Join();
   5647   printf("\tGLOB=%d\n", GLOB);
   5648 }
   5649 REGISTER_TEST(Run, 118)
   5650 }  // namespace test118
   5651 
   5652 
   5653 // test119: TP. Testing that malloc does not introduce any HB arc. {{{1
   5654 namespace test119 {
   5655 int     GLOB = 0;
   5656 void Worker1() {
   5657   GLOB = 1;
   5658   free(malloc(123));
   5659 }
   5660 void Worker2() {
   5661   usleep(100000);
   5662   free(malloc(345));
   5663   GLOB = 2;
   5664 }
   5665 void Run() {
   5666   printf("test119: positive (checking if malloc creates HB arcs)\n");
   5667   FAST_MODE_INIT(&GLOB);
   5668   if (!(Tsan_PureHappensBefore() && kMallocUsesMutex))
   5669     ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "true race");
   5670   MyThreadArray t(Worker1, Worker2);
   5671   t.Start();
   5672   t.Join();
   5673   printf("\tGLOB=%d\n", GLOB);
   5674 }
   5675 REGISTER_TEST(Run, 119)
   5676 }  // namespace test119
   5677 
   5678 
   5679 // test120: TP. Thread1: write then read. Thread2: read. {{{1
   5680 namespace test120 {
   5681 int     GLOB = 0;
   5682 
   5683 void Thread1() {
   5684   GLOB = 1;           // write
   5685   CHECK(GLOB);        // read
   5686 }
   5687 
   5688 void Thread2() {
   5689   usleep(100000);
   5690   CHECK(GLOB >= 0);   // read
   5691 }
   5692 
   5693 void Run() {
   5694   FAST_MODE_INIT(&GLOB);
   5695   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "TP (T1: write then read, T2: read)");
   5696   printf("test120: positive\n");
   5697   MyThreadArray t(Thread1, Thread2);
   5698   GLOB = 1;
   5699   t.Start();
   5700   t.Join();
   5701   printf("\tGLOB=%d\n", GLOB);
   5702 }
   5703 REGISTER_TEST(Run, 120)
   5704 }  // namespace test120
   5705 
   5706 
   5707 // test121: TP. Example of double-checked-locking  {{{1
   5708 namespace test121 {
   5709 struct Foo {
   5710   uintptr_t a, b[15];
   5711 } __attribute__ ((aligned (64)));
   5712 
   5713 static Mutex mu;
   5714 static Foo  *foo;
   5715 
   5716 void InitMe() {
   5717   if (!foo) {
   5718     MutexLock lock(&mu);
   5719     if (!foo) {
   5720       ANNOTATE_EXPECT_RACE_FOR_TSAN(&foo, "test121. Double-checked locking (ptr)");
   5721       foo = new Foo;
   5722       if (!Tsan_FastMode())
   5723         ANNOTATE_EXPECT_RACE_FOR_TSAN(&foo->a, "test121. Double-checked locking (obj)");
   5724       foo->a = 42;
   5725     }
   5726   }
   5727 }
   5728 
   5729 void UseMe() {
   5730   InitMe();
   5731   CHECK(foo && foo->a == 42);
   5732 }
   5733 
   5734 void Worker1() { UseMe(); }
   5735 void Worker2() { UseMe(); }
   5736 void Worker3() { UseMe(); }
   5737 
   5738 
   5739 void Run() {
   5740   FAST_MODE_INIT(&foo);
   5741   printf("test121: TP. Example of double-checked-locking\n");
   5742   MyThreadArray t1(Worker1, Worker2, Worker3);
   5743   t1.Start();
   5744   t1.Join();
   5745   delete foo;
   5746 }
   5747 REGISTER_TEST(Run, 121)
   5748 }  // namespace test121
   5749 
   5750 // test122 TP: Simple test with RWLock {{{1
   5751 namespace  test122 {
   5752 int     VAR1 = 0;
   5753 int     VAR2 = 0;
   5754 RWLock mu;
   5755 
   5756 void WriteWhileHoldingReaderLock(int *p) {
   5757   usleep(100000);
   5758   ReaderLockScoped lock(&mu);  // Reader lock for writing. -- bug.
   5759   (*p)++;
   5760 }
   5761 
   5762 void CorrectWrite(int *p) {
   5763   WriterLockScoped lock(&mu);
   5764   (*p)++;
   5765 }
   5766 
   5767 void Thread1() { WriteWhileHoldingReaderLock(&VAR1); }
   5768 void Thread2() { CorrectWrite(&VAR1); }
   5769 void Thread3() { CorrectWrite(&VAR2); }
   5770 void Thread4() { WriteWhileHoldingReaderLock(&VAR2); }
   5771 
   5772 
   5773 void Run() {
   5774   printf("test122: positive (rw-lock)\n");
   5775   VAR1 = 0;
   5776   VAR2 = 0;
   5777   ANNOTATE_TRACE_MEMORY(&VAR1);
   5778   ANNOTATE_TRACE_MEMORY(&VAR2);
   5779   if (!Tsan_PureHappensBefore()) {
   5780     ANNOTATE_EXPECT_RACE_FOR_TSAN(&VAR1, "test122. TP. ReaderLock-ed while writing");
   5781     ANNOTATE_EXPECT_RACE_FOR_TSAN(&VAR2, "test122. TP. ReaderLock-ed while writing");
   5782   }
   5783   MyThreadArray t(Thread1, Thread2, Thread3, Thread4);
   5784   t.Start();
   5785   t.Join();
   5786 }
   5787 REGISTER_TEST(Run, 122)
   5788 }  // namespace test122
   5789 
   5790 
   5791 // test123 TP: accesses of different sizes. {{{1
   5792 namespace test123 {
   5793 
   5794 union uint_union {
   5795   uint64_t u64[1];
   5796   uint32_t u32[2];
   5797   uint16_t u16[4];
   5798   uint8_t  u8[8];
   5799 };
   5800 
   5801 uint_union MEM[8];
   5802 
   5803 // Q. Hey dude, why so many functions?
   5804 // A. I need different stack traces for different accesses.
   5805 
   5806 void Wr64_0() { MEM[0].u64[0] = 1; }
   5807 void Wr64_1() { MEM[1].u64[0] = 1; }
   5808 void Wr64_2() { MEM[2].u64[0] = 1; }
   5809 void Wr64_3() { MEM[3].u64[0] = 1; }
   5810 void Wr64_4() { MEM[4].u64[0] = 1; }
   5811 void Wr64_5() { MEM[5].u64[0] = 1; }
   5812 void Wr64_6() { MEM[6].u64[0] = 1; }
   5813 void Wr64_7() { MEM[7].u64[0] = 1; }
   5814 
   5815 void Wr32_0() { MEM[0].u32[0] = 1; }
   5816 void Wr32_1() { MEM[1].u32[1] = 1; }
   5817 void Wr32_2() { MEM[2].u32[0] = 1; }
   5818 void Wr32_3() { MEM[3].u32[1] = 1; }
   5819 void Wr32_4() { MEM[4].u32[0] = 1; }
   5820 void Wr32_5() { MEM[5].u32[1] = 1; }
   5821 void Wr32_6() { MEM[6].u32[0] = 1; }
   5822 void Wr32_7() { MEM[7].u32[1] = 1; }
   5823 
   5824 void Wr16_0() { MEM[0].u16[0] = 1; }
   5825 void Wr16_1() { MEM[1].u16[1] = 1; }
   5826 void Wr16_2() { MEM[2].u16[2] = 1; }
   5827 void Wr16_3() { MEM[3].u16[3] = 1; }
   5828 void Wr16_4() { MEM[4].u16[0] = 1; }
   5829 void Wr16_5() { MEM[5].u16[1] = 1; }
   5830 void Wr16_6() { MEM[6].u16[2] = 1; }
   5831 void Wr16_7() { MEM[7].u16[3] = 1; }
   5832 
   5833 void Wr8_0() { MEM[0].u8[0] = 1; }
   5834 void Wr8_1() { MEM[1].u8[1] = 1; }
   5835 void Wr8_2() { MEM[2].u8[2] = 1; }
   5836 void Wr8_3() { MEM[3].u8[3] = 1; }
   5837 void Wr8_4() { MEM[4].u8[4] = 1; }
   5838 void Wr8_5() { MEM[5].u8[5] = 1; }
   5839 void Wr8_6() { MEM[6].u8[6] = 1; }
   5840 void Wr8_7() { MEM[7].u8[7] = 1; }
   5841 
   5842 void WriteAll64() {
   5843   Wr64_0();
   5844   Wr64_1();
   5845   Wr64_2();
   5846   Wr64_3();
   5847   Wr64_4();
   5848   Wr64_5();
   5849   Wr64_6();
   5850   Wr64_7();
   5851 }
   5852 
   5853 void WriteAll32() {
   5854   Wr32_0();
   5855   Wr32_1();
   5856   Wr32_2();
   5857   Wr32_3();
   5858   Wr32_4();
   5859   Wr32_5();
   5860   Wr32_6();
   5861   Wr32_7();
   5862 }
   5863 
   5864 void WriteAll16() {
   5865   Wr16_0();
   5866   Wr16_1();
   5867   Wr16_2();
   5868   Wr16_3();
   5869   Wr16_4();
   5870   Wr16_5();
   5871   Wr16_6();
   5872   Wr16_7();
   5873 }
   5874 
   5875 void WriteAll8() {
   5876   Wr8_0();
   5877   Wr8_1();
   5878   Wr8_2();
   5879   Wr8_3();
   5880   Wr8_4();
   5881   Wr8_5();
   5882   Wr8_6();
   5883   Wr8_7();
   5884 }
   5885 
   5886 void W00() { WriteAll64(); }
   5887 void W01() { WriteAll64(); }
   5888 void W02() { WriteAll64(); }
   5889 
   5890 void W10() { WriteAll32(); }
   5891 void W11() { WriteAll32(); }
   5892 void W12() { WriteAll32(); }
   5893 
   5894 void W20() { WriteAll16(); }
   5895 void W21() { WriteAll16(); }
   5896 void W22() { WriteAll16(); }
   5897 
   5898 void W30() { WriteAll8(); }
   5899 void W31() { WriteAll8(); }
   5900 void W32() { WriteAll8(); }
   5901 
   5902 typedef void (*F)(void);
   5903 
   5904 void TestTwoSizes(F f1, F f2) {
   5905   // first f1, then f2
   5906   ANNOTATE_NEW_MEMORY(&MEM, sizeof(MEM));
   5907   memset(&MEM, 0, sizeof(MEM));
   5908   MyThreadArray t1(f1, f2);
   5909   t1.Start();
   5910   t1.Join();
   5911   // reverse order
   5912   ANNOTATE_NEW_MEMORY(&MEM, sizeof(MEM));
   5913   memset(&MEM, 0, sizeof(MEM));
   5914   MyThreadArray t2(f2, f1);
   5915   t2.Start();
   5916   t2.Join();
   5917 }
   5918 
   5919 void Run() {
   5920   printf("test123: positive (different sizes)\n");
   5921   TestTwoSizes(W00, W10);
   5922 //  TestTwoSizes(W01, W20);
   5923 //  TestTwoSizes(W02, W30);
   5924 //  TestTwoSizes(W11, W21);
   5925 //  TestTwoSizes(W12, W31);
   5926 //  TestTwoSizes(W22, W32);
   5927 
   5928 }
   5929 REGISTER_TEST2(Run, 123, FEATURE|EXCLUDE_FROM_ALL)
   5930 }  // namespace test123
   5931 
   5932 
   5933 // test124: What happens if we delete an unlocked lock? {{{1
   5934 namespace test124 {
   5935 // This test does not worg with pthreads (you can't call
   5936 // pthread_mutex_destroy on a locked lock).
   5937 int     GLOB = 0;
   5938 const int N = 1000;
   5939 void Worker() {
   5940   Mutex *a_large_local_array_of_mutexes;
   5941   a_large_local_array_of_mutexes = new Mutex[N];
   5942   for (int i = 0; i < N; i++) {
   5943     a_large_local_array_of_mutexes[i].Lock();
   5944   }
   5945   delete []a_large_local_array_of_mutexes;
   5946   GLOB = 1;
   5947 }
   5948 
   5949 void Run() {
   5950   printf("test124: negative\n");
   5951   MyThreadArray t(Worker, Worker, Worker);
   5952   t.Start();
   5953   t.Join();
   5954   printf("\tGLOB=%d\n", GLOB);
   5955 }
   5956 REGISTER_TEST2(Run, 124, FEATURE|EXCLUDE_FROM_ALL)
   5957 }  // namespace test124
   5958 
   5959 
   5960 // test125 TN: Backwards lock (annotated). {{{1
   5961 namespace test125 {
   5962 // This test uses "Backwards mutex" locking protocol.
   5963 // We take a *reader* lock when writing to a per-thread data
   5964 // (GLOB[thread_num])  and we take a *writer* lock when we
   5965 // are reading from the entire array at once.
   5966 //
   5967 // Such locking protocol is not understood by ThreadSanitizer's
   5968 // hybrid state machine. So, you either have to use a pure-happens-before
   5969 // detector ("tsan --pure-happens-before") or apply pure happens-before mode
   5970 // to this particular lock by using ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(&mu).
   5971 
   5972 const int n_threads = 3;
   5973 RWLock   mu;
   5974 int     GLOB[n_threads];
   5975 
   5976 int adder_num; // updated atomically.
   5977 
   5978 void Adder() {
   5979   int my_num = AtomicIncrement(&adder_num, 1);
   5980 
   5981   ReaderLockScoped lock(&mu);
   5982   GLOB[my_num]++;
   5983 }
   5984 
   5985 void Aggregator() {
   5986   int sum = 0;
   5987   {
   5988     WriterLockScoped lock(&mu);
   5989     for (int i = 0; i < n_threads; i++) {
   5990       sum += GLOB[i];
   5991     }
   5992   }
   5993   printf("sum=%d\n", sum);
   5994 }
   5995 
   5996 void Run() {
   5997   printf("test125: negative\n");
   5998 
   5999   ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(&mu);
   6000 
   6001   // run Adders, then Aggregator
   6002   {
   6003     MyThreadArray t(Adder, Adder, Adder, Aggregator);
   6004     t.Start();
   6005     t.Join();
   6006   }
   6007 
   6008   // Run Aggregator first.
   6009   adder_num = 0;
   6010   {
   6011     MyThreadArray t(Aggregator, Adder, Adder, Adder);
   6012     t.Start();
   6013     t.Join();
   6014   }
   6015 
   6016 }
   6017 REGISTER_TEST(Run, 125)
   6018 }  // namespace test125
   6019 
   6020 // test126 TN: test for BlockingCounter {{{1
   6021 namespace  test126 {
   6022 BlockingCounter *blocking_counter;
   6023 int     GLOB = 0;
   6024 void Worker() {
   6025   CHECK(blocking_counter);
   6026   CHECK(GLOB == 0);
   6027   blocking_counter->DecrementCount();
   6028 }
   6029 void Run() {
   6030   printf("test126: negative\n");
   6031   MyThreadArray t(Worker, Worker, Worker);
   6032   blocking_counter = new BlockingCounter(3);
   6033   t.Start();
   6034   blocking_counter->Wait();
   6035   GLOB = 1;
   6036   t.Join();
   6037   printf("\tGLOB=%d\n", GLOB);
   6038 }
   6039 REGISTER_TEST(Run, 126)
   6040 }  // namespace test126
   6041 
   6042 
   6043 // test127. Bad code: unlocking a mutex locked by another thread. {{{1
   6044 namespace test127 {
   6045 Mutex mu;
   6046 void Thread1() {
   6047   mu.Lock();
   6048 }
   6049 void Thread2() {
   6050   usleep(100000);
   6051   mu.Unlock();
   6052 }
   6053 void Run() {
   6054   printf("test127: unlocking a mutex locked by another thread.\n");
   6055   MyThreadArray t(Thread1, Thread2);
   6056   t.Start();
   6057   t.Join();
   6058 }
   6059 REGISTER_TEST(Run, 127)
   6060 }  // namespace test127
   6061 
   6062 // test128. Suppressed code in concurrent accesses {{{1
   6063 // Please use --suppressions=unittest.supp flag when running this test.
   6064 namespace test128 {
   6065 Mutex mu;
   6066 int GLOB = 0;
   6067 void Worker() {
   6068   usleep(100000);
   6069   mu.Lock();
   6070   GLOB++;
   6071   mu.Unlock();
   6072 }
   6073 void ThisFunctionShouldBeSuppressed() {
   6074   GLOB++;
   6075 }
   6076 void Run() {
   6077   printf("test128: Suppressed code in concurrent accesses.\n");
   6078   MyThreadArray t(Worker, ThisFunctionShouldBeSuppressed);
   6079   t.Start();
   6080   t.Join();
   6081 }
   6082 REGISTER_TEST2(Run, 128, FEATURE | EXCLUDE_FROM_ALL)
   6083 }  // namespace test128
   6084 
   6085 // test129: TN. Synchronization via ReaderLockWhen(). {{{1
   6086 namespace test129 {
   6087 int     GLOB = 0;
   6088 Mutex   MU;
   6089 bool WeirdCondition(int* param) {
   6090   *param = GLOB;  // a write into Waiter's memory
   6091   return GLOB > 0;
   6092 }
   6093 void Waiter() {
   6094   int param = 0;
   6095   MU.ReaderLockWhen(Condition(WeirdCondition, &param));
   6096   MU.ReaderUnlock();
   6097   CHECK(GLOB > 0);
   6098   CHECK(param > 0);
   6099 }
   6100 void Waker() {
   6101   usleep(100000);  // Make sure the waiter blocks.
   6102   MU.Lock();
   6103   GLOB++;
   6104   MU.Unlock();     // calls ANNOTATE_CONDVAR_SIGNAL;
   6105 }
   6106 void Run() {
   6107   printf("test129: Synchronization via ReaderLockWhen()\n");
   6108   MyThread mt(Waiter, NULL, "Waiter Thread");
   6109   mt.Start();
   6110   Waker();
   6111   mt.Join();
   6112   printf("\tGLOB=%d\n", GLOB);
   6113 }
   6114 REGISTER_TEST2(Run, 129, FEATURE);
   6115 }  // namespace test129
   6116 
   6117 // test130: TN. Per-thread. {{{1
   6118 namespace test130 {
   6119 #ifndef NO_TLS
   6120 // This test verifies that the race detector handles
   6121 // thread-local storage (TLS) correctly.
   6122 // As of 09-03-30 ThreadSanitizer has a bug:
   6123 //   - Thread1 starts
   6124 //   - Thread1 touches per_thread_global
   6125 //   - Thread1 ends
   6126 //   - Thread2 starts (and there is no happens-before relation between it and
   6127 //   Thread1)
   6128 //   - Thread2 touches per_thread_global
   6129 // It may happen so that Thread2 will have per_thread_global in the same address
   6130 // as Thread1. Since there is no happens-before relation between threads,
   6131 // ThreadSanitizer reports a race.
   6132 //
   6133 // test131 does the same for stack.
   6134 
   6135 static __thread int per_thread_global[10] = {0};
   6136 
   6137 void RealWorker() {  // Touch per_thread_global.
   6138   per_thread_global[1]++;
   6139   errno++;
   6140 }
   6141 
   6142 void Worker() {  // Spawn few threads that touch per_thread_global.
   6143   MyThreadArray t(RealWorker, RealWorker);
   6144   t.Start();
   6145   t.Join();
   6146 }
   6147 void Worker0() { sleep(0); Worker(); }
   6148 void Worker1() { sleep(1); Worker(); }
   6149 void Worker2() { sleep(2); Worker(); }
   6150 void Worker3() { sleep(3); Worker(); }
   6151 
   6152 void Run() {
   6153   printf("test130: Per-thread\n");
   6154   MyThreadArray t1(Worker0, Worker1, Worker2, Worker3);
   6155   t1.Start();
   6156   t1.Join();
   6157   printf("\tper_thread_global=%d\n", per_thread_global[1]);
   6158 }
   6159 REGISTER_TEST(Run, 130)
   6160 #endif // NO_TLS
   6161 }  // namespace test130
   6162 
   6163 
   6164 // test131: TN. Stack. {{{1
   6165 namespace test131 {
   6166 // Same as test130, but for stack.
   6167 
   6168 void RealWorker() {  // Touch stack.
   6169   int stack_var = 0;
   6170   stack_var++;
   6171 }
   6172 
   6173 void Worker() {  // Spawn few threads that touch stack.
   6174   MyThreadArray t(RealWorker, RealWorker);
   6175   t.Start();
   6176   t.Join();
   6177 }
   6178 void Worker0() { sleep(0); Worker(); }
   6179 void Worker1() { sleep(1); Worker(); }
   6180 void Worker2() { sleep(2); Worker(); }
   6181 void Worker3() { sleep(3); Worker(); }
   6182 
   6183 void Run() {
   6184   printf("test131: stack\n");
   6185   MyThreadArray t(Worker0, Worker1, Worker2, Worker3);
   6186   t.Start();
   6187   t.Join();
   6188 }
   6189 REGISTER_TEST(Run, 131)
   6190 }  // namespace test131
   6191 
   6192 
   6193 // test132: TP. Simple race (write vs write). Works in fast-mode. {{{1
   6194 namespace test132 {
   6195 int     GLOB = 0;
   6196 void Worker() { GLOB = 1; }
   6197 
   6198 void Run1() {
   6199   FAST_MODE_INIT(&GLOB);
   6200   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test132");
   6201   printf("test132: positive; &GLOB=%p\n", &GLOB);
   6202   ANNOTATE_TRACE_MEMORY(&GLOB);
   6203   GLOB = 7;
   6204   MyThreadArray t(Worker, Worker);
   6205   t.Start();
   6206   t.Join();
   6207 }
   6208 
   6209 void Run() {
   6210   Run1();
   6211 }
   6212 REGISTER_TEST(Run, 132);
   6213 }  // namespace test132
   6214 
   6215 
   6216 // test133: TP. Simple race (write vs write). Works in fast mode. {{{1
   6217 namespace test133 {
   6218 // Same as test132, but everything is run from a separate thread spawned from
   6219 // the main thread.
   6220 int     GLOB = 0;
   6221 void Worker() { GLOB = 1; }
   6222 
   6223 void Run1() {
   6224   FAST_MODE_INIT(&GLOB);
   6225   ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "test133");
   6226   printf("test133: positive; &GLOB=%p\n", &GLOB);
   6227   ANNOTATE_TRACE_MEMORY(&GLOB);
   6228   GLOB = 7;
   6229   MyThreadArray t(Worker, Worker);
   6230   t.Start();
   6231   t.Join();
   6232 }
   6233 void Run() {
   6234   MyThread t(Run1);
   6235   t.Start();
   6236   t.Join();
   6237 }
   6238 REGISTER_TEST(Run, 133);
   6239 }  // namespace test133
   6240 
   6241 
   6242 // test134 TN. Swap. Variant of test79. {{{1
   6243 namespace test134 {
   6244 #if 0
   6245 typedef __gnu_cxx::hash_map<int, int> map_t;
   6246 #else
   6247 typedef std::map<int, int> map_t;
   6248 #endif
   6249 map_t   map;
   6250 Mutex   mu;
   6251 // Here we use swap to pass map between threads.
   6252 // The synchronization is correct, but w/o the annotation
   6253 // any hybrid detector will complain.
   6254 
   6255 // Swap is very unfriendly to the lock-set (and hybrid) race detectors.
   6256 // Since tmp is destructed outside the mutex, we need to have a happens-before
   6257 // arc between any prior access to map and here.
   6258 // Since the internals of tmp are created ouside the mutex and are passed to
   6259 // other thread, we need to have a h-b arc between here and any future access.
   6260 // These arcs can be created by HAPPENS_{BEFORE,AFTER} annotations, but it is
   6261 // much simpler to apply pure-happens-before mode to the mutex mu.
   6262 void Swapper() {
   6263   map_t tmp;
   6264   MutexLock lock(&mu);
   6265   ANNOTATE_HAPPENS_AFTER(&map);
   6266   // We swap the new empty map 'tmp' with 'map'.
   6267   map.swap(tmp);
   6268   ANNOTATE_HAPPENS_BEFORE(&map);
   6269   // tmp (which is the old version of map) is destroyed here.
   6270 }
   6271 
   6272 void Worker() {
   6273   MutexLock lock(&mu);
   6274   ANNOTATE_HAPPENS_AFTER(&map);
   6275   map[1]++;
   6276   ANNOTATE_HAPPENS_BEFORE(&map);
   6277 }
   6278 
   6279 void Run() {
   6280   printf("test134: negative (swap)\n");
   6281   // ********************** Shorter way: ***********************
   6282   // ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(&mu);
   6283   MyThreadArray t(Worker, Worker, Swapper, Worker, Worker);
   6284   t.Start();
   6285   t.Join();
   6286 }
   6287 REGISTER_TEST(Run, 134)
   6288 }  // namespace test134
   6289 
   6290 // test135 TN. Swap. Variant of test79. {{{1
   6291 namespace test135 {
   6292 
   6293 void SubWorker() {
   6294   const long SIZE = 65536;
   6295   for (int i = 0; i < 32; i++) {
   6296     int *ptr = (int*)mmap(NULL, SIZE, PROT_READ | PROT_WRITE,
   6297                           MAP_PRIVATE | MAP_ANON, -1, 0);
   6298     *ptr = 42;
   6299     munmap(ptr, SIZE);
   6300   }
   6301 }
   6302 
   6303 void Worker() {
   6304   MyThreadArray t(SubWorker, SubWorker, SubWorker, SubWorker);
   6305   t.Start();
   6306   t.Join();
   6307 }
   6308 
   6309 void Run() {
   6310   printf("test135: negative (mmap)\n");
   6311   MyThreadArray t(Worker, Worker, Worker, Worker);
   6312   t.Start();
   6313   t.Join();
   6314 }
   6315 REGISTER_TEST(Run, 135)
   6316 }  // namespace test135
   6317 
   6318 // test136. Unlock twice. {{{1
   6319 namespace test136 {
   6320 void Run() {
   6321   printf("test136: unlock twice\n");
   6322   pthread_mutexattr_t attr;
   6323   CHECK(0 == pthread_mutexattr_init(&attr));
   6324   CHECK(0 == pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK));
   6325 
   6326   pthread_mutex_t mu;
   6327   CHECK(0 == pthread_mutex_init(&mu, &attr));
   6328   CHECK(0 == pthread_mutex_lock(&mu));
   6329   CHECK(0 == pthread_mutex_unlock(&mu));
   6330   int ret_unlock = pthread_mutex_unlock(&mu);  // unlocking twice.
   6331   int ret_destroy = pthread_mutex_destroy(&mu);
   6332   printf("  pthread_mutex_unlock returned %d\n", ret_unlock);
   6333   printf("  pthread_mutex_destroy returned %d\n", ret_destroy);
   6334 
   6335 }
   6336 
   6337 REGISTER_TEST(Run, 136)
   6338 }  // namespace test136
   6339 
   6340 // test137 TP. Races on stack variables. {{{1
   6341 namespace test137 {
   6342 int GLOB = 0;
   6343 ProducerConsumerQueue q(10);
   6344 
   6345 void Worker() {
   6346   int stack;
   6347   int *tmp = (int*)q.Get();
   6348   (*tmp)++;
   6349   int *racey = &stack;
   6350   q.Put(racey);
   6351   (*racey)++;
   6352   usleep(150000);
   6353   // We may miss the races if we sleep less due to die_memory events...
   6354 }
   6355 
   6356 void Run() {
   6357   int tmp = 0;
   6358   printf("test137: TP. Races on stack variables.\n");
   6359   q.Put(&tmp);
   6360   MyThreadArray t(Worker, Worker, Worker, Worker);
   6361   t.Start();
   6362   t.Join();
   6363   q.Get();
   6364 }
   6365 
   6366 REGISTER_TEST2(Run, 137, FEATURE | EXCLUDE_FROM_ALL)
   6367 }  // namespace test137
   6368 
   6369 // test138 FN. Two closures hit the same thread in ThreadPool. {{{1
   6370 namespace test138 {
   6371 int GLOB = 0;
   6372 
   6373 void Worker() {
   6374   usleep(100000);
   6375   GLOB++;
   6376 }
   6377 
   6378 void Run() {
   6379   FAST_MODE_INIT(&GLOB);
   6380   printf("test138: FN. Two closures hit the same thread in ThreadPool.\n");
   6381 
   6382   // When using thread pools, two concurrent callbacks might be scheduled
   6383   // onto the same executor thread. As a result, unnecessary happens-before
   6384   // relation may be introduced between callbacks.
   6385   // If we set the number of executor threads to 1, any known data
   6386   // race detector will be silent. However, the same situation may happen
   6387   // with any number of executor threads (with some probability).
   6388   ThreadPool tp(1);
   6389   tp.StartWorkers();
   6390   tp.Add(NewCallback(Worker));
   6391   tp.Add(NewCallback(Worker));
   6392 }
   6393 
   6394 REGISTER_TEST2(Run, 138, FEATURE)
   6395 }  // namespace test138
   6396 
   6397 // test139: FN. A true race hidden by reference counting annotation. {{{1
   6398 namespace test139 {
   6399 int GLOB = 0;
   6400 RefCountedClass *obj;
   6401 
   6402 void Worker1() {
   6403   GLOB++;  // First access.
   6404   obj->Unref();
   6405 }
   6406 
   6407 void Worker2() {
   6408   usleep(100000);
   6409   obj->Unref();
   6410   GLOB++;  // Second access.
   6411 }
   6412 
   6413 void Run() {
   6414   FAST_MODE_INIT(&GLOB);
   6415   printf("test139: FN. A true race hidden by reference counting annotation.\n");
   6416 
   6417   obj = new RefCountedClass;
   6418   obj->AnnotateUnref();
   6419   obj->Ref();
   6420   obj->Ref();
   6421   MyThreadArray mt(Worker1, Worker2);
   6422   mt.Start();
   6423   mt.Join();
   6424 }
   6425 
   6426 REGISTER_TEST2(Run, 139, FEATURE)
   6427 }  // namespace test139
   6428 
   6429 // test140 TN. Swap. Variant of test79 and test134. {{{1
   6430 namespace test140 {
   6431 #if 0
   6432 typedef __gnu_cxx::hash_map<int, int> Container;
   6433 #else
   6434 typedef std::map<int,int>             Container;
   6435 #endif
   6436 Mutex mu;
   6437 static Container container;
   6438 
   6439 // Here we use swap to pass a Container between threads.
   6440 // The synchronization is correct, but w/o the annotation
   6441 // any hybrid detector will complain.
   6442 //
   6443 // Unlike the test134, we try to have a minimal set of annotations
   6444 // so that extra h-b arcs do not hide other races.
   6445 
   6446 // Swap is very unfriendly to the lock-set (and hybrid) race detectors.
   6447 // Since tmp is destructed outside the mutex, we need to have a happens-before
   6448 // arc between any prior access to map and here.
   6449 // Since the internals of tmp are created ouside the mutex and are passed to
   6450 // other thread, we need to have a h-b arc between here and any future access.
   6451 //
   6452 // We want to be able to annotate swapper so that we don't need to annotate
   6453 // anything else.
   6454 void Swapper() {
   6455   Container tmp;
   6456   tmp[1] = tmp[2] = tmp[3] = 0;
   6457   {
   6458     MutexLock lock(&mu);
   6459     container.swap(tmp);
   6460     // we are unpublishing the old container.
   6461     ANNOTATE_UNPUBLISH_MEMORY_RANGE(&container, sizeof(container));
   6462     // we are publishing the new container.
   6463     ANNOTATE_PUBLISH_MEMORY_RANGE(&container, sizeof(container));
   6464   }
   6465   tmp[1]++;
   6466   tmp[2]++;
   6467   // tmp (which is the old version of container) is destroyed here.
   6468 }
   6469 
   6470 void Worker() {
   6471   MutexLock lock(&mu);
   6472   container[1]++;
   6473   int *v = &container[2];
   6474   for (int i = 0; i < 10; i++) {
   6475     // if uncommented, this will break ANNOTATE_UNPUBLISH_MEMORY_RANGE():
   6476     // ANNOTATE_HAPPENS_BEFORE(v);
   6477     if (i % 3) {
   6478       (*v)++;
   6479     }
   6480   }
   6481 }
   6482 
   6483 void Run() {
   6484   printf("test140: negative (swap) %p\n", &container);
   6485   MyThreadArray t(Worker, Worker, Swapper, Worker, Worker);
   6486   t.Start();
   6487   t.Join();
   6488 }
   6489 REGISTER_TEST(Run, 140)
   6490 }  // namespace test140
   6491 
   6492 // test141 FP. unlink/fopen, rmdir/opendir. {{{1
   6493 namespace test141 {
   6494 int GLOB1 = 0,
   6495     GLOB2 = 0;
   6496 char *dir_name = NULL,
   6497      *filename = NULL;
   6498 
   6499 void Waker1() {
   6500   usleep(100000);
   6501   GLOB1 = 1;  // Write
   6502   // unlink deletes a file 'filename'
   6503   // which exits spin-loop in Waiter1().
   6504   printf("  Deleting file...\n");
   6505   CHECK(unlink(filename) == 0);
   6506 }
   6507 
   6508 void Waiter1() {
   6509   FILE *tmp;
   6510   while ((tmp = fopen(filename, "r")) != NULL) {
   6511     fclose(tmp);
   6512     usleep(10000);
   6513   }
   6514   printf("  ...file has been deleted\n");
   6515   GLOB1 = 2;  // Write
   6516 }
   6517 
   6518 void Waker2() {
   6519   usleep(100000);
   6520   GLOB2 = 1;  // Write
   6521   // rmdir deletes a directory 'dir_name'
   6522   // which exit spin-loop in Waker().
   6523   printf("  Deleting directory...\n");
   6524   CHECK(rmdir(dir_name) == 0);
   6525 }
   6526 
   6527 void Waiter2() {
   6528   DIR *tmp;
   6529   while ((tmp = opendir(dir_name)) != NULL) {
   6530     closedir(tmp);
   6531     usleep(10000);
   6532   }
   6533   printf("  ...directory has been deleted\n");
   6534   GLOB2 = 2;
   6535 }
   6536 
   6537 void Run() {
   6538   FAST_MODE_INIT(&GLOB1);
   6539   FAST_MODE_INIT(&GLOB2);
   6540   printf("test141: FP. unlink/fopen, rmdir/opendir.\n");
   6541 
   6542   dir_name = strdup("/tmp/tsan-XXXXXX");
   6543   IGNORE_RETURN_VALUE(mkdtemp(dir_name));
   6544 
   6545   filename = strdup((std::string() + dir_name + "/XXXXXX").c_str());
   6546   const int fd = mkstemp(filename);
   6547   CHECK(fd >= 0);
   6548   close(fd);
   6549 
   6550   MyThreadArray mta1(Waker1, Waiter1);
   6551   mta1.Start();
   6552   mta1.Join();
   6553 
   6554   MyThreadArray mta2(Waker2, Waiter2);
   6555   mta2.Start();
   6556   mta2.Join();
   6557   free(filename);
   6558   filename = 0;
   6559   free(dir_name);
   6560   dir_name = 0;
   6561 }
   6562 REGISTER_TEST(Run, 141)
   6563 }  // namespace test141
   6564 
   6565 
   6566 // Simple FIFO queue annotated with PCQ annotations. {{{1
   6567 class FifoMessageQueue {
   6568  public:
   6569   FifoMessageQueue() { ANNOTATE_PCQ_CREATE(this); }
   6570   ~FifoMessageQueue() { ANNOTATE_PCQ_DESTROY(this); }
   6571   // Send a message. 'message' should be positive.
   6572   void Put(int message) {
   6573     CHECK(message);
   6574     MutexLock lock(&mu_);
   6575     ANNOTATE_PCQ_PUT(this);
   6576     q_.push(message);
   6577   }
   6578   // Return the message from the queue and pop it
   6579   // or return 0 if there are no messages.
   6580   int Get() {
   6581     MutexLock lock(&mu_);
   6582     if (q_.empty()) return 0;
   6583     int res = q_.front();
   6584     q_.pop();
   6585     ANNOTATE_PCQ_GET(this);
   6586     return res;
   6587   }
   6588  private:
   6589   Mutex mu_;
   6590   queue<int> q_;
   6591 };
   6592 
   6593 
   6594 // test142: TN. Check PCQ_* annotations. {{{1
   6595 namespace test142 {
   6596 // Putter writes to array[i] and sends a message 'i'.
   6597 // Getters receive messages and read array[message].
   6598 // PCQ_* annotations calm down the hybrid detectors.
   6599 
   6600 const int N = 1000;
   6601 int array[N+1];
   6602 
   6603 FifoMessageQueue q;
   6604 
   6605 void Putter() {
   6606   for (int i = 1; i <= N; i++) {
   6607     array[i] = i*i;
   6608     q.Put(i);
   6609     usleep(1000);
   6610   }
   6611 }
   6612 
   6613 void Getter() {
   6614   int non_zero_received  = 0;
   6615   for (int i = 1; i <= N; i++) {
   6616     int res = q.Get();
   6617     if (res > 0) {
   6618       CHECK(array[res] = res * res);
   6619       non_zero_received++;
   6620     }
   6621     usleep(1000);
   6622   }
   6623   printf("T=%zd: non_zero_received=%d\n",
   6624          (size_t)pthread_self(), non_zero_received);
   6625 }
   6626 
   6627 void Run() {
   6628   printf("test142: tests PCQ annotations\n");
   6629   MyThreadArray t(Putter, Getter, Getter);
   6630   t.Start();
   6631   t.Join();
   6632 }
   6633 REGISTER_TEST(Run, 142)
   6634 }  // namespace test142
   6635 
   6636 
   6637 // test143: TP. Check PCQ_* annotations. {{{1
   6638 namespace test143 {
   6639 // True positive.
   6640 // We have a race on GLOB between Putter and one of the Getters.
   6641 // Pure h-b will not see it.
   6642 // If FifoMessageQueue was annotated using HAPPENS_BEFORE/AFTER, the race would
   6643 // be missed too.
   6644 // PCQ_* annotations do not hide this race.
   6645 int     GLOB = 0;
   6646 
   6647 FifoMessageQueue q;
   6648 
   6649 void Putter() {
   6650   GLOB = 1;
   6651   q.Put(1);
   6652 }
   6653 
   6654 void Getter() {
   6655   usleep(10000);
   6656   q.Get();
   6657   CHECK(GLOB == 1);  // Race here
   6658 }
   6659 
   6660 void Run() {
   6661   q.Put(1);
   6662   if (!Tsan_PureHappensBefore()) {
   6663     ANNOTATE_EXPECT_RACE_FOR_TSAN(&GLOB, "true races");
   6664   }
   6665   printf("test143: tests PCQ annotations (true positive)\n");
   6666   MyThreadArray t(Putter, Getter, Getter);
   6667   t.Start();
   6668   t.Join();
   6669 }
   6670 REGISTER_TEST(Run, 143);
   6671 }  // namespace test143
   6672 
   6673 
   6674 
   6675 
   6676 // test300: {{{1
   6677 namespace test300 {
   6678 int     GLOB = 0;
   6679 void Run() {
   6680 }
   6681 REGISTER_TEST2(Run, 300, RACE_DEMO)
   6682 }  // namespace test300
   6683 
   6684 // test301: Simple race.  {{{1
   6685 namespace test301 {
   6686 Mutex mu1;  // This Mutex guards var.
   6687 Mutex mu2;  // This Mutex is not related to var.
   6688 int   var;  // GUARDED_BY(mu1)
   6689 
   6690 void Thread1() {  // Runs in thread named 'test-thread-1'.
   6691   MutexLock lock(&mu1);  // Correct Mutex.
   6692   var = 1;
   6693 }
   6694 
   6695 void Thread2() {  // Runs in thread named 'test-thread-2'.
   6696   MutexLock lock(&mu2);  // Wrong Mutex.
   6697   var = 2;
   6698 }
   6699 
   6700 void Run() {
   6701   var = 0;
   6702   printf("test301: simple race.\n");
   6703   MyThread t1(Thread1, NULL, "test-thread-1");
   6704   MyThread t2(Thread2, NULL, "test-thread-2");
   6705   t1.Start();
   6706   t2.Start();
   6707   t1.Join();
   6708   t2.Join();
   6709 }
   6710 REGISTER_TEST2(Run, 301, RACE_DEMO)
   6711 }  // namespace test301
   6712 
   6713 // test302: Complex race which happens at least twice.  {{{1
   6714 namespace test302 {
   6715 // In this test we have many different accesses to GLOB and only one access
   6716 // is not synchronized properly.
   6717 int     GLOB = 0;
   6718 
   6719 Mutex MU1;
   6720 Mutex MU2;
   6721 void Worker() {
   6722   for(int i = 0; i < 100; i++) {
   6723     switch(i % 4) {
   6724       case 0:
   6725         // This read is protected correctly.
   6726         MU1.Lock(); CHECK(GLOB >= 0); MU1.Unlock();
   6727         break;
   6728       case 1:
   6729         // Here we used the wrong lock! The reason of the race is here.
   6730         MU2.Lock(); CHECK(GLOB >= 0); MU2.Unlock();
   6731         break;
   6732       case 2:
   6733         // This read is protected correctly.
   6734         MU1.Lock(); CHECK(GLOB >= 0); MU1.Unlock();
   6735         break;
   6736       case 3:
   6737         // This write is protected correctly.
   6738         MU1.Lock(); GLOB++; MU1.Unlock();
   6739         break;
   6740     }
   6741     // sleep a bit so that the threads interleave
   6742     // and the race happens at least twice.
   6743     usleep(100);
   6744   }
   6745 }
   6746 
   6747 void Run() {
   6748   printf("test302: Complex race that happens twice.\n");
   6749   MyThread t1(Worker), t2(Worker);
   6750   t1.Start();
   6751   t2.Start();
   6752   t1.Join();   t2.Join();
   6753 }
   6754 REGISTER_TEST2(Run, 302, RACE_DEMO)
   6755 }  // namespace test302
   6756 
   6757 
   6758 // test303: Need to trace the memory to understand the report. {{{1
   6759 namespace test303 {
   6760 int     GLOB = 0;
   6761 
   6762 Mutex MU;
   6763 void Worker1() { CHECK(GLOB >= 0); }
   6764 void Worker2() { MU.Lock(); GLOB=1;  MU.Unlock();}
   6765 
   6766 void Run() {
   6767   printf("test303: a race that needs annotations.\n");
   6768   ANNOTATE_TRACE_MEMORY(&GLOB);
   6769   MyThreadArray t(Worker1, Worker2);
   6770   t.Start();
   6771   t.Join();
   6772 }
   6773 REGISTER_TEST2(Run, 303, RACE_DEMO)
   6774 }  // namespace test303
   6775 
   6776 
   6777 
   6778 // test304: Can not trace the memory, since it is a library object. {{{1
   6779 namespace test304 {
   6780 string *STR;
   6781 Mutex   MU;
   6782 
   6783 void Worker1() {
   6784   sleep(0);
   6785   ANNOTATE_CONDVAR_SIGNAL((void*)0xDEADBEAF);
   6786   MU.Lock(); CHECK(STR->length() >= 4); MU.Unlock();
   6787 }
   6788 void Worker2() {
   6789   sleep(1);
   6790   ANNOTATE_CONDVAR_SIGNAL((void*)0xDEADBEAF);
   6791   CHECK(STR->length() >= 4); // Unprotected!
   6792 }
   6793 void Worker3() {
   6794   sleep(2);
   6795   ANNOTATE_CONDVAR_SIGNAL((void*)0xDEADBEAF);
   6796   MU.Lock(); CHECK(STR->length() >= 4); MU.Unlock();
   6797 }
   6798 void Worker4() {
   6799   sleep(3);
   6800   ANNOTATE_CONDVAR_SIGNAL((void*)0xDEADBEAF);
   6801   MU.Lock(); *STR += " + a very very long string"; MU.Unlock();
   6802 }
   6803 
   6804 void Run() {
   6805   STR = new string ("The String");
   6806   printf("test304: a race where memory tracing does not work.\n");
   6807   MyThreadArray t(Worker1, Worker2, Worker3, Worker4);
   6808   t.Start();
   6809   t.Join();
   6810 
   6811   printf("%s\n", STR->c_str());
   6812   delete STR;
   6813 }
   6814 REGISTER_TEST2(Run, 304, RACE_DEMO)
   6815 }  // namespace test304
   6816 
   6817 
   6818 
   6819 // test305: A bit more tricky: two locks used inconsistenly. {{{1
   6820 namespace test305 {
   6821 int     GLOB = 0;
   6822 
   6823 // In this test GLOB is protected by MU1 and MU2, but inconsistently.
   6824 // The TRACES observed by helgrind are:
   6825 // TRACE[1]: Access{T2/S2 wr} -> new State{Mod; #LS=2; #SS=1; T2/S2}
   6826 // TRACE[2]: Access{T4/S9 wr} -> new State{Mod; #LS=1; #SS=2; T2/S2, T4/S9}
   6827 // TRACE[3]: Access{T5/S13 wr} -> new State{Mod; #LS=1; #SS=3; T2/S2, T4/S9, T5/S13}
   6828 // TRACE[4]: Access{T6/S19 wr} -> new State{Mod; #LS=0; #SS=4; T2/S2, T4/S9, T5/S13, T6/S19}
   6829 //
   6830 // The guilty access is either Worker2() or Worker4(), depending on
   6831 // which mutex is supposed to protect GLOB.
   6832 Mutex MU1;
   6833 Mutex MU2;
   6834 void Worker1() { MU1.Lock(); MU2.Lock(); GLOB=1; MU2.Unlock(); MU1.Unlock(); }
   6835 void Worker2() { MU1.Lock();             GLOB=2;               MU1.Unlock(); }
   6836 void Worker3() { MU1.Lock(); MU2.Lock(); GLOB=3; MU2.Unlock(); MU1.Unlock(); }
   6837 void Worker4() {             MU2.Lock(); GLOB=4; MU2.Unlock();               }
   6838 
   6839 void Run() {
   6840   ANNOTATE_TRACE_MEMORY(&GLOB);
   6841   printf("test305: simple race.\n");
   6842   MyThread t1(Worker1), t2(Worker2), t3(Worker3), t4(Worker4);
   6843   t1.Start(); usleep(100);
   6844   t2.Start(); usleep(100);
   6845   t3.Start(); usleep(100);
   6846   t4.Start(); usleep(100);
   6847   t1.Join(); t2.Join(); t3.Join(); t4.Join();
   6848 }
   6849 REGISTER_TEST2(Run, 305, RACE_DEMO)
   6850 }  // namespace test305
   6851 
   6852 // test306: Two locks are used to protect a var.  {{{1
   6853 namespace test306 {
   6854 int     GLOB = 0;
   6855 // Thread1 and Thread2 access the var under two locks.
   6856 // Thread3 uses no locks.
   6857 
   6858 Mutex MU1;
   6859 Mutex MU2;
   6860 void Worker1() { MU1.Lock(); MU2.Lock(); GLOB=1; MU2.Unlock(); MU1.Unlock(); }
   6861 void Worker2() { MU1.Lock(); MU2.Lock(); GLOB=3; MU2.Unlock(); MU1.Unlock(); }
   6862 void Worker3() {                         GLOB=4;               }
   6863 
   6864 void Run() {
   6865   ANNOTATE_TRACE_MEMORY(&GLOB);
   6866   printf("test306: simple race.\n");
   6867   MyThread t1(Worker1), t2(Worker2), t3(Worker3);
   6868   t1.Start(); usleep(100);
   6869   t2.Start(); usleep(100);
   6870   t3.Start(); usleep(100);
   6871   t1.Join(); t2.Join(); t3.Join();
   6872 }
   6873 REGISTER_TEST2(Run, 306, RACE_DEMO)
   6874 }  // namespace test306
   6875 
   6876 // test307: Simple race, code with control flow  {{{1
   6877 namespace test307 {
   6878 int     *GLOB = 0;
   6879 volatile /*to fake the compiler*/ bool some_condition = true;
   6880 
   6881 
   6882 void SomeFunc() { }
   6883 
   6884 int FunctionWithControlFlow() {
   6885   int unrelated_stuff = 0;
   6886   unrelated_stuff++;
   6887   SomeFunc();                // "--keep-history=1" will point somewhere here.
   6888   if (some_condition) {      // Or here
   6889     if (some_condition) {
   6890       unrelated_stuff++;     // Or here.
   6891       unrelated_stuff++;
   6892       (*GLOB)++;             // "--keep-history=2" will point here (experimental).
   6893     }
   6894   }
   6895   usleep(100000);
   6896   return unrelated_stuff;
   6897 }
   6898 
   6899 void Worker1() { FunctionWithControlFlow(); }
   6900 void Worker2() { Worker1(); }
   6901 void Worker3() { Worker2(); }
   6902 void Worker4() { Worker3(); }
   6903 
   6904 void Run() {
   6905   GLOB = new int;
   6906   *GLOB = 1;
   6907   printf("test307: simple race, code with control flow\n");
   6908   MyThreadArray t1(Worker1, Worker2, Worker3, Worker4);
   6909   t1.Start();
   6910   t1.Join();
   6911 }
   6912 REGISTER_TEST2(Run, 307, RACE_DEMO)
   6913 }  // namespace test307
   6914 
   6915 // test308: Example of double-checked-locking  {{{1
   6916 namespace test308 {
   6917 struct Foo {
   6918   int a;
   6919 };
   6920 
   6921 static int   is_inited = 0;
   6922 static Mutex lock;
   6923 static Foo  *foo;
   6924 
   6925 void InitMe() {
   6926   if (!is_inited) {
   6927     lock.Lock();
   6928       if (!is_inited) {
   6929         foo = new Foo;
   6930         foo->a = 42;
   6931         is_inited = 1;
   6932       }
   6933     lock.Unlock();
   6934   }
   6935 }
   6936 
   6937 void UseMe() {
   6938   InitMe();
   6939   CHECK(foo && foo->a == 42);
   6940 }
   6941 
   6942 void Worker1() { UseMe(); }
   6943 void Worker2() { UseMe(); }
   6944 void Worker3() { UseMe(); }
   6945 
   6946 
   6947 void Run() {
   6948   ANNOTATE_TRACE_MEMORY(&is_inited);
   6949   printf("test308: Example of double-checked-locking\n");
   6950   MyThreadArray t1(Worker1, Worker2, Worker3);
   6951   t1.Start();
   6952   t1.Join();
   6953 }
   6954 REGISTER_TEST2(Run, 308, RACE_DEMO)
   6955 }  // namespace test308
   6956 
   6957 // test309: Simple race on an STL object.  {{{1
   6958 namespace test309 {
   6959 string  GLOB;
   6960 
   6961 void Worker1() {
   6962   GLOB="Thread1";
   6963 }
   6964 void Worker2() {
   6965   usleep(100000);
   6966   GLOB="Booooooooooo";
   6967 }
   6968 
   6969 void Run() {
   6970   printf("test309: simple race on an STL object.\n");
   6971   MyThread t1(Worker1), t2(Worker2);
   6972   t1.Start();
   6973   t2.Start();
   6974   t1.Join();   t2.Join();
   6975 }
   6976 REGISTER_TEST2(Run, 309, RACE_DEMO)
   6977 }  // namespace test309
   6978 
   6979 // test310: One more simple race.  {{{1
   6980 namespace test310 {
   6981 int     *PTR = NULL;  // GUARDED_BY(mu1)
   6982 
   6983 Mutex mu1;  // Protects PTR.
   6984 Mutex mu2;  // Unrelated to PTR.
   6985 Mutex mu3;  // Unrelated to PTR.
   6986 
   6987 void Writer1() {
   6988   MutexLock lock3(&mu3);  // This lock is unrelated to PTR.
   6989   MutexLock lock1(&mu1);  // Protect PTR.
   6990   *PTR = 1;
   6991 }
   6992 
   6993 void Writer2() {
   6994   MutexLock lock2(&mu2);  // This lock is unrelated to PTR.
   6995   MutexLock lock1(&mu1);  // Protect PTR.
   6996   int some_unrelated_stuff = 0;
   6997   if (some_unrelated_stuff == 0)
   6998     some_unrelated_stuff++;
   6999   *PTR = 2;
   7000 }
   7001 
   7002 
   7003 void Reader() {
   7004   MutexLock lock2(&mu2);  // Oh, gosh, this is a wrong mutex!
   7005   CHECK(*PTR <= 2);
   7006 }
   7007 
   7008 // Some functions to make the stack trace non-trivial.
   7009 void DoWrite1() { Writer1();  }
   7010 void Thread1()  { DoWrite1(); }
   7011 
   7012 void DoWrite2() { Writer2();  }
   7013 void Thread2()  { DoWrite2(); }
   7014 
   7015 void DoRead()  { Reader();  }
   7016 void Thread3() { DoRead();  }
   7017 
   7018 void Run() {
   7019   printf("test310: simple race.\n");
   7020   PTR = new int;
   7021   ANNOTATE_TRACE_MEMORY(PTR);
   7022   *PTR = 0;
   7023   MyThread t1(Thread1, NULL, "writer1"),
   7024            t2(Thread2, NULL, "writer2"),
   7025            t3(Thread3, NULL, "buggy reader");
   7026   t1.Start();
   7027   t2.Start();
   7028   usleep(100000);  // Let the writers go first.
   7029   t3.Start();
   7030 
   7031   t1.Join();
   7032   t2.Join();
   7033   t3.Join();
   7034 }
   7035 REGISTER_TEST2(Run, 310, RACE_DEMO)
   7036 }  // namespace test310
   7037 
   7038 // test311: Yet another simple race.  {{{1
   7039 namespace test311 {
   7040 int     *PTR = NULL;  // GUARDED_BY(mu1)
   7041 
   7042 Mutex mu1;  // Protects PTR.
   7043 Mutex mu2;  // Unrelated to PTR.
   7044 Mutex mu3;  // Unrelated to PTR.
   7045 
   7046 void GoodWriter1() {
   7047   MutexLock lock3(&mu3);  // This lock is unrelated to PTR.
   7048   MutexLock lock1(&mu1);  // Protect PTR.
   7049   *PTR = 1;
   7050 }
   7051 
   7052 void GoodWriter2() {
   7053   MutexLock lock2(&mu2);  // This lock is unrelated to PTR.
   7054   MutexLock lock1(&mu1);  // Protect PTR.
   7055   *PTR = 2;
   7056 }
   7057 
   7058 void GoodReader() {
   7059   MutexLock lock1(&mu1);  // Protect PTR.
   7060   CHECK(*PTR >= 0);
   7061 }
   7062 
   7063 void BuggyWriter() {
   7064   MutexLock lock2(&mu2);  // Wrong mutex!
   7065   *PTR = 3;
   7066 }
   7067 
   7068 // Some functions to make the stack trace non-trivial.
   7069 void DoWrite1() { GoodWriter1();  }
   7070 void Thread1()  { DoWrite1(); }
   7071 
   7072 void DoWrite2() { GoodWriter2();  }
   7073 void Thread2()  { DoWrite2(); }
   7074 
   7075 void DoGoodRead()  { GoodReader();  }
   7076 void Thread3()     { DoGoodRead();  }
   7077 
   7078 void DoBadWrite()  { BuggyWriter(); }
   7079 void Thread4()     { DoBadWrite(); }
   7080 
   7081 void Run() {
   7082   printf("test311: simple race.\n");
   7083   PTR = new int;
   7084   ANNOTATE_TRACE_MEMORY(PTR);
   7085   *PTR = 0;
   7086   MyThread t1(Thread1, NULL, "good writer1"),
   7087            t2(Thread2, NULL, "good writer2"),
   7088            t3(Thread3, NULL, "good reader"),
   7089            t4(Thread4, NULL, "buggy writer");
   7090   t1.Start();
   7091   t3.Start();
   7092   // t2 goes after t3. This way a pure happens-before detector has no chance.
   7093   usleep(10000);
   7094   t2.Start();
   7095   usleep(100000);  // Let the good folks go first.
   7096   t4.Start();
   7097 
   7098   t1.Join();
   7099   t2.Join();
   7100   t3.Join();
   7101   t4.Join();
   7102 }
   7103 REGISTER_TEST2(Run, 311, RACE_DEMO)
   7104 }  // namespace test311
   7105 
   7106 // test312: A test with a very deep stack. {{{1
   7107 namespace test312 {
   7108 int     GLOB = 0;
   7109 void RaceyWrite() { GLOB++; }
   7110 void Func1() { RaceyWrite(); }
   7111 void Func2() { Func1(); }
   7112 void Func3() { Func2(); }
   7113 void Func4() { Func3(); }
   7114 void Func5() { Func4(); }
   7115 void Func6() { Func5(); }
   7116 void Func7() { Func6(); }
   7117 void Func8() { Func7(); }
   7118 void Func9() { Func8(); }
   7119 void Func10() { Func9(); }
   7120 void Func11() { Func10(); }
   7121 void Func12() { Func11(); }
   7122 void Func13() { Func12(); }
   7123 void Func14() { Func13(); }
   7124 void Func15() { Func14(); }
   7125 void Func16() { Func15(); }
   7126 void Func17() { Func16(); }
   7127 void Func18() { Func17(); }
   7128 void Func19() { Func18(); }
   7129 void Worker() { Func19(); }
   7130 void Run() {
   7131   printf("test312: simple race with deep stack.\n");
   7132   MyThreadArray t(Worker, Worker, Worker);
   7133   t.Start();
   7134   t.Join();
   7135 }
   7136 REGISTER_TEST2(Run, 312, RACE_DEMO)
   7137 }  // namespace test312
   7138 
   7139 // test313 TP: test for thread graph output {{{1
   7140 namespace  test313 {
   7141 BlockingCounter *blocking_counter;
   7142 int     GLOB = 0;
   7143 
   7144 // Worker(N) will do 2^N increments of GLOB, each increment in a separate thread
   7145 void Worker(int depth) {
   7146   CHECK(depth >= 0);
   7147   if (depth > 0) {
   7148     ThreadPool pool(2);
   7149     pool.StartWorkers();
   7150     pool.Add(NewCallback(Worker, depth-1));
   7151     pool.Add(NewCallback(Worker, depth-1));
   7152   } else {
   7153     GLOB++; // Race here
   7154   }
   7155 }
   7156 void Run() {
   7157   printf("test313: positive\n");
   7158   Worker(4);
   7159   printf("\tGLOB=%d\n", GLOB);
   7160 }
   7161 REGISTER_TEST2(Run, 313, RACE_DEMO)
   7162 }  // namespace test313
   7163 
   7164 
   7165 
   7166 // test400: Demo of a simple false positive. {{{1
   7167 namespace test400 {
   7168 static Mutex mu;
   7169 static vector<int> *vec; // GUARDED_BY(mu);
   7170 
   7171 void InitAllBeforeStartingThreads() {
   7172   vec = new vector<int>;
   7173   vec->push_back(1);
   7174   vec->push_back(2);
   7175 }
   7176 
   7177 void Thread1() {
   7178   MutexLock lock(&mu);
   7179   vec->pop_back();
   7180 }
   7181 
   7182 void Thread2() {
   7183   MutexLock lock(&mu);
   7184   vec->pop_back();
   7185 }
   7186 
   7187 //---- Sub-optimal code ---------
   7188 size_t NumberOfElementsLeft() {
   7189   MutexLock lock(&mu);
   7190   return vec->size();
   7191 }
   7192 
   7193 void WaitForAllThreadsToFinish_InefficientAndTsanUnfriendly() {
   7194   while(NumberOfElementsLeft()) {
   7195     ; // sleep or print or do nothing.
   7196   }
   7197   // It is now safe to access vec w/o lock.
   7198   // But a hybrid detector (like ThreadSanitizer) can't see it.
   7199   // Solutions:
   7200   //   1. Use pure happens-before detector (e.g. "tsan --pure-happens-before")
   7201   //   2. Call ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(&mu)
   7202   //      in InitAllBeforeStartingThreads()
   7203   //   3. (preferred) Use WaitForAllThreadsToFinish_Good() (see below).
   7204   CHECK(vec->empty());
   7205   delete vec;
   7206 }
   7207 
   7208 //----- Better code -----------
   7209 
   7210 bool NoElementsLeft(vector<int> *v) {
   7211   return v->empty();
   7212 }
   7213 
   7214 void WaitForAllThreadsToFinish_Good() {
   7215   mu.LockWhen(Condition(NoElementsLeft, vec));
   7216   mu.Unlock();
   7217 
   7218   // It is now safe to access vec w/o lock.
   7219   CHECK(vec->empty());
   7220   delete vec;
   7221 }
   7222 
   7223 
   7224 void Run() {
   7225   MyThreadArray t(Thread1, Thread2);
   7226   InitAllBeforeStartingThreads();
   7227   t.Start();
   7228   WaitForAllThreadsToFinish_InefficientAndTsanUnfriendly();
   7229 //  WaitForAllThreadsToFinish_Good();
   7230   t.Join();
   7231 }
   7232 REGISTER_TEST2(Run, 400, RACE_DEMO)
   7233 }  // namespace test400
   7234 
   7235 // test401: Demo of false positive caused by reference counting. {{{1
   7236 namespace test401 {
   7237 // A simplified example of reference counting.
   7238 // DecRef() does ref count increment in a way unfriendly to race detectors.
   7239 // DecRefAnnotated() does the same in a friendly way.
   7240 
   7241 static vector<int> *vec;
   7242 static int ref_count;
   7243 
   7244 void InitAllBeforeStartingThreads(int number_of_threads) {
   7245   vec = new vector<int>;
   7246   vec->push_back(1);
   7247   ref_count = number_of_threads;
   7248 }
   7249 
   7250 // Correct, but unfriendly to race detectors.
   7251 int DecRef() {
   7252   return AtomicIncrement(&ref_count, -1);
   7253 }
   7254 
   7255 // Correct and friendly to race detectors.
   7256 int DecRefAnnotated() {
   7257   ANNOTATE_CONDVAR_SIGNAL(&ref_count);
   7258   int res = AtomicIncrement(&ref_count, -1);
   7259   if (res == 0) {
   7260     ANNOTATE_CONDVAR_WAIT(&ref_count);
   7261   }
   7262   return res;
   7263 }
   7264 
   7265 void ThreadWorker() {
   7266   CHECK(ref_count > 0);
   7267   CHECK(vec->size() == 1);
   7268   if (DecRef() == 0) {  // Use DecRefAnnotated() instead!
   7269     // No one uses vec now ==> delete it.
   7270     delete vec;  // A false race may be reported here.
   7271     vec = NULL;
   7272   }
   7273 }
   7274 
   7275 void Run() {
   7276   MyThreadArray t(ThreadWorker, ThreadWorker, ThreadWorker);
   7277   InitAllBeforeStartingThreads(3 /*number of threads*/);
   7278   t.Start();
   7279   t.Join();
   7280   CHECK(vec == 0);
   7281 }
   7282 REGISTER_TEST2(Run, 401, RACE_DEMO)
   7283 }  // namespace test401
   7284 
   7285 // test501: Manually call PRINT_* annotations {{{1
   7286 namespace test501 {
   7287 int  COUNTER = 0;
   7288 int     GLOB = 0;
   7289 Mutex muCounter, muGlob[65];
   7290 
   7291 void Worker() {
   7292    muCounter.Lock();
   7293    int myId = ++COUNTER;
   7294    muCounter.Unlock();
   7295 
   7296    usleep(100);
   7297 
   7298    muGlob[myId].Lock();
   7299    muGlob[0].Lock();
   7300    GLOB++;
   7301    muGlob[0].Unlock();
   7302    muGlob[myId].Unlock();
   7303 }
   7304 
   7305 void Worker_1() {
   7306    MyThreadArray ta (Worker, Worker, Worker, Worker);
   7307    ta.Start();
   7308    usleep(500000);
   7309    ta.Join ();
   7310 }
   7311 
   7312 void Worker_2() {
   7313    MyThreadArray ta (Worker_1, Worker_1, Worker_1, Worker_1);
   7314    ta.Start();
   7315    usleep(300000);
   7316    ta.Join ();
   7317 }
   7318 
   7319 void Run() {
   7320    ANNOTATE_RESET_STATS();
   7321    printf("test501: Manually call PRINT_* annotations.\n");
   7322    MyThreadArray ta (Worker_2, Worker_2, Worker_2, Worker_2);
   7323    ta.Start();
   7324    usleep(100000);
   7325    ta.Join ();
   7326    ANNOTATE_PRINT_MEMORY_USAGE(0);
   7327    ANNOTATE_PRINT_STATS();
   7328 }
   7329 
   7330 REGISTER_TEST2(Run, 501, FEATURE | EXCLUDE_FROM_ALL)
   7331 }  // namespace test501
   7332 
   7333 // test502: produce lots of segments without cross-thread relations {{{1
   7334 namespace test502 {
   7335 
   7336 /*
   7337  * This test produces ~1Gb of memory usage when run with the following options:
   7338  *
   7339  * --tool=helgrind
   7340  * --trace-after-race=0
   7341  * --num-callers=2
   7342  * --more-context=no
   7343  */
   7344 
   7345 Mutex MU;
   7346 int     GLOB = 0;
   7347 
   7348 void TP() {
   7349    for (int i = 0; i < 750000; i++) {
   7350       MU.Lock();
   7351       GLOB++;
   7352       MU.Unlock();
   7353    }
   7354 }
   7355 
   7356 void Run() {
   7357    MyThreadArray t(TP, TP);
   7358    printf("test502: produce lots of segments without cross-thread relations\n");
   7359 
   7360    t.Start();
   7361    t.Join();
   7362 }
   7363 
   7364 REGISTER_TEST2(Run, 502, MEMORY_USAGE | PRINT_STATS | EXCLUDE_FROM_ALL
   7365                               | PERFORMANCE)
   7366 }  // namespace test502
   7367 
   7368 // test503: produce lots of segments with simple HB-relations {{{1
   7369 // HB cache-miss rate is ~55%
   7370 namespace test503 {
   7371 
   7372 //  |- |  |  |  |  |
   7373 //  | \|  |  |  |  |
   7374 //  |  |- |  |  |  |
   7375 //  |  | \|  |  |  |
   7376 //  |  |  |- |  |  |
   7377 //  |  |  | \|  |  |
   7378 //  |  |  |  |- |  |
   7379 //  |  |  |  | \|  |
   7380 //  |  |  |  |  |- |
   7381 //  |  |  |  |  | \|
   7382 //  |  |  |  |  |  |----
   7383 //->|  |  |  |  |  |
   7384 //  |- |  |  |  |  |
   7385 //  | \|  |  |  |  |
   7386 //     ...
   7387 
   7388 const int N_threads = 32;
   7389 const int ARRAY_SIZE = 128;
   7390 int       GLOB[ARRAY_SIZE];
   7391 ProducerConsumerQueue *Q[N_threads];
   7392 int GLOB_limit = 100000;
   7393 int count = -1;
   7394 
   7395 void Worker(){
   7396    int myId = AtomicIncrement(&count, 1);
   7397 
   7398    ProducerConsumerQueue &myQ = *Q[myId], &nextQ = *Q[(myId+1) % N_threads];
   7399 
   7400    // this code produces a new SS with each new segment
   7401    while (myQ.Get() != NULL) {
   7402       for (int i = 0; i < ARRAY_SIZE; i++)
   7403          GLOB[i]++;
   7404 
   7405       if (myId == 0 && GLOB[0] > GLOB_limit) {
   7406          // Stop all threads
   7407          for (int i = 0; i < N_threads; i++)
   7408             Q[i]->Put(NULL);
   7409       } else
   7410          nextQ.Put(GLOB);
   7411    }
   7412 }
   7413 
   7414 void Run() {
   7415    printf("test503: produce lots of segments with simple HB-relations\n");
   7416    for (int i = 0; i < N_threads; i++)
   7417       Q[i] = new ProducerConsumerQueue(1);
   7418    Q[0]->Put(GLOB);
   7419 
   7420    {
   7421       ThreadPool pool(N_threads);
   7422       pool.StartWorkers();
   7423       for (int i = 0; i < N_threads; i++) {
   7424          pool.Add(NewCallback(Worker));
   7425       }
   7426    } // all folks are joined here.
   7427 
   7428    for (int i = 0; i < N_threads; i++)
   7429       delete Q[i];
   7430 }
   7431 
   7432 REGISTER_TEST2(Run, 503, MEMORY_USAGE | PRINT_STATS
   7433                   | PERFORMANCE | EXCLUDE_FROM_ALL)
   7434 }  // namespace test503
   7435 
   7436 // test504: force massive cache fetch-wback (50% misses, mostly CacheLineZ) {{{1
   7437 namespace test504 {
   7438 
   7439 const int N_THREADS = 2,
   7440           HG_CACHELINE_COUNT = 1 << 16,
   7441           HG_CACHELINE_SIZE  = 1 << 6,
   7442           HG_CACHE_SIZE = HG_CACHELINE_COUNT * HG_CACHELINE_SIZE;
   7443 
   7444 // int gives us ~4x speed of the byte test
   7445 // 4x array size gives us
   7446 // total multiplier of 16x over the cachesize
   7447 // so we can neglect the cached-at-the-end memory
   7448 const int ARRAY_SIZE = 4 * HG_CACHE_SIZE,
   7449           ITERATIONS = 30;
   7450 int array[ARRAY_SIZE];
   7451 
   7452 int count = 0;
   7453 Mutex count_mu;
   7454 
   7455 void Worker() {
   7456    count_mu.Lock();
   7457    int myId = ++count;
   7458    count_mu.Unlock();
   7459 
   7460    // all threads write to different memory locations,
   7461    // so no synchronization mechanisms are needed
   7462    int lower_bound = ARRAY_SIZE * (myId-1) / N_THREADS,
   7463        upper_bound = ARRAY_SIZE * ( myId ) / N_THREADS;
   7464    for (int j = 0; j < ITERATIONS; j++)
   7465    for (int i = lower_bound; i < upper_bound;
   7466             i += HG_CACHELINE_SIZE / sizeof(array[0])) {
   7467       array[i] = i; // each array-write generates a cache miss
   7468    }
   7469 }
   7470 
   7471 void Run() {
   7472    printf("test504: force massive CacheLineZ fetch-wback\n");
   7473    MyThreadArray t(Worker, Worker);
   7474    t.Start();
   7475    t.Join();
   7476 }
   7477 
   7478 REGISTER_TEST2(Run, 504, PERFORMANCE | PRINT_STATS | EXCLUDE_FROM_ALL)
   7479 }  // namespace test504
   7480 
   7481 // test505: force massive cache fetch-wback (60% misses) {{{1
   7482 // modification of test504 - more threads, byte accesses and lots of mutexes
   7483 // so it produces lots of CacheLineF misses (30-50% of CacheLineZ misses)
   7484 namespace test505 {
   7485 
   7486 const int N_THREADS = 2,
   7487           HG_CACHELINE_COUNT = 1 << 16,
   7488           HG_CACHELINE_SIZE  = 1 << 6,
   7489           HG_CACHE_SIZE = HG_CACHELINE_COUNT * HG_CACHELINE_SIZE;
   7490 
   7491 const int ARRAY_SIZE = 4 * HG_CACHE_SIZE,
   7492           ITERATIONS = 3;
   7493 int64_t array[ARRAY_SIZE];
   7494 
   7495 int count = 0;
   7496 Mutex count_mu;
   7497 
   7498 void Worker() {
   7499    const int N_MUTEXES = 5;
   7500    Mutex mu[N_MUTEXES];
   7501    count_mu.Lock();
   7502    int myId = ++count;
   7503    count_mu.Unlock();
   7504 
   7505    // all threads write to different memory locations,
   7506    // so no synchronization mechanisms are needed
   7507    int lower_bound = ARRAY_SIZE * (myId-1) / N_THREADS,
   7508        upper_bound = ARRAY_SIZE * ( myId ) / N_THREADS;
   7509    for (int j = 0; j < ITERATIONS; j++)
   7510    for (int mutex_id = 0; mutex_id < N_MUTEXES; mutex_id++) {
   7511       Mutex *m = & mu[mutex_id];
   7512       m->Lock();
   7513       for (int i = lower_bound + mutex_id, cnt = 0;
   7514                i < upper_bound;
   7515                i += HG_CACHELINE_SIZE / sizeof(array[0]), cnt++) {
   7516          array[i] = i; // each array-write generates a cache miss
   7517       }
   7518       m->Unlock();
   7519    }
   7520 }
   7521 
   7522 void Run() {
   7523    printf("test505: force massive CacheLineF fetch-wback\n");
   7524    MyThreadArray t(Worker, Worker);
   7525    t.Start();
   7526    t.Join();
   7527 }
   7528 
   7529 REGISTER_TEST2(Run, 505, PERFORMANCE | PRINT_STATS | EXCLUDE_FROM_ALL)
   7530 }  // namespace test505
   7531 
   7532 // test506: massive HB's using Barriers {{{1
   7533 // HB cache miss is ~40%
   7534 // segments consume 10x more memory than SSs
   7535 // modification of test39
   7536 namespace test506 {
   7537 #ifndef NO_BARRIER
   7538 // Same as test17 but uses Barrier class (pthread_barrier_t).
   7539 int     GLOB = 0;
   7540 const int N_threads = 64,
   7541           ITERATIONS = 1000;
   7542 Barrier *barrier[ITERATIONS];
   7543 Mutex   MU;
   7544 
   7545 void Worker() {
   7546   for (int i = 0; i < ITERATIONS; i++) {
   7547      MU.Lock();
   7548      GLOB++;
   7549      MU.Unlock();
   7550      barrier[i]->Block();
   7551   }
   7552 }
   7553 void Run() {
   7554   printf("test506: massive HB's using Barriers\n");
   7555   for (int i = 0; i < ITERATIONS; i++) {
   7556      barrier[i] = new Barrier(N_threads);
   7557   }
   7558   {
   7559     ThreadPool pool(N_threads);
   7560     pool.StartWorkers();
   7561     for (int i = 0; i < N_threads; i++) {
   7562       pool.Add(NewCallback(Worker));
   7563     }
   7564   } // all folks are joined here.
   7565   CHECK(GLOB == N_threads * ITERATIONS);
   7566   for (int i = 0; i < ITERATIONS; i++) {
   7567      delete barrier[i];
   7568   }
   7569 }
   7570 REGISTER_TEST2(Run, 506, PERFORMANCE | PRINT_STATS | EXCLUDE_FROM_ALL);
   7571 #endif // NO_BARRIER
   7572 }  // namespace test506
   7573 
   7574 // test507: vgHelgrind_initIterAtFM/stackClear benchmark {{{1
   7575 // vgHelgrind_initIterAtFM/stackClear consume ~8.5%/5.5% CPU
   7576 namespace test507 {
   7577 const int N_THREADS    = 1,
   7578           BUFFER_SIZE  = 1,
   7579           ITERATIONS   = 1 << 20;
   7580 
   7581 void Foo() {
   7582   struct T {
   7583     char temp;
   7584     T() {
   7585       ANNOTATE_RWLOCK_CREATE(&temp);
   7586     }
   7587     ~T() {
   7588       ANNOTATE_RWLOCK_DESTROY(&temp);
   7589     }
   7590   } s[BUFFER_SIZE];
   7591   s->temp = '\0';
   7592 }
   7593 
   7594 void Worker() {
   7595   for (int j = 0; j < ITERATIONS; j++) {
   7596     Foo();
   7597   }
   7598 }
   7599 
   7600 void Run() {
   7601   printf("test507: vgHelgrind_initIterAtFM/stackClear benchmark\n");
   7602   {
   7603     ThreadPool pool(N_THREADS);
   7604     pool.StartWorkers();
   7605     for (int i = 0; i < N_THREADS; i++) {
   7606       pool.Add(NewCallback(Worker));
   7607     }
   7608   } // all folks are joined here.
   7609 }
   7610 REGISTER_TEST2(Run, 507, EXCLUDE_FROM_ALL);
   7611 }  // namespace test507
   7612 
   7613 // test508: cmp_WordVecs_for_FM benchmark {{{1
   7614 // 50+% of CPU consumption by cmp_WordVecs_for_FM
   7615 namespace test508 {
   7616 const int N_THREADS    = 1,
   7617           BUFFER_SIZE  = 1 << 10,
   7618           ITERATIONS   = 1 << 9;
   7619 
   7620 void Foo() {
   7621   struct T {
   7622     char temp;
   7623     T() {
   7624       ANNOTATE_RWLOCK_CREATE(&temp);
   7625     }
   7626     ~T() {
   7627       ANNOTATE_RWLOCK_DESTROY(&temp);
   7628     }
   7629   } s[BUFFER_SIZE];
   7630   s->temp = '\0';
   7631 }
   7632 
   7633 void Worker() {
   7634   for (int j = 0; j < ITERATIONS; j++) {
   7635     Foo();
   7636   }
   7637 }
   7638 
   7639 void Run() {
   7640   printf("test508: cmp_WordVecs_for_FM benchmark\n");
   7641   {
   7642     ThreadPool pool(N_THREADS);
   7643     pool.StartWorkers();
   7644     for (int i = 0; i < N_THREADS; i++) {
   7645       pool.Add(NewCallback(Worker));
   7646     }
   7647   } // all folks are joined here.
   7648 }
   7649 REGISTER_TEST2(Run, 508, EXCLUDE_FROM_ALL);
   7650 }  // namespace test508
   7651 
   7652 // test509: avl_find_node benchmark {{{1
   7653 // 10+% of CPU consumption by avl_find_node
   7654 namespace test509 {
   7655 const int N_THREADS    = 16,
   7656           ITERATIONS   = 1 << 8;
   7657 
   7658 void Worker() {
   7659   std::vector<Mutex*> mu_list;
   7660   for (int i = 0; i < ITERATIONS; i++) {
   7661     Mutex * mu = new Mutex();
   7662     mu_list.push_back(mu);
   7663     mu->Lock();
   7664   }
   7665   for (int i = ITERATIONS - 1; i >= 0; i--) {
   7666     Mutex * mu = mu_list[i];
   7667     mu->Unlock();
   7668     delete mu;
   7669   }
   7670 }
   7671 
   7672 void Run() {
   7673   printf("test509: avl_find_node benchmark\n");
   7674   {
   7675     ThreadPool pool(N_THREADS);
   7676     pool.StartWorkers();
   7677     for (int i = 0; i < N_THREADS; i++) {
   7678       pool.Add(NewCallback(Worker));
   7679     }
   7680   } // all folks are joined here.
   7681 }
   7682 REGISTER_TEST2(Run, 509, EXCLUDE_FROM_ALL);
   7683 }  // namespace test509
   7684 
   7685 // test510: SS-recycle test {{{1
   7686 // this tests shows the case where only ~1% of SS are recycled
   7687 namespace test510 {
   7688 const int N_THREADS    = 16,
   7689           ITERATIONS   = 1 << 10;
   7690 int GLOB = 0;
   7691 
   7692 void Worker() {
   7693   usleep(100000);
   7694   for (int i = 0; i < ITERATIONS; i++) {
   7695     ANNOTATE_CONDVAR_SIGNAL((void*)0xDeadBeef);
   7696     GLOB++;
   7697     usleep(10);
   7698   }
   7699 }
   7700 
   7701 void Run() {
   7702   //ANNOTATE_BENIGN_RACE(&GLOB, "Test");
   7703   printf("test510: SS-recycle test\n");
   7704   {
   7705     ThreadPool pool(N_THREADS);
   7706     pool.StartWorkers();
   7707     for (int i = 0; i < N_THREADS; i++) {
   7708       pool.Add(NewCallback(Worker));
   7709     }
   7710   } // all folks are joined here.
   7711 }
   7712 REGISTER_TEST2(Run, 510, MEMORY_USAGE | PRINT_STATS | EXCLUDE_FROM_ALL);
   7713 }  // namespace test510
   7714 
   7715 // test511: Segment refcounting test ('1' refcounting) {{{1
   7716 namespace test511 {
   7717 int GLOB = 0;
   7718 
   7719 void Run () {
   7720    for (int i = 0; i < 300; i++) {
   7721       ANNOTATE_CONDVAR_SIGNAL(&GLOB);
   7722       usleep(1000);
   7723       GLOB++;
   7724       ANNOTATE_CONDVAR_WAIT(&GLOB);
   7725       if (i % 100 == 0)
   7726          ANNOTATE_PRINT_MEMORY_USAGE(0);
   7727    }
   7728 }
   7729 REGISTER_TEST2(Run, 511, MEMORY_USAGE | PRINT_STATS | EXCLUDE_FROM_ALL);
   7730 }  // namespace test511
   7731 
   7732 // test512: Segment refcounting test ('S' refcounting) {{{1
   7733 namespace test512 {
   7734 int GLOB = 0;
   7735 sem_t SEM;
   7736 
   7737 void Run () {
   7738    sem_init(&SEM, 0, 0);
   7739    for (int i = 0; i < 300; i++) {
   7740       sem_post(&SEM);
   7741       usleep(1000);
   7742       GLOB++;
   7743       sem_wait(&SEM);
   7744       /*if (i % 100 == 0)
   7745          ANNOTATE_PRINT_MEMORY_USAGE(0);*/
   7746    }
   7747    sem_destroy(&SEM);
   7748 }
   7749 REGISTER_TEST2(Run, 512, MEMORY_USAGE | PRINT_STATS | EXCLUDE_FROM_ALL);
   7750 }  // namespace test512
   7751 
   7752 // test513: --fast-mode benchmark {{{1
   7753 namespace test513 {
   7754 
   7755 const int N_THREADS = 2,
   7756           HG_CACHELINE_SIZE  = 1 << 6,
   7757           ARRAY_SIZE = HG_CACHELINE_SIZE * 512,
   7758           MUTEX_ID_BITS = 8,
   7759           MUTEX_ID_MASK = (1 << MUTEX_ID_BITS) - 1;
   7760 
   7761 // Each thread has its own cacheline and tackles with it intensively
   7762 const int ITERATIONS = 1024;
   7763 int array[N_THREADS][ARRAY_SIZE];
   7764 
   7765 int count = 0;
   7766 Mutex count_mu;
   7767 Mutex mutex_arr[N_THREADS][MUTEX_ID_BITS];
   7768 
   7769 void Worker() {
   7770    count_mu.Lock();
   7771    int myId = count++;
   7772    count_mu.Unlock();
   7773 
   7774    // all threads write to different memory locations
   7775    for (int j = 0; j < ITERATIONS; j++) {
   7776       int mutex_mask = j & MUTEX_ID_BITS;
   7777       for (int m = 0; m < MUTEX_ID_BITS; m++)
   7778          if (mutex_mask & (1 << m))
   7779             mutex_arr[myId][m].Lock();
   7780 
   7781       for (int i = 0; i < ARRAY_SIZE; i++) {
   7782          array[myId][i] = i;
   7783       }
   7784 
   7785       for (int m = 0; m < MUTEX_ID_BITS; m++)
   7786          if (mutex_mask & (1 << m))
   7787             mutex_arr[myId][m].Unlock();
   7788    }
   7789 }
   7790 
   7791 void Run() {
   7792    printf("test513: --fast-mode benchmark\n");
   7793    {
   7794       ThreadPool pool(N_THREADS);
   7795       pool.StartWorkers();
   7796       for (int i = 0; i < N_THREADS; i++) {
   7797          pool.Add(NewCallback(Worker));
   7798       }
   7799    } // all folks are joined here.
   7800 }
   7801 
   7802 REGISTER_TEST2(Run, 513, PERFORMANCE | PRINT_STATS | EXCLUDE_FROM_ALL)
   7803 }  // namespace test513
   7804 
   7805 // End {{{1
   7806 // vim:shiftwidth=2:softtabstop=2:expandtab:foldmethod=marker
   7807