Home | History | Annotate | Download | only in tsan
      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