1//===-- tsan_test_util.h ----------------------------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of ThreadSanitizer (TSan), a race detector.
10//
11// Test utils.
12//===----------------------------------------------------------------------===//
13#ifndef TSAN_TEST_UTIL_H
14#define TSAN_TEST_UTIL_H
15
16#include "gtest/gtest.h"
17
18class ThreadSanitizer : public ::testing::Test {
19 protected:
20 void TearDown() override;
21};
22
23void TestMutexBeforeInit();
24
25// A location of memory on which a race may be detected.
26class MemLoc {
27 public:
28 explicit MemLoc(int offset_from_aligned = 0);
29 explicit MemLoc(void *const real_addr) : loc_(real_addr) { }
30 ~MemLoc();
31 void *loc() const { return loc_; }
32 private:
33 void *const loc_;
34 MemLoc(const MemLoc&);
35 void operator = (const MemLoc&);
36};
37
38class UserMutex {
39 public:
40 enum Type {
41 Normal,
42 RW,
43#ifndef __APPLE__
44 Spin
45#else
46 Spin = Normal
47#endif
48 };
49
50 explicit UserMutex(Type type = Normal);
51 ~UserMutex();
52
53 void Init();
54 void StaticInit(); // Emulates static initialization (tsan invisible).
55 void Destroy();
56 void Lock();
57 bool TryLock();
58 void Unlock();
59 void ReadLock();
60 bool TryReadLock();
61 void ReadUnlock();
62
63 private:
64 // Placeholder for pthread_mutex_t, CRITICAL_SECTION or whatever.
65 void *mtx_[128];
66 bool alive_;
67 const Type type_;
68
69 UserMutex(const UserMutex &);
70 void operator=(const UserMutex &);
71};
72
73// A thread is started in CTOR and joined in DTOR.
74class ScopedThread {
75 public:
76 explicit ScopedThread(bool detached = false, bool main = false);
77 ~ScopedThread();
78 void Detach();
79
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(addr: ml.loc(), is_write: false, size, expect_race);
83 }
84 void Write(const MemLoc &ml, int size, bool expect_race = false) {
85 Access(addr: ml.loc(), is_write: true, size, expect_race);
86 }
87 void Read1(const MemLoc &ml, bool expect_race = false) {
88 Read(ml, size: 1, expect_race); }
89 void Read2(const MemLoc &ml, bool expect_race = false) {
90 Read(ml, size: 2, expect_race); }
91 void Read4(const MemLoc &ml, bool expect_race = false) {
92 Read(ml, size: 4, expect_race); }
93 void Read8(const MemLoc &ml, bool expect_race = false) {
94 Read(ml, size: 8, expect_race); }
95 void Write1(const MemLoc &ml, bool expect_race = false) {
96 Write(ml, size: 1, expect_race); }
97 void Write2(const MemLoc &ml, bool expect_race = false) {
98 Write(ml, size: 2, expect_race); }
99 void Write4(const MemLoc &ml, bool expect_race = false) {
100 Write(ml, size: 4, expect_race); }
101 void Write8(const MemLoc &ml, bool expect_race = false) {
102 Write(ml, size: 8, expect_race); }
103
104 void VptrUpdate(const MemLoc &vptr, const MemLoc &new_val,
105 bool expect_race = false);
106
107 void Call(void(*pc)());
108 void Return();
109
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);
118
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);
121
122 private:
123 struct Impl;
124 Impl *impl_;
125 ScopedThread(const ScopedThread&); // Not implemented.
126 void operator = (const ScopedThread&); // Not implemented.
127};
128
129class MainThread : public ScopedThread {
130 public:
131 MainThread()
132 : ScopedThread(false, true) {
133 }
134};
135
136#endif // #ifndef TSAN_TEST_UTIL_H
137

source code of compiler-rt/lib/tsan/tests/rtl/tsan_test_util.h