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