blob: e761c787e61098146e0cbb3538200c13355a0458 [file] [log] [blame]
Kostya Serebryany4ad375f2012-05-10 13:48:04 +00001//===-- 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
Alexey Samsonov5bbf8292012-06-05 14:25:27 +000017#include "sanitizer_common/sanitizer_internal_defs.h"
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000018#include "tsan_stat.h"
19
20#ifndef TSAN_DEBUG
21#define TSAN_DEBUG 0
22#endif // TSAN_DEBUG
23
Alexey Samsonovef2e2cf2012-06-05 13:50:57 +000024namespace __tsan {
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000025
26const uptr kPageSize = 4096;
Dmitry Vyukovf6985e32012-05-22 14:34:43 +000027const int kTidBits = 13;
Kostya Serebryany07c48052012-05-11 14:42:24 +000028const unsigned kMaxTid = 1 << kTidBits;
Dmitry Vyukovfee5b7d2012-05-17 14:17:51 +000029const unsigned kMaxTidInClock = kMaxTid * 2; // This includes msb 'freed' bit.
Dmitry Vyukov302cebb2012-05-22 18:07:45 +000030const int kClkBits = 43;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000031
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#define CHECK_IMPL(c1, op, c2) \
57 do { \
Alexey Samsonovef2e2cf2012-06-05 13:50:57 +000058 __sanitizer::u64 v1 = (u64)(c1); \
59 __sanitizer::u64 v2 = (u64)(c2); \
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000060 if (!(v1 op v2)) \
61 __tsan::CheckFailed(__FILE__, __LINE__, \
62 "(" #c1 ") " #op " (" #c2 ")", v1, v2); \
63 } while (false) \
64/**/
65
66#define CHECK(a) CHECK_IMPL((a), !=, 0)
67#define CHECK_EQ(a, b) CHECK_IMPL((a), ==, (b))
68#define CHECK_NE(a, b) CHECK_IMPL((a), !=, (b))
69#define CHECK_LT(a, b) CHECK_IMPL((a), <, (b))
70#define CHECK_LE(a, b) CHECK_IMPL((a), <=, (b))
71#define CHECK_GT(a, b) CHECK_IMPL((a), >, (b))
72#define CHECK_GE(a, b) CHECK_IMPL((a), >=, (b))
73
74#if TSAN_DEBUG
75#define DCHECK(a) CHECK(a)
76#define DCHECK_EQ(a, b) CHECK_EQ(a, b)
77#define DCHECK_NE(a, b) CHECK_NE(a, b)
78#define DCHECK_LT(a, b) CHECK_LT(a, b)
79#define DCHECK_LE(a, b) CHECK_LE(a, b)
80#define DCHECK_GT(a, b) CHECK_GT(a, b)
81#define DCHECK_GE(a, b) CHECK_GE(a, b)
82#else
83#define DCHECK(a)
84#define DCHECK_EQ(a, b)
85#define DCHECK_NE(a, b)
86#define DCHECK_LT(a, b)
87#define DCHECK_LE(a, b)
88#define DCHECK_GT(a, b)
89#define DCHECK_GE(a, b)
90#endif
91
92void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2);
93
94// The following "build consistency" machinery ensures that all source files
95// are built in the same configuration. Inconsistent builds lead to
96// hard to debug crashes.
97#if TSAN_DEBUG
98void build_consistency_debug();
99#else
100void build_consistency_release();
101#endif
102
103#if TSAN_COLLECT_STATS
104void build_consistency_stats();
105#else
106void build_consistency_nostats();
107#endif
108
109#if TSAN_SHADOW_COUNT == 1
110void build_consistency_shadow1();
111#elif TSAN_SHADOW_COUNT == 2
112void build_consistency_shadow2();
113#elif TSAN_SHADOW_COUNT == 4
114void build_consistency_shadow4();
115#else
116void build_consistency_shadow8();
117#endif
118
119static inline void USED build_consistency() {
120#if TSAN_DEBUG
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000121 build_consistency_debug();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000122#else
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000123 build_consistency_release();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000124#endif
125#if TSAN_COLLECT_STATS
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000126 build_consistency_stats();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000127#else
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000128 build_consistency_nostats();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000129#endif
130#if TSAN_SHADOW_COUNT == 1
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000131 build_consistency_shadow1();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000132#elif TSAN_SHADOW_COUNT == 2
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000133 build_consistency_shadow2();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000134#elif TSAN_SHADOW_COUNT == 4
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000135 build_consistency_shadow4();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000136#else
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000137 build_consistency_shadow8();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000138#endif
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000139}
140
141template<typename T>
142T min(T a, T b) {
143 return a < b ? a : b;
144}
145
146template<typename T>
147T max(T a, T b) {
148 return a > b ? a : b;
149}
150
151template<typename T>
152T RoundUp(T p, int align) {
153 DCHECK_EQ(align & (align - 1), 0);
154 return (T)(((u64)p + align - 1) & ~(align - 1));
155}
156
157void internal_memset(void *ptr, int c, uptr size);
158void internal_memcpy(void *dst, const void *src, uptr size);
159int internal_memcmp(const void *s1, const void *s2, uptr size);
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000160int internal_strncmp(const char *s1, const char *s2, uptr size);
161void internal_strcpy(char *s1, const char *s2);
162uptr internal_strlen(const char *s);
163char* internal_strdup(const char *s);
164const char *internal_strstr(const char *where, const char *what);
165const char *internal_strchr(const char *where, char what);
Dmitry Vyukov7339eb12012-05-25 11:15:04 +0000166const char *internal_strrchr(const char *where, char what);
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000167
168struct MD5Hash {
169 u64 hash[2];
170 bool operator==(const MD5Hash &other) const {
171 return hash[0] == other.hash[0] && hash[1] == other.hash[1];
172 }
173};
174
175MD5Hash md5_hash(const void *data, uptr size);
176
177struct ThreadState;
178struct ThreadContext;
179struct Context;
180struct ReportStack;
181class ReportDesc;
182class RegionAlloc;
183class StackTrace;
184
185} // namespace __tsan
186
187#endif // TSAN_DEFS_H