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