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