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