From b69aaf04e9a3e40124d1063271deba396eb775b6 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Tue, 7 Apr 2020 22:01:31 +0200 Subject: [PATCH] Add support for QPC timer. --- client/TracyProfiler.cpp | 13 ++++++++++++- client/TracyProfiler.hpp | 8 ++++++++ client/TracySysTrace.cpp | 4 ++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/client/TracyProfiler.cpp b/client/TracyProfiler.cpp index efe09a81..bf5d8a31 100644 --- a/client/TracyProfiler.cpp +++ b/client/TracyProfiler.cpp @@ -220,6 +220,7 @@ static void InitFailure( const char* msg ) static int64_t SetupHwTimer() { +#ifndef TRACY_TIMER_QPC uint32_t regs[4]; CpuId( regs, 0x80000001 ); if( !( regs[3] & ( 1 << 27 ) ) ) InitFailure( "CPU doesn't support RDTSCP instruction." ); @@ -229,9 +230,10 @@ static int64_t SetupHwTimer() const char* noCheck = getenv( "TRACY_NO_INVARIANT_CHECK" ); if( !noCheck || noCheck[0] != '1' ) { - InitFailure( "CPU doesn't support invariant TSC.\nDefine TRACY_NO_INVARIANT_CHECK=1 to ignore this error, *if you know what you are doing*." ); + InitFailure( "CPU doesn't support invariant TSC.\nDefine TRACY_NO_INVARIANT_CHECK=1 to ignore this error, *if you know what you are doing*.\nAlternatively you may rebuild the application with the TRACY_TIMER_QPC define to use lower resolution timer." ); } } +#endif return Profiler::GetTime(); } @@ -2786,6 +2788,15 @@ void Profiler::SendCodeLocation( uint64_t ptr ) #endif } +#if ( defined _WIN32 || defined __CYGWIN__ ) && defined TRACY_TIMER_QPC +int64_t Profiler::GetTimeQpc() +{ + LARGE_INTEGER t; + QueryPerformanceCounter( &t ); + return t.QuadPart; +} +#endif + } #ifdef __cplusplus diff --git a/client/TracyProfiler.hpp b/client/TracyProfiler.hpp index 55e19c46..f5deb9eb 100644 --- a/client/TracyProfiler.hpp +++ b/client/TracyProfiler.hpp @@ -131,7 +131,11 @@ public: return std::chrono::duration_cast( std::chrono::high_resolution_clock::now().time_since_epoch() ).count(); # endif # elif defined _WIN32 || defined __CYGWIN__ +# ifdef TRACY_TIMER_QPC + return GetTimeQpc(); +# else return int64_t( __rdtsc() ); +# endif # elif defined __i386 || defined _M_IX86 uint32_t eax, edx; asm volatile ( "rdtsc" : "=a" (eax), "=d" (edx) ); @@ -609,6 +613,10 @@ private: GetProfiler().m_serialQueue.commit_next(); } +#if ( defined _WIN32 || defined __CYGWIN__ ) && defined TRACY_TIMER_QPC + static int64_t GetTimeQpc(); +#endif + double m_timerMul; uint64_t m_resolution; uint64_t m_delay; diff --git a/client/TracySysTrace.cpp b/client/TracySysTrace.cpp index fd7dd870..4241f3ea 100644 --- a/client/TracySysTrace.cpp +++ b/client/TracySysTrace.cpp @@ -226,7 +226,11 @@ bool SysTraceStart( int64_t& samplingPeriod ) s_prop->LogFileMode = EVENT_TRACE_REAL_TIME_MODE; s_prop->Wnode.BufferSize = psz; s_prop->Wnode.Flags = WNODE_FLAG_TRACED_GUID; +#ifdef TRACY_TIMER_QPC + s_prop->Wnode.ClientContext = 1; +#else s_prop->Wnode.ClientContext = 3; +#endif s_prop->Wnode.Guid = SystemTraceControlGuid; s_prop->BufferSize = 1024; s_prop->LoggerNameOffset = sizeof( EVENT_TRACE_PROPERTIES );