1 | #ifndef __TSAN_TEST_H__ |
2 | #define __TSAN_TEST_H__ |
3 | |
4 | #include <pthread.h> |
5 | #include <stdlib.h> |
6 | #include <stdio.h> |
7 | #include <unistd.h> |
8 | #include <dlfcn.h> |
9 | #include <stddef.h> |
10 | #include <sched.h> |
11 | #include <stdarg.h> |
12 | #include "sanitizer_common/print_address.h" |
13 | |
14 | #include <sanitizer/tsan_interface.h> |
15 | |
16 | #ifdef __APPLE__ |
17 | #include <mach/mach_time.h> |
18 | #endif |
19 | |
20 | #ifndef TSAN_VECTORIZE |
21 | # define TSAN_VECTORIZE __SSE4_2__ |
22 | #endif |
23 | |
24 | #if TSAN_VECTORIZE |
25 | # include <emmintrin.h> |
26 | # include <smmintrin.h> |
27 | #else |
28 | struct __m128i { |
29 | unsigned long long x[2]; |
30 | }; |
31 | #endif |
32 | |
33 | // TSan-invisible barrier. |
34 | // Tests use it to establish necessary execution order in a way that does not |
35 | // interfere with tsan (does not establish synchronization between threads). |
36 | typedef unsigned invisible_barrier_t; |
37 | |
38 | #ifdef __cplusplus |
39 | extern "C" { |
40 | #endif |
41 | void __tsan_testonly_barrier_init(invisible_barrier_t *barrier, |
42 | unsigned count); |
43 | void __tsan_testonly_barrier_wait(invisible_barrier_t *barrier); |
44 | unsigned long __tsan_testonly_shadow_stack_current_size(); |
45 | #ifdef __cplusplus |
46 | } |
47 | #endif |
48 | |
49 | static inline void barrier_init(invisible_barrier_t *barrier, unsigned count) { |
50 | __tsan_testonly_barrier_init(barrier, count); |
51 | } |
52 | |
53 | static inline void barrier_wait(invisible_barrier_t *barrier) { |
54 | __tsan_testonly_barrier_wait(barrier); |
55 | } |
56 | |
57 | // Default instance of the barrier, but a test can declare more manually. |
58 | invisible_barrier_t barrier; |
59 | |
60 | #ifdef __APPLE__ |
61 | unsigned long long monotonic_clock_ns() { |
62 | static mach_timebase_info_data_t timebase_info; |
63 | if (timebase_info.denom == 0) mach_timebase_info(&timebase_info); |
64 | return (mach_absolute_time() * timebase_info.numer) / timebase_info.denom; |
65 | } |
66 | #else |
67 | unsigned long long monotonic_clock_ns() { |
68 | struct timespec t; |
69 | clock_gettime(CLOCK_MONOTONIC, tp: &t); |
70 | return (unsigned long long)t.tv_sec * 1000000000ull + t.tv_nsec; |
71 | } |
72 | #endif |
73 | |
74 | //The const kPCInc must be in sync with StackTrace::GetPreviousInstructionPc |
75 | #if defined(__s390__) || defined(__i386__) || defined(__x86_64__) |
76 | const int kPCInc = 1; |
77 | #elif defined(__sparc__) || defined(__mips__) |
78 | const int kPCInc = 8; |
79 | #elif defined(__riscv) && __riscv_xlen == 64 |
80 | const int kPCInc = 2; |
81 | #else |
82 | const int kPCInc = 4; |
83 | #endif |
84 | |
85 | #ifdef __cplusplus |
86 | extern "C" { |
87 | #endif |
88 | |
89 | void AnnotateThreadName(const char *f, int l, const char *name); |
90 | |
91 | void AnnotateRWLockCreate(const char *f, int l, void *m); |
92 | void AnnotateRWLockCreateStatic(const char *f, int l, void *m); |
93 | void AnnotateRWLockDestroy(const char *f, int l, void *m); |
94 | void AnnotateRWLockAcquired(const char *f, int l, void *m, long is_w); |
95 | void AnnotateRWLockReleased(const char *f, int l, void *m, long is_w); |
96 | |
97 | void AnnotateIgnoreReadsBegin(const char *f, int l); |
98 | void AnnotateIgnoreReadsEnd(const char *f, int l); |
99 | void AnnotateIgnoreWritesBegin(const char *f, int l); |
100 | void AnnotateIgnoreWritesEnd(const char *f, int l); |
101 | |
102 | void AnnotateIgnoreSyncBegin(const char *f, int l); |
103 | void AnnotateIgnoreSyncEnd(const char *f, int l); |
104 | |
105 | void AnnotateHappensBefore(const char *f, int l, void *addr); |
106 | void AnnotateHappensAfter(const char *f, int l, void *addr); |
107 | |
108 | void AnnotateBenignRaceSized(const char *f, int l, const volatile void *mem, |
109 | unsigned int size, const char *desc); |
110 | void WTFAnnotateBenignRaceSized(const char *f, int l, const volatile void *mem, |
111 | unsigned int size, const char *desc); |
112 | |
113 | #ifdef __cplusplus |
114 | } |
115 | #endif |
116 | |
117 | #define ANNOTATE_RWLOCK_CREATE(m) \ |
118 | AnnotateRWLockCreate(__FILE__, __LINE__, m) |
119 | #define ANNOTATE_RWLOCK_CREATE_STATIC(m) \ |
120 | AnnotateRWLockCreateStatic(__FILE__, __LINE__, m) |
121 | #define ANNOTATE_RWLOCK_DESTROY(m) \ |
122 | AnnotateRWLockDestroy(__FILE__, __LINE__, m) |
123 | #define ANNOTATE_RWLOCK_ACQUIRED(m, is_w) \ |
124 | AnnotateRWLockAcquired(__FILE__, __LINE__, m, is_w) |
125 | #define ANNOTATE_RWLOCK_RELEASED(m, is_w) \ |
126 | AnnotateRWLockReleased(__FILE__, __LINE__, m, is_w) |
127 | #define ANNOTATE_HAPPENS_BEFORE(addr) \ |
128 | AnnotateHappensBefore(__FILE__, __LINE__, (void *)(addr)) |
129 | #define ANNOTATE_HAPPENS_AFTER(addr) \ |
130 | AnnotateHappensAfter(__FILE__, __LINE__, (void *)(addr)) |
131 | #define ANNOTATE_BENIGN_RACE(var) \ |
132 | AnnotateBenignRaceSized(__FILE__, __LINE__, &(var), sizeof(var), #var) |
133 | #define WTF_ANNOTATE_BENIGN_RACE(var) \ |
134 | WTFAnnotateBenignRaceSized(__FILE__, __LINE__, &(var), sizeof(var), #var) |
135 | |
136 | #ifdef __APPLE__ |
137 | #define ASM_SYMBOL(symbol) "_" #symbol |
138 | #else |
139 | #define ASM_SYMBOL(symbol) #symbol |
140 | #endif |
141 | |
142 | #endif // __TSAN_TEST_H__ |
143 | |