tsan_defs.h revision 789b6c5669547b550034fc9888059b17e2ff1417
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 "tsan_compiler.h"
18#include "tsan_stat.h"
19
20#ifndef TSAN_DEBUG
21#define TSAN_DEBUG 0
22#endif  // TSAN_DEBUG
23
24namespace __tsan {
25
26typedef unsigned u32;  // NOLINT
27typedef unsigned long long u64;  // NOLINT
28typedef   signed long long s64;  // NOLINT
29typedef unsigned long uptr;  // NOLINT
30
31const uptr kPageSize = 4096;
32const int kTidBits = 13;
33const unsigned kMaxTid = 1 << kTidBits;
34const unsigned kMaxTidInClock = kMaxTid * 2;  // This includes msb 'freed' bit.
35const int kClkBits = 43;
36
37#ifdef TSAN_SHADOW_COUNT
38# if TSAN_SHADOW_COUNT == 2 \
39  || TSAN_SHADOW_COUNT == 4 || TSAN_SHADOW_COUNT == 8
40const unsigned kShadowCnt = TSAN_SHADOW_COUNT;
41# else
42#   error "TSAN_SHADOW_COUNT must be one of 2,4,8"
43# endif
44#else
45// Count of shadow values in a shadow cell.
46const unsigned kShadowCnt = 8;
47#endif
48
49// That many user bytes are mapped onto a single shadow cell.
50const unsigned kShadowCell = 8;
51
52// Size of a single shadow value (u64).
53const unsigned kShadowSize = 8;
54
55#if defined(TSAN_COLLECT_STATS) && TSAN_COLLECT_STATS
56const bool kCollectStats = true;
57#else
58const bool kCollectStats = false;
59#endif
60
61#define CHECK_IMPL(c1, op, c2) \
62  do { \
63    __tsan::u64 v1 = (u64)(c1); \
64    __tsan::u64 v2 = (u64)(c2); \
65    if (!(v1 op v2)) \
66      __tsan::CheckFailed(__FILE__, __LINE__, \
67        "(" #c1 ") " #op " (" #c2 ")", v1, v2); \
68  } while (false) \
69/**/
70
71#define CHECK(a)       CHECK_IMPL((a), !=, 0)
72#define CHECK_EQ(a, b) CHECK_IMPL((a), ==, (b))
73#define CHECK_NE(a, b) CHECK_IMPL((a), !=, (b))
74#define CHECK_LT(a, b) CHECK_IMPL((a), <,  (b))
75#define CHECK_LE(a, b) CHECK_IMPL((a), <=, (b))
76#define CHECK_GT(a, b) CHECK_IMPL((a), >,  (b))
77#define CHECK_GE(a, b) CHECK_IMPL((a), >=, (b))
78
79#if TSAN_DEBUG
80#define DCHECK(a)       CHECK(a)
81#define DCHECK_EQ(a, b) CHECK_EQ(a, b)
82#define DCHECK_NE(a, b) CHECK_NE(a, b)
83#define DCHECK_LT(a, b) CHECK_LT(a, b)
84#define DCHECK_LE(a, b) CHECK_LE(a, b)
85#define DCHECK_GT(a, b) CHECK_GT(a, b)
86#define DCHECK_GE(a, b) CHECK_GE(a, b)
87#else
88#define DCHECK(a)
89#define DCHECK_EQ(a, b)
90#define DCHECK_NE(a, b)
91#define DCHECK_LT(a, b)
92#define DCHECK_LE(a, b)
93#define DCHECK_GT(a, b)
94#define DCHECK_GE(a, b)
95#endif
96
97void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2);
98
99// The following "build consistency" machinery ensures that all source files
100// are built in the same configuration. Inconsistent builds lead to
101// hard to debug crashes.
102#if TSAN_DEBUG
103void build_consistency_debug();
104#else
105void build_consistency_release();
106#endif
107
108#if TSAN_COLLECT_STATS
109void build_consistency_stats();
110#else
111void build_consistency_nostats();
112#endif
113
114#if TSAN_SHADOW_COUNT == 1
115void build_consistency_shadow1();
116#elif TSAN_SHADOW_COUNT == 2
117void build_consistency_shadow2();
118#elif TSAN_SHADOW_COUNT == 4
119void build_consistency_shadow4();
120#else
121void build_consistency_shadow8();
122#endif
123
124static inline void USED build_consistency() {
125#if TSAN_DEBUG
126  build_consistency_debug();
127#else
128  build_consistency_release();
129#endif
130#if TSAN_COLLECT_STATS
131  build_consistency_stats();
132#else
133  build_consistency_nostats();
134#endif
135#if TSAN_SHADOW_COUNT == 1
136  build_consistency_shadow1();
137#elif TSAN_SHADOW_COUNT == 2
138  build_consistency_shadow2();
139#elif TSAN_SHADOW_COUNT == 4
140  build_consistency_shadow4();
141#else
142  build_consistency_shadow8();
143#endif
144}
145
146template<typename T>
147T min(T a, T b) {
148  return a < b ? a : b;
149}
150
151template<typename T>
152T max(T a, T b) {
153  return a > b ? a : b;
154}
155
156template<typename T>
157T RoundUp(T p, int align) {
158  DCHECK_EQ(align & (align - 1), 0);
159  return (T)(((u64)p + align - 1) & ~(align - 1));
160}
161
162void internal_memset(void *ptr, int c, uptr size);
163void internal_memcpy(void *dst, const void *src, uptr size);
164int internal_memcmp(const void *s1, const void *s2, uptr size);
165int internal_strcmp(const char *s1, const char *s2);
166int internal_strncmp(const char *s1, const char *s2, uptr size);
167void internal_strcpy(char *s1, const char *s2);
168uptr internal_strlen(const char *s);
169char* internal_strdup(const char *s);
170const char *internal_strstr(const char *where, const char *what);
171const char *internal_strchr(const char *where, char what);
172const char *internal_strrchr(const char *where, char what);
173
174struct MD5Hash {
175  u64 hash[2];
176  bool operator==(const MD5Hash &other) const {
177    return hash[0] == other.hash[0] && hash[1] == other.hash[1];
178  }
179};
180
181MD5Hash md5_hash(const void *data, uptr size);
182
183struct ThreadState;
184struct ThreadContext;
185struct Context;
186struct ReportStack;
187class ReportDesc;
188class RegionAlloc;
189class StackTrace;
190
191}  // namespace __tsan
192
193#endif  // TSAN_DEFS_H
194