1 #include <pthread.h> 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include <unistd.h> 5 #include <dlfcn.h> 6 #include <stddef.h> 7 #include <sched.h> 8 #include <stdarg.h> 9 10 #ifdef __APPLE__ 11 #include <mach/mach_time.h> 12 #endif 13 14 // TSan-invisible barrier. 15 // Tests use it to establish necessary execution order in a way that does not 16 // interfere with tsan (does not establish synchronization between threads). 17 typedef unsigned long long invisible_barrier_t; 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 void __tsan_testonly_barrier_init(invisible_barrier_t *barrier, 23 unsigned count); 24 void __tsan_testonly_barrier_wait(invisible_barrier_t *barrier); 25 #ifdef __cplusplus 26 } 27 #endif 28 29 static inline void barrier_init(invisible_barrier_t *barrier, unsigned count) { 30 __tsan_testonly_barrier_init(barrier, count); 31 } 32 33 static inline void barrier_wait(invisible_barrier_t *barrier) { 34 __tsan_testonly_barrier_wait(barrier); 35 } 36 37 // Default instance of the barrier, but a test can declare more manually. 38 invisible_barrier_t barrier; 39 40 void print_address(const char *str, int n, ...) { 41 fprintf(stderr, "%s", str); 42 va_list ap; 43 va_start(ap, n); 44 while (n--) { 45 void *p = va_arg(ap, void *); 46 #if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) 47 // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not 48 // match to the format used in the diagnotic message. 49 fprintf(stderr, "0x%012lx ", (unsigned long) p); 50 #elif defined(__mips64) 51 fprintf(stderr, "0x%010lx ", (unsigned long) p); 52 #endif 53 } 54 fprintf(stderr, "\n"); 55 } 56 57 #ifdef __APPLE__ 58 unsigned long long monotonic_clock_ns() { 59 static mach_timebase_info_data_t timebase_info; 60 if (timebase_info.denom == 0) mach_timebase_info(&timebase_info); 61 return (mach_absolute_time() * timebase_info.numer) / timebase_info.denom; 62 } 63 #else 64 unsigned long long monotonic_clock_ns() { 65 struct timespec t; 66 clock_gettime(CLOCK_MONOTONIC, &t); 67 return (unsigned long long)t.tv_sec * 1000000000ull + t.tv_nsec; 68 } 69 #endif 70 71 //The const kPCInc must be in sync with StackTrace::GetPreviousInstructionPc 72 #if defined(__powerpc64__) 73 // PCs are always 4 byte aligned. 74 const int kPCInc = 4; 75 #elif defined(__sparc__) || defined(__mips__) 76 const int kPCInc = 8; 77 #else 78 const int kPCInc = 1; 79 #endif 80 81 #ifdef __cplusplus 82 extern "C" { 83 #endif 84 85 void AnnotateRWLockCreate(const char *f, int l, void *m); 86 void AnnotateRWLockCreateStatic(const char *f, int l, void *m); 87 void AnnotateRWLockDestroy(const char *f, int l, void *m); 88 void AnnotateRWLockAcquired(const char *f, int l, void *m, long is_w); 89 void AnnotateRWLockReleased(const char *f, int l, void *m, long is_w); 90 91 #ifdef __cplusplus 92 } 93 #endif 94 95 #define ANNOTATE_RWLOCK_CREATE(m) \ 96 AnnotateRWLockCreate(__FILE__, __LINE__, m) 97 #define ANNOTATE_RWLOCK_CREATE_STATIC(m) \ 98 AnnotateRWLockCreateStatic(__FILE__, __LINE__, m) 99 #define ANNOTATE_RWLOCK_DESTROY(m) \ 100 AnnotateRWLockDestroy(__FILE__, __LINE__, m) 101 #define ANNOTATE_RWLOCK_ACQUIRED(m, is_w) \ 102 AnnotateRWLockAcquired(__FILE__, __LINE__, m, is_w) 103 #define ANNOTATE_RWLOCK_RELEASED(m, is_w) \ 104 AnnotateRWLockReleased(__FILE__, __LINE__, m, is_w) 105