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