1 //===-- tsan_test_util.h ----------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of ThreadSanitizer (TSan), a race detector.
12 //===----------------------------------------------------------------------===//
13 #ifndef TSAN_TEST_UTIL_H
14 #define TSAN_TEST_UTIL_H
16 #include "gtest/gtest.h"
18 class ThreadSanitizer
: public ::testing::Test
{
20 void TearDown() override
;
23 void TestMutexBeforeInit();
25 // A location of memory on which a race may be detected.
28 explicit MemLoc(int offset_from_aligned
= 0);
29 explicit MemLoc(void *const real_addr
) : loc_(real_addr
) { }
31 void *loc() const { return loc_
; }
34 MemLoc(const MemLoc
&);
35 void operator = (const MemLoc
&);
50 explicit UserMutex(Type type
= Normal
);
54 void StaticInit(); // Emulates static initialization (tsan invisible).
64 // Placeholder for pthread_mutex_t, CRITICAL_SECTION or whatever.
69 UserMutex(const UserMutex
&);
70 void operator=(const UserMutex
&);
73 // A thread is started in CTOR and joined in DTOR.
76 explicit ScopedThread(bool detached
= false, bool main
= false);
80 void Access(void *addr
, bool is_write
, int size
, bool expect_race
);
81 void Read(const MemLoc
&ml
, int size
, bool expect_race
= false) {
82 Access(ml
.loc(), false, size
, expect_race
);
84 void Write(const MemLoc
&ml
, int size
, bool expect_race
= false) {
85 Access(ml
.loc(), true, size
, expect_race
);
87 void Read1(const MemLoc
&ml
, bool expect_race
= false) {
88 Read(ml
, 1, expect_race
); }
89 void Read2(const MemLoc
&ml
, bool expect_race
= false) {
90 Read(ml
, 2, expect_race
); }
91 void Read4(const MemLoc
&ml
, bool expect_race
= false) {
92 Read(ml
, 4, expect_race
); }
93 void Read8(const MemLoc
&ml
, bool expect_race
= false) {
94 Read(ml
, 8, expect_race
); }
95 void Write1(const MemLoc
&ml
, bool expect_race
= false) {
96 Write(ml
, 1, expect_race
); }
97 void Write2(const MemLoc
&ml
, bool expect_race
= false) {
98 Write(ml
, 2, expect_race
); }
99 void Write4(const MemLoc
&ml
, bool expect_race
= false) {
100 Write(ml
, 4, expect_race
); }
101 void Write8(const MemLoc
&ml
, bool expect_race
= false) {
102 Write(ml
, 8, expect_race
); }
104 void VptrUpdate(const MemLoc
&vptr
, const MemLoc
&new_val
,
105 bool expect_race
= false);
107 void Call(void(*pc
)());
110 void Create(const UserMutex
&m
);
111 void Destroy(const UserMutex
&m
);
112 void Lock(const UserMutex
&m
);
113 bool TryLock(const UserMutex
&m
);
114 void Unlock(const UserMutex
&m
);
115 void ReadLock(const UserMutex
&m
);
116 bool TryReadLock(const UserMutex
&m
);
117 void ReadUnlock(const UserMutex
&m
);
119 void Memcpy(void *dst
, const void *src
, int size
, bool expect_race
= false);
120 void Memset(void *dst
, int val
, int size
, bool expect_race
= false);
125 ScopedThread(const ScopedThread
&); // Not implemented.
126 void operator = (const ScopedThread
&); // Not implemented.
129 class MainThread
: public ScopedThread
{
132 : ScopedThread(false, true) {
136 #endif // #ifndef TSAN_TEST_UTIL_H