tsan_defs.h revision a52e5c6f371bcc66e89792db1219a557664aab8d
1//===-- tsan_defs.h ---------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of ThreadSanitizer (TSan), a race detector.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef TSAN_DEFS_H
15#define TSAN_DEFS_H
16
17#include "sanitizer_common/sanitizer_internal_defs.h"
18#include "sanitizer_common/sanitizer_libc.h"
19#include "tsan_stat.h"
20
21#ifndef TSAN_DEBUG
22#define TSAN_DEBUG 0
23#endif  // TSAN_DEBUG
24
25namespace __tsan {
26
27#ifdef TSAN_GO
28const bool kGoMode = true;
29const bool kCppMode = false;
30const char *const kTsanOptionsEnv = "GORACE";
31// Go linker does not support weak symbols.
32#define CPP_WEAK
33#else
34const bool kGoMode = false;
35const bool kCppMode = true;
36const char *const kTsanOptionsEnv = "TSAN_OPTIONS";
37#define CPP_WEAK WEAK
38#endif
39
40const int kTidBits = 13;
41const unsigned kMaxTid = 1 << kTidBits;
42const unsigned kMaxTidInClock = kMaxTid * 2;  // This includes msb 'freed' bit.
43const int kClkBits = 42;
44#ifndef TSAN_GO
45const int kShadowStackSize = 4 * 1024;
46const int kTraceStackSize = 256;
47#endif
48
49#ifdef TSAN_SHADOW_COUNT
50# if TSAN_SHADOW_COUNT == 2 \
51  || TSAN_SHADOW_COUNT == 4 || TSAN_SHADOW_COUNT == 8
52const uptr kShadowCnt = TSAN_SHADOW_COUNT;
53# else
54#   error "TSAN_SHADOW_COUNT must be one of 2,4,8"
55# endif
56#else
57// Count of shadow values in a shadow cell.
58const uptr kShadowCnt = 4;
59#endif
60
61// That many user bytes are mapped onto a single shadow cell.
62const uptr kShadowCell = 8;
63
64// Size of a single shadow value (u64).
65const uptr kShadowSize = 8;
66
67// Shadow memory is kShadowMultiplier times larger than user memory.
68const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;
69
70#if defined(TSAN_COLLECT_STATS) && TSAN_COLLECT_STATS
71const bool kCollectStats = true;
72#else
73const bool kCollectStats = false;
74#endif
75
76// The following "build consistency" machinery ensures that all source files
77// are built in the same configuration. Inconsistent builds lead to
78// hard to debug crashes.
79#if TSAN_DEBUG
80void build_consistency_debug();
81#else
82void build_consistency_release();
83#endif
84
85#if TSAN_COLLECT_STATS
86void build_consistency_stats();
87#else
88void build_consistency_nostats();
89#endif
90
91#if TSAN_SHADOW_COUNT == 1
92void build_consistency_shadow1();
93#elif TSAN_SHADOW_COUNT == 2
94void build_consistency_shadow2();
95#elif TSAN_SHADOW_COUNT == 4
96void build_consistency_shadow4();
97#else
98void build_consistency_shadow8();
99#endif
100
101static inline void USED build_consistency() {
102#if TSAN_DEBUG
103  build_consistency_debug();
104#else
105  build_consistency_release();
106#endif
107#if TSAN_COLLECT_STATS
108  build_consistency_stats();
109#else
110  build_consistency_nostats();
111#endif
112#if TSAN_SHADOW_COUNT == 1
113  build_consistency_shadow1();
114#elif TSAN_SHADOW_COUNT == 2
115  build_consistency_shadow2();
116#elif TSAN_SHADOW_COUNT == 4
117  build_consistency_shadow4();
118#else
119  build_consistency_shadow8();
120#endif
121}
122
123template<typename T>
124T min(T a, T b) {
125  return a < b ? a : b;
126}
127
128template<typename T>
129T max(T a, T b) {
130  return a > b ? a : b;
131}
132
133template<typename T>
134T RoundUp(T p, u64 align) {
135  DCHECK_EQ(align & (align - 1), 0);
136  return (T)(((u64)p + align - 1) & ~(align - 1));
137}
138
139template<typename T>
140T RoundDown(T p, u64 align) {
141  DCHECK_EQ(align & (align - 1), 0);
142  return (T)((u64)p & ~(align - 1));
143}
144
145// Zeroizes high part, returns 'bits' lsb bits.
146template<typename T>
147T GetLsb(T v, int bits) {
148  return (T)((u64)v & ((1ull << bits) - 1));
149}
150
151struct MD5Hash {
152  u64 hash[2];
153  bool operator==(const MD5Hash &other) const;
154};
155
156MD5Hash md5_hash(const void *data, uptr size);
157
158struct ThreadState;
159struct Context;
160struct ReportStack;
161class ReportDesc;
162class RegionAlloc;
163class StackTrace;
164struct MBlock;
165
166}  // namespace __tsan
167
168#endif  // TSAN_DEFS_H
169