[XRay][compiler-rt] Support TSC emulation even for x86_64
Summary: Use TSC emulation in cases where RDTSCP isn't available on the host running an XRay instrumented binary. We can then fall back into emulation instead of not even installing XRay's runtime functionality. We only do this for now in the naive/basic logging implementation, but should be useful in even FDR mode. Should fix http://llvm.org/PR32148. Reviewers: pelikan, rnk, sdardis Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D30677 llvm-svn: 297800
This commit is contained in:
parent
842c707d7c
commit
66443d80f1
|
@ -77,7 +77,6 @@ using namespace __xray;
|
|||
|
||||
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 @@ static int __xray_OpenLogFile() XRAY_NEVER_INSTRUMENT {
|
|||
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 @@ static int __xray_OpenLogFile() XRAY_NEVER_INSTRUMENT {
|
|||
return F;
|
||||
}
|
||||
|
||||
void __xray_InMemoryRawLog(int32_t FuncId,
|
||||
XRayEntryType Type) XRAY_NEVER_INSTRUMENT {
|
||||
template <class RDTSC>
|
||||
void __xray_InMemoryRawLog(int32_t FuncId, XRayEntryType Type,
|
||||
RDTSC ReadTSC) XRAY_NEVER_INSTRUMENT {
|
||||
using Buffer =
|
||||
std::aligned_storage<sizeof(XRayRecord), alignof(XRayRecord)>::type;
|
||||
static constexpr size_t BuffLen = 1024;
|
||||
|
@ -115,7 +117,7 @@ void __xray_InMemoryRawLog(int32_t FuncId,
|
|||
// 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_InMemoryRawLog(int32_t FuncId,
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}();
|
||||
|
|
|
@ -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 @@ inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT {
|
|||
} // namespace __xray
|
||||
|
||||
#else
|
||||
"Unsupported CPU Architecture"
|
||||
#error Target architecture is not supported.
|
||||
#endif // CPU architecture
|
||||
|
||||
#endif // XRAY_EMULATE_TSC_H
|
||||
|
|
Loading…
Reference in New Issue