blob: ae99ecc483580eb307109656f1fc407d87f498f4 [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 Samsonov3efd6fc2012-06-15 12:24:07 +000017#include "interception/interception.h"
Alexey Samsonov5bbf8292012-06-05 14:25:27 +000018#include "sanitizer_common/sanitizer_internal_defs.h"
Alexey Samsonov91e1a7e2012-06-07 11:54:08 +000019#include "sanitizer_common/sanitizer_libc.h"
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000020#include "tsan_stat.h"
21
22#ifndef TSAN_DEBUG
23#define TSAN_DEBUG 0
24#endif // TSAN_DEBUG
25
Alexey Samsonovef2e2cf2012-06-05 13:50:57 +000026namespace __tsan {
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000027
Dmitry Vyukovf6985e32012-05-22 14:34:43 +000028const int kTidBits = 13;
Kostya Serebryany07c48052012-05-11 14:42:24 +000029const unsigned kMaxTid = 1 << kTidBits;
Dmitry Vyukovfee5b7d2012-05-17 14:17:51 +000030const unsigned kMaxTidInClock = kMaxTid * 2; // This includes msb 'freed' bit.
Dmitry Vyukov302cebb2012-05-22 18:07:45 +000031const int kClkBits = 43;
Dmitry Vyukovde1fd1c2012-06-22 11:08:55 +000032const int kShadowStackSize = 1024;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000033
34#ifdef TSAN_SHADOW_COUNT
35# if TSAN_SHADOW_COUNT == 2 \
36 || TSAN_SHADOW_COUNT == 4 || TSAN_SHADOW_COUNT == 8
37const unsigned kShadowCnt = TSAN_SHADOW_COUNT;
38# else
39# error "TSAN_SHADOW_COUNT must be one of 2,4,8"
40# endif
41#else
42// Count of shadow values in a shadow cell.
43const unsigned kShadowCnt = 8;
44#endif
45
46// That many user bytes are mapped onto a single shadow cell.
47const unsigned kShadowCell = 8;
48
49// Size of a single shadow value (u64).
50const unsigned kShadowSize = 8;
51
52#if defined(TSAN_COLLECT_STATS) && TSAN_COLLECT_STATS
53const bool kCollectStats = true;
54#else
55const bool kCollectStats = false;
56#endif
57
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000058#if TSAN_DEBUG
59#define DCHECK(a) CHECK(a)
60#define DCHECK_EQ(a, b) CHECK_EQ(a, b)
61#define DCHECK_NE(a, b) CHECK_NE(a, b)
62#define DCHECK_LT(a, b) CHECK_LT(a, b)
63#define DCHECK_LE(a, b) CHECK_LE(a, b)
64#define DCHECK_GT(a, b) CHECK_GT(a, b)
65#define DCHECK_GE(a, b) CHECK_GE(a, b)
66#else
67#define DCHECK(a)
68#define DCHECK_EQ(a, b)
69#define DCHECK_NE(a, b)
70#define DCHECK_LT(a, b)
71#define DCHECK_LE(a, b)
72#define DCHECK_GT(a, b)
73#define DCHECK_GE(a, b)
74#endif
75
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000076// The following "build consistency" machinery ensures that all source files
77// are built in the same configuration. Inconsistent builds lead to
78// hard to debug crashes.
79#if TSAN_DEBUG
80void build_consistency_debug();
81#else
82void build_consistency_release();
83#endif
84
85#if TSAN_COLLECT_STATS
86void build_consistency_stats();
87#else
88void build_consistency_nostats();
89#endif
90
91#if TSAN_SHADOW_COUNT == 1
92void build_consistency_shadow1();
93#elif TSAN_SHADOW_COUNT == 2
94void build_consistency_shadow2();
95#elif TSAN_SHADOW_COUNT == 4
96void build_consistency_shadow4();
97#else
98void build_consistency_shadow8();
99#endif
100
101static inline void USED build_consistency() {
102#if TSAN_DEBUG
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000103 build_consistency_debug();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000104#else
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000105 build_consistency_release();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000106#endif
107#if TSAN_COLLECT_STATS
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000108 build_consistency_stats();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000109#else
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000110 build_consistency_nostats();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000111#endif
112#if TSAN_SHADOW_COUNT == 1
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000113 build_consistency_shadow1();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000114#elif TSAN_SHADOW_COUNT == 2
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000115 build_consistency_shadow2();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000116#elif TSAN_SHADOW_COUNT == 4
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000117 build_consistency_shadow4();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000118#else
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000119 build_consistency_shadow8();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000120#endif
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000121}
122
123template<typename T>
124T min(T a, T b) {
125 return a < b ? a : b;
126}
127
128template<typename T>
129T max(T a, T b) {
130 return a > b ? a : b;
131}
132
133template<typename T>
134T RoundUp(T p, int align) {
135 DCHECK_EQ(align & (align - 1), 0);
136 return (T)(((u64)p + align - 1) & ~(align - 1));
137}
138
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000139struct MD5Hash {
140 u64 hash[2];
141 bool operator==(const MD5Hash &other) const {
142 return hash[0] == other.hash[0] && hash[1] == other.hash[1];
143 }
144};
145
146MD5Hash md5_hash(const void *data, uptr size);
147
148struct ThreadState;
149struct ThreadContext;
150struct Context;
151struct ReportStack;
152class ReportDesc;
153class RegionAlloc;
154class StackTrace;
155
156} // namespace __tsan
157
Alexey Samsonov3efd6fc2012-06-15 12:24:07 +0000158DECLARE_REAL(void*, memset, void *ptr, int v, uptr size);
159DECLARE_REAL(void*, memcpy, void *dst, const void *src, uptr size);
160DECLARE_REAL(int, strncmp, const char *s1, const char *s2, uptr n);
161DECLARE_REAL(const char*, strstr, const char *s1, const char *s2);
162
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000163#endif // TSAN_DEFS_H