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