Index: compiler-rt/trunk/lib/xray/xray_inmemory_log.cc =================================================================== --- compiler-rt/trunk/lib/xray/xray_inmemory_log.cc +++ compiler-rt/trunk/lib/xray/xray_inmemory_log.cc @@ -77,7 +77,6 @@ static int __xray_OpenLogFile() XRAY_NEVER_INSTRUMENT { int F = getLogFD(); - auto TSCFrequency = getTSCFrequency(); if (F == -1) return -1; // Since we're here, we get to write the header. We set it up so that the @@ -86,7 +85,9 @@ XRayFileHeader Header; Header.Version = 1; Header.Type = FileTypes::NAIVE_LOG; - Header.CycleFrequency = TSCFrequency; + Header.CycleFrequency = probeRequiredCPUFeatures() + ? getTSCFrequency() + : __xray::NanosecondsPerSecond; // FIXME: Actually check whether we have 'constant_tsc' and 'nonstop_tsc' // before setting the values in the header. @@ -97,8 +98,9 @@ return F; } -void __xray_InMemoryRawLog(int32_t FuncId, - XRayEntryType Type) XRAY_NEVER_INSTRUMENT { +template +void __xray_InMemoryRawLog(int32_t FuncId, XRayEntryType Type, + RDTSC ReadTSC) XRAY_NEVER_INSTRUMENT { using Buffer = std::aligned_storage::type; static constexpr size_t BuffLen = 1024; @@ -115,7 +117,7 @@ // through a pointer offset. auto &R = reinterpret_cast<__xray::XRayRecord *>(InMemoryBuffer)[Offset]; R.RecordType = RecordTypes::NORMAL; - R.TSC = __xray::readTSC(R.CPU); + R.TSC = ReadTSC(R.CPU); R.TId = TId; R.Type = Type; R.FuncId = FuncId; @@ -129,13 +131,32 @@ } } +void __xray_InMemoryRawLogRealTSC(int32_t FuncId, + XRayEntryType Type) XRAY_NEVER_INSTRUMENT { + __xray_InMemoryRawLog(FuncId, Type, __xray::readTSC); +} + +void __xray_InMemoryEmulateTSC(int32_t FuncId, + XRayEntryType Type) XRAY_NEVER_INSTRUMENT { + __xray_InMemoryRawLog(FuncId, Type, [](uint8_t &CPU) XRAY_NEVER_INSTRUMENT { + timespec TS; + int result = clock_gettime(CLOCK_REALTIME, &TS); + if (result != 0) { + Report("clock_gettimg(2) return %d, errno=%d.", result, int(errno)); + TS = {0, 0}; + } + CPU = 0; + return TS.tv_sec * __xray::NanosecondsPerSecond + TS.tv_nsec; + }); +} + static auto UNUSED Unused = [] { - if (!probeRequiredCPUFeatures()) { - Report("Required CPU features missing for XRay instrumentation, not " - "installing instrumentation hooks.\n"); - return false; - } + auto UseRealTSC = probeRequiredCPUFeatures(); + if (!UseRealTSC) + Report("WARNING: Required CPU features missing for XRay instrumentation, " + "using emulation instead.\n"); if (flags()->xray_naive_log) - __xray_set_handler(__xray_InMemoryRawLog); + __xray_set_handler(UseRealTSC ? __xray_InMemoryRawLogRealTSC + : __xray_InMemoryEmulateTSC); return true; }(); Index: compiler-rt/trunk/lib/xray/xray_tsc.h =================================================================== --- compiler-rt/trunk/lib/xray/xray_tsc.h +++ compiler-rt/trunk/lib/xray/xray_tsc.h @@ -13,6 +13,10 @@ #ifndef XRAY_EMULATE_TSC_H #define XRAY_EMULATE_TSC_H +namespace __xray { +static constexpr uint64_t NanosecondsPerSecond = 1000ULL * 1000 * 1000; +} + #if defined(__x86_64__) #include "xray_x86_64.inc" #elif defined(__powerpc64__) @@ -37,8 +41,6 @@ namespace __xray { -static constexpr uint64_t NanosecondsPerSecond = 1000ULL * 1000 * 1000; - inline bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; } ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT { @@ -60,7 +62,7 @@ } // namespace __xray #else -"Unsupported CPU Architecture" +#error Target architecture is not supported. #endif // CPU architecture #endif // XRAY_EMULATE_TSC_H