blob: 5127d5dc46f3d3db7ef2dd40df55bf07355fe47c [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;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000032
33#ifdef TSAN_SHADOW_COUNT
34# if TSAN_SHADOW_COUNT == 2 \
35 || TSAN_SHADOW_COUNT == 4 || TSAN_SHADOW_COUNT == 8
36const unsigned kShadowCnt = TSAN_SHADOW_COUNT;
37# else
38# error "TSAN_SHADOW_COUNT must be one of 2,4,8"
39# endif
40#else
41// Count of shadow values in a shadow cell.
42const unsigned kShadowCnt = 8;
43#endif
44
45// That many user bytes are mapped onto a single shadow cell.
46const unsigned kShadowCell = 8;
47
48// Size of a single shadow value (u64).
49const unsigned kShadowSize = 8;
50
51#if defined(TSAN_COLLECT_STATS) && TSAN_COLLECT_STATS
52const bool kCollectStats = true;
53#else
54const bool kCollectStats = false;
55#endif
56
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000057#if TSAN_DEBUG
58#define DCHECK(a) CHECK(a)
59#define DCHECK_EQ(a, b) CHECK_EQ(a, b)
60#define DCHECK_NE(a, b) CHECK_NE(a, b)
61#define DCHECK_LT(a, b) CHECK_LT(a, b)
62#define DCHECK_LE(a, b) CHECK_LE(a, b)
63#define DCHECK_GT(a, b) CHECK_GT(a, b)
64#define DCHECK_GE(a, b) CHECK_GE(a, b)
65#else
66#define DCHECK(a)
67#define DCHECK_EQ(a, b)
68#define DCHECK_NE(a, b)
69#define DCHECK_LT(a, b)
70#define DCHECK_LE(a, b)
71#define DCHECK_GT(a, b)
72#define DCHECK_GE(a, b)
73#endif
74
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000075// The following "build consistency" machinery ensures that all source files
76// are built in the same configuration. Inconsistent builds lead to
77// hard to debug crashes.
78#if TSAN_DEBUG
79void build_consistency_debug();
80#else
81void build_consistency_release();
82#endif
83
84#if TSAN_COLLECT_STATS
85void build_consistency_stats();
86#else
87void build_consistency_nostats();
88#endif
89
90#if TSAN_SHADOW_COUNT == 1
91void build_consistency_shadow1();
92#elif TSAN_SHADOW_COUNT == 2
93void build_consistency_shadow2();
94#elif TSAN_SHADOW_COUNT == 4
95void build_consistency_shadow4();
96#else
97void build_consistency_shadow8();
98#endif
99
100static inline void USED build_consistency() {
101#if TSAN_DEBUG
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000102 build_consistency_debug();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000103#else
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000104 build_consistency_release();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000105#endif
106#if TSAN_COLLECT_STATS
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000107 build_consistency_stats();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000108#else
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000109 build_consistency_nostats();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000110#endif
111#if TSAN_SHADOW_COUNT == 1
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000112 build_consistency_shadow1();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000113#elif TSAN_SHADOW_COUNT == 2
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000114 build_consistency_shadow2();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000115#elif TSAN_SHADOW_COUNT == 4
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000116 build_consistency_shadow4();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000117#else
Dmitry Vyukov30c32a82012-05-24 14:50:33 +0000118 build_consistency_shadow8();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000119#endif
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000120}
121
122template<typename T>
123T min(T a, T b) {
124 return a < b ? a : b;
125}
126
127template<typename T>
128T max(T a, T b) {
129 return a > b ? a : b;
130}
131
132template<typename T>
133T RoundUp(T p, int align) {
134 DCHECK_EQ(align & (align - 1), 0);
135 return (T)(((u64)p + align - 1) & ~(align - 1));
136}
137
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000138struct MD5Hash {
139 u64 hash[2];
140 bool operator==(const MD5Hash &other) const {
141 return hash[0] == other.hash[0] && hash[1] == other.hash[1];
142 }
143};
144
145MD5Hash md5_hash(const void *data, uptr size);
146
147struct ThreadState;
148struct ThreadContext;
149struct Context;
150struct ReportStack;
151class ReportDesc;
152class RegionAlloc;
153class StackTrace;
154
155} // namespace __tsan
156
Alexey Samsonov3efd6fc2012-06-15 12:24:07 +0000157DECLARE_REAL(void*, memset, void *ptr, int v, uptr size);
158DECLARE_REAL(void*, memcpy, void *dst, const void *src, uptr size);
159DECLARE_REAL(int, strncmp, const char *s1, const char *s2, uptr n);
160DECLARE_REAL(const char*, strstr, const char *s1, const char *s2);
161
Kostya Serebryany4ad375f2012-05-10 13:48:04 +0000162#endif // TSAN_DEFS_H