tsan_defs.h revision 9d2ffc2ee08216f8fad9b1bd267d1f112e0d2f01
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 = 40; 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 void(*volatile cfg)() = &build_consistency_debug; 127#else 128 void(*volatile cfg)() = &build_consistency_release; 129#endif 130#if TSAN_COLLECT_STATS 131 void(*volatile stats)() = &build_consistency_stats; 132#else 133 void(*volatile stats)() = &build_consistency_nostats; 134#endif 135#if TSAN_SHADOW_COUNT == 1 136 void(*volatile shadow)() = &build_consistency_shadow1; 137#elif TSAN_SHADOW_COUNT == 2 138 void(*volatile shadow)() = &build_consistency_shadow2; 139#elif TSAN_SHADOW_COUNT == 4 140 void(*volatile shadow)() = &build_consistency_shadow4; 141#else 142 void(*volatile shadow)() = &build_consistency_shadow8; 143#endif 144 (void)cfg; 145 (void)stats; 146 (void)shadow; 147} 148 149template<typename T> 150T min(T a, T b) { 151 return a < b ? a : b; 152} 153 154template<typename T> 155T max(T a, T b) { 156 return a > b ? a : b; 157} 158 159template<typename T> 160T RoundUp(T p, int align) { 161 DCHECK_EQ(align & (align - 1), 0); 162 return (T)(((u64)p + align - 1) & ~(align - 1)); 163} 164 165void internal_memset(void *ptr, int c, uptr size); 166void internal_memcpy(void *dst, const void *src, uptr size); 167int internal_memcmp(const void *s1, const void *s2, uptr size); 168int internal_strcmp(const char *s1, const char *s2); 169int internal_strncmp(const char *s1, const char *s2, uptr size); 170void internal_strcpy(char *s1, const char *s2); 171uptr internal_strlen(const char *s); 172char* internal_strdup(const char *s); 173const char *internal_strstr(const char *where, const char *what); 174const char *internal_strchr(const char *where, char what); 175 176struct MD5Hash { 177 u64 hash[2]; 178 bool operator==(const MD5Hash &other) const { 179 return hash[0] == other.hash[0] && hash[1] == other.hash[1]; 180 } 181}; 182 183MD5Hash md5_hash(const void *data, uptr size); 184 185struct ThreadState; 186struct ThreadContext; 187struct Context; 188struct ReportStack; 189class ReportDesc; 190class RegionAlloc; 191class StackTrace; 192 193} // namespace __tsan 194 195#endif // TSAN_DEFS_H 196