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