Home | History | Annotate | Line # | Download | only in xray
      1  1.1  kamil //===-- xray_tsc.h ----------------------------------------------*- C++ -*-===//
      2  1.1  kamil //
      3  1.1  kamil //                     The LLVM Compiler Infrastructure
      4  1.1  kamil //
      5  1.1  kamil // This file is distributed under the University of Illinois Open Source
      6  1.1  kamil // License. See LICENSE.TXT for details.
      7  1.1  kamil //
      8  1.1  kamil //===----------------------------------------------------------------------===//
      9  1.1  kamil //
     10  1.1  kamil // This file is a part of XRay, a dynamic runtime instrumentation system.
     11  1.1  kamil //
     12  1.1  kamil //===----------------------------------------------------------------------===//
     13  1.1  kamil #ifndef XRAY_EMULATE_TSC_H
     14  1.1  kamil #define XRAY_EMULATE_TSC_H
     15  1.1  kamil 
     16  1.1  kamil #include "sanitizer_common/sanitizer_common.h"
     17  1.1  kamil 
     18  1.1  kamil namespace __xray {
     19  1.1  kamil static constexpr uint64_t NanosecondsPerSecond = 1000ULL * 1000 * 1000;
     20  1.1  kamil }
     21  1.1  kamil 
     22  1.1  kamil #if SANITIZER_FUCHSIA
     23  1.1  kamil #include <zircon/syscalls.h>
     24  1.1  kamil 
     25  1.1  kamil namespace __xray {
     26  1.1  kamil 
     27  1.1  kamil inline bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; }
     28  1.1  kamil 
     29  1.1  kamil ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
     30  1.1  kamil   CPU = 0;
     31  1.1  kamil   return _zx_ticks_get();
     32  1.1  kamil }
     33  1.1  kamil 
     34  1.1  kamil inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT {
     35  1.1  kamil   return _zx_ticks_per_second();
     36  1.1  kamil }
     37  1.1  kamil 
     38  1.1  kamil } // namespace __xray
     39  1.1  kamil 
     40  1.1  kamil #else // SANITIZER_FUCHSIA
     41  1.1  kamil 
     42  1.1  kamil #if defined(__x86_64__)
     43  1.1  kamil #include "xray_x86_64.inc"
     44  1.1  kamil #elif defined(__powerpc64__)
     45  1.1  kamil #include "xray_powerpc64.inc"
     46  1.1  kamil #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__)
     47  1.1  kamil // Emulated TSC.
     48  1.1  kamil // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does
     49  1.1  kamil //   not have a constant frequency like TSC on x86(_64), it may go faster
     50  1.1  kamil //   or slower depending on CPU turbo or power saving mode. Furthermore,
     51  1.1  kamil //   to read from CP15 on ARM a kernel modification or a driver is needed.
     52  1.1  kamil //   We can not require this from users of compiler-rt.
     53  1.1  kamil // So on ARM we use clock_gettime() which gives the result in nanoseconds.
     54  1.1  kamil //   To get the measurements per second, we scale this by the number of
     55  1.1  kamil //   nanoseconds per second, pretending that the TSC frequency is 1GHz and
     56  1.1  kamil //   one TSC tick is 1 nanosecond.
     57  1.1  kamil #include "sanitizer_common/sanitizer_common.h"
     58  1.1  kamil #include "sanitizer_common/sanitizer_internal_defs.h"
     59  1.1  kamil #include "xray_defs.h"
     60  1.1  kamil #include <cerrno>
     61  1.1  kamil #include <cstdint>
     62  1.1  kamil #include <time.h>
     63  1.1  kamil 
     64  1.1  kamil namespace __xray {
     65  1.1  kamil 
     66  1.1  kamil inline bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; }
     67  1.1  kamil 
     68  1.1  kamil ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
     69  1.1  kamil   timespec TS;
     70  1.1  kamil   int result = clock_gettime(CLOCK_REALTIME, &TS);
     71  1.1  kamil   if (result != 0) {
     72  1.1  kamil     Report("clock_gettime(2) returned %d, errno=%d.", result, int(errno));
     73  1.1  kamil     TS.tv_sec = 0;
     74  1.1  kamil     TS.tv_nsec = 0;
     75  1.1  kamil   }
     76  1.1  kamil   CPU = 0;
     77  1.1  kamil   return TS.tv_sec * NanosecondsPerSecond + TS.tv_nsec;
     78  1.1  kamil }
     79  1.1  kamil 
     80  1.1  kamil inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT {
     81  1.1  kamil   return NanosecondsPerSecond;
     82  1.1  kamil }
     83  1.1  kamil 
     84  1.1  kamil } // namespace __xray
     85  1.1  kamil 
     86  1.1  kamil #else
     87  1.1  kamil #error Target architecture is not supported.
     88  1.1  kamil #endif // CPU architecture
     89  1.1  kamil #endif // SANITIZER_FUCHSIA
     90  1.1  kamil 
     91  1.1  kamil #endif // XRAY_EMULATE_TSC_H
     92