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