Dmitry Vyukov | 3ab6b23 | 2015-01-21 13:50:02 +0000 | [diff] [blame] | 1 | #include <pthread.h> |
| 2 | #include <stdlib.h> |
| 3 | #include <stdio.h> |
| 4 | #include <unistd.h> |
| 5 | #include <dlfcn.h> |
| 6 | #include <stddef.h> |
Dmitry Vyukov | 1041aab | 2015-11-12 10:24:22 +0000 | [diff] [blame] | 7 | #include <sched.h> |
Adhemerval Zanella | 7a09659 | 2015-11-30 19:43:03 +0000 | [diff] [blame] | 8 | #include <stdarg.h> |
Strahinja Petrovic | f10d114 | 2016-11-14 11:40:56 +0000 | [diff] [blame] | 9 | #include "sanitizer_common/print_address.h" |
Dmitry Vyukov | 3ab6b23 | 2015-01-21 13:50:02 +0000 | [diff] [blame] | 10 | |
Kuba Mracek | dd13e4e | 2017-04-24 16:48:30 +0000 | [diff] [blame] | 11 | #include <sanitizer/tsan_interface.h> |
| 12 | |
Kuba Brecka | 8aa56d3 | 2015-11-20 11:07:16 +0000 | [diff] [blame] | 13 | #ifdef __APPLE__ |
| 14 | #include <mach/mach_time.h> |
| 15 | #endif |
| 16 | |
Dmitry Vyukov | 3ab6b23 | 2015-01-21 13:50:02 +0000 | [diff] [blame] | 17 | // TSan-invisible barrier. |
| 18 | // Tests use it to establish necessary execution order in a way that does not |
| 19 | // interfere with tsan (does not establish synchronization between threads). |
Dmitry Vyukov | 4cd631c | 2015-11-06 11:52:24 +0000 | [diff] [blame] | 20 | typedef unsigned long long invisible_barrier_t; |
Dmitry Vyukov | 3ab6b23 | 2015-01-21 13:50:02 +0000 | [diff] [blame] | 21 | |
Dmitry Vyukov | eee690b | 2015-12-08 17:54:47 +0000 | [diff] [blame] | 22 | #ifdef __cplusplus |
| 23 | extern "C" { |
| 24 | #endif |
| 25 | void __tsan_testonly_barrier_init(invisible_barrier_t *barrier, |
| 26 | unsigned count); |
| 27 | void __tsan_testonly_barrier_wait(invisible_barrier_t *barrier); |
Kuba Brecka | b0dd454 | 2016-11-14 21:41:33 +0000 | [diff] [blame] | 28 | unsigned long __tsan_testonly_shadow_stack_current_size(); |
Dmitry Vyukov | eee690b | 2015-12-08 17:54:47 +0000 | [diff] [blame] | 29 | #ifdef __cplusplus |
| 30 | } |
| 31 | #endif |
| 32 | |
| 33 | static inline void barrier_init(invisible_barrier_t *barrier, unsigned count) { |
| 34 | __tsan_testonly_barrier_init(barrier, count); |
Dmitry Vyukov | 4cd631c | 2015-11-06 11:52:24 +0000 | [diff] [blame] | 35 | } |
Viktor Kutuzov | 281347a | 2015-03-13 14:08:55 +0000 | [diff] [blame] | 36 | |
Dmitry Vyukov | eee690b | 2015-12-08 17:54:47 +0000 | [diff] [blame] | 37 | static inline void barrier_wait(invisible_barrier_t *barrier) { |
| 38 | __tsan_testonly_barrier_wait(barrier); |
Dmitry Vyukov | 3ab6b23 | 2015-01-21 13:50:02 +0000 | [diff] [blame] | 39 | } |
| 40 | |
| 41 | // Default instance of the barrier, but a test can declare more manually. |
Dmitry Vyukov | 4cd631c | 2015-11-06 11:52:24 +0000 | [diff] [blame] | 42 | invisible_barrier_t barrier; |
Dmitry Vyukov | 3ab6b23 | 2015-01-21 13:50:02 +0000 | [diff] [blame] | 43 | |
Kuba Brecka | 8aa56d3 | 2015-11-20 11:07:16 +0000 | [diff] [blame] | 44 | #ifdef __APPLE__ |
| 45 | unsigned long long monotonic_clock_ns() { |
| 46 | static mach_timebase_info_data_t timebase_info; |
| 47 | if (timebase_info.denom == 0) mach_timebase_info(&timebase_info); |
| 48 | return (mach_absolute_time() * timebase_info.numer) / timebase_info.denom; |
| 49 | } |
| 50 | #else |
| 51 | unsigned long long monotonic_clock_ns() { |
| 52 | struct timespec t; |
| 53 | clock_gettime(CLOCK_MONOTONIC, &t); |
| 54 | return (unsigned long long)t.tv_sec * 1000000000ull + t.tv_nsec; |
| 55 | } |
| 56 | #endif |
Sagar Thakur | 8f3381e | 2016-03-02 13:53:22 +0000 | [diff] [blame] | 57 | |
| 58 | //The const kPCInc must be in sync with StackTrace::GetPreviousInstructionPc |
Igor Kudrin | 13f8a77 | 2018-05-24 12:26:20 +0000 | [diff] [blame] | 59 | #if defined(__powerpc64__) || defined(__arm__) || defined(__aarch64__) |
Sagar Thakur | 8f3381e | 2016-03-02 13:53:22 +0000 | [diff] [blame] | 60 | // PCs are always 4 byte aligned. |
| 61 | const int kPCInc = 4; |
| 62 | #elif defined(__sparc__) || defined(__mips__) |
| 63 | const int kPCInc = 8; |
| 64 | #else |
| 65 | const int kPCInc = 1; |
| 66 | #endif |
Dmitry Vyukov | 0f7e949 | 2016-06-03 11:48:27 +0000 | [diff] [blame] | 67 | |
| 68 | #ifdef __cplusplus |
| 69 | extern "C" { |
| 70 | #endif |
| 71 | |
| 72 | void AnnotateRWLockCreate(const char *f, int l, void *m); |
| 73 | void AnnotateRWLockCreateStatic(const char *f, int l, void *m); |
| 74 | void AnnotateRWLockDestroy(const char *f, int l, void *m); |
| 75 | void AnnotateRWLockAcquired(const char *f, int l, void *m, long is_w); |
| 76 | void AnnotateRWLockReleased(const char *f, int l, void *m, long is_w); |
| 77 | |
| 78 | #ifdef __cplusplus |
| 79 | } |
| 80 | #endif |
| 81 | |
| 82 | #define ANNOTATE_RWLOCK_CREATE(m) \ |
| 83 | AnnotateRWLockCreate(__FILE__, __LINE__, m) |
| 84 | #define ANNOTATE_RWLOCK_CREATE_STATIC(m) \ |
| 85 | AnnotateRWLockCreateStatic(__FILE__, __LINE__, m) |
| 86 | #define ANNOTATE_RWLOCK_DESTROY(m) \ |
| 87 | AnnotateRWLockDestroy(__FILE__, __LINE__, m) |
| 88 | #define ANNOTATE_RWLOCK_ACQUIRED(m, is_w) \ |
| 89 | AnnotateRWLockAcquired(__FILE__, __LINE__, m, is_w) |
| 90 | #define ANNOTATE_RWLOCK_RELEASED(m, is_w) \ |
| 91 | AnnotateRWLockReleased(__FILE__, __LINE__, m, is_w) |