| 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 | |