From e550e15ce6c20f6db8ecd8fe0318f6d24e603508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Gr=C3=A9goire?= Date: Mon, 20 Apr 2026 14:29:35 +0200 Subject: [PATCH 1/4] Turn GetSamplingPeriod into SamplingFrequencyToPeriodNs This forces to (re)use frequency values as input, which may be changed by the platform code later on. This way we have a single "source of truth" for sample freq. Also removed the Win32 `GetSamplingInterval` which was a wrapper above `GetSamplingPeriod` but its value would be divided again anyway. --- public/client/TracySysTrace.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/public/client/TracySysTrace.cpp b/public/client/TracySysTrace.cpp index dcb510a3..8dcf4e13 100644 --- a/public/client/TracySysTrace.cpp +++ b/public/client/TracySysTrace.cpp @@ -34,9 +34,9 @@ static int GetSamplingFrequency() #endif } -static int GetSamplingPeriod() +static int SamplingFrequencyToPeriodNs( int samplingHz ) { - return 1000000000 / GetSamplingFrequency(); + return 1000000000 / samplingHz; } } @@ -174,11 +174,6 @@ void WINAPI EventRecordCallback( PEVENT_RECORD record ) } } -static int GetSamplingInterval() -{ - return GetSamplingPeriod() / 100; -} - static etw::Session session_kernel = {}; static etw::Session session_vsync = {}; static PROCESSTRACE_HANDLE consumer_kernel = INVALID_PROCESSTRACE_HANDLE; @@ -207,10 +202,10 @@ bool SysTraceStart( int64_t& samplingPeriod ) #ifndef TRACY_NO_SAMPLING - int microseconds = GetSamplingInterval() / 10; + samplingPeriod = SamplingFrequencyToPeriodNs( GetSamplingFrequency() ); + const int microseconds = samplingPeriod / 1000; if( etw::EnableCPUProfiling( session_kernel, microseconds ) != ERROR_SUCCESS ) return etw::StopSession( session_kernel ), false; - samplingPeriod = GetSamplingPeriod(); #endif consumer_kernel = etw::SetupEventConsumer( session_kernel, EventRecordCallback ); @@ -659,7 +654,8 @@ bool SysTraceStart( int64_t& samplingPeriod ) const bool noVsync = noVsyncEnv && noVsyncEnv[0] == '1'; #endif - samplingPeriod = GetSamplingPeriod(); + const int samplingFrequency = GetSamplingFrequency(); + samplingPeriod = SamplingFrequencyToPeriodNs( samplingFrequency ); uint32_t currentPid = ___tracy_magic_pid_override != 0 ? ___tracy_magic_pid_override : (uint32_t)getpid(); s_numCpus = (int)std::thread::hardware_concurrency(); @@ -680,7 +676,7 @@ bool SysTraceStart( int64_t& samplingPeriod ) pe.type = PERF_TYPE_SOFTWARE; pe.size = sizeof( perf_event_attr ); pe.config = PERF_COUNT_SW_CPU_CLOCK; - pe.sample_freq = GetSamplingFrequency(); + pe.sample_freq = samplingFrequency; pe.sample_type = PERF_SAMPLE_TID | PERF_SAMPLE_TIME | PERF_SAMPLE_CALLCHAIN; #if LINUX_VERSION_CODE >= KERNEL_VERSION( 4, 8, 0 ) pe.sample_max_stack = 127; From 95b6fdeed3e283a23d70318881adb84a12243d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Gr=C3=A9goire?= Date: Mon, 20 Apr 2026 14:31:41 +0200 Subject: [PATCH 2/4] Fixes #1337: On Linux, respect perf_event_max_sample_rate to avoid lost events This may be especially useful for low performance machines. We also warn about this behaviour through TracyDebug which ends up in Messages. --- public/client/TracySysTrace.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/public/client/TracySysTrace.cpp b/public/client/TracySysTrace.cpp index 8dcf4e13..df25f723 100644 --- a/public/client/TracySysTrace.cpp +++ b/public/client/TracySysTrace.cpp @@ -654,7 +654,21 @@ bool SysTraceStart( int64_t& samplingPeriod ) const bool noVsync = noVsyncEnv && noVsyncEnv[0] == '1'; #endif - const int samplingFrequency = GetSamplingFrequency(); + int samplingFrequency = GetSamplingFrequency(); + if( samplingFrequency > 0 ) + { + FILE* f = fopen( "/proc/sys/kernel/perf_event_max_sample_rate", "r" ); + if( f ) + { + int sysMax; + if( fscanf( f, "%d", &sysMax ) == 1 && samplingFrequency > sysMax ) + { + TracyDebug( "Requested sampling frequency %d Hz is higher than system maximum of %d Hz, reducing to system maximum.", samplingFrequency, sysMax ); + samplingFrequency = sysMax; + } + fclose( f ); + } + } samplingPeriod = SamplingFrequencyToPeriodNs( samplingFrequency ); uint32_t currentPid = ___tracy_magic_pid_override != 0 ? ___tracy_magic_pid_override : (uint32_t)getpid(); From 8f208d732a9217c0e43b733d5d41190ec28c46c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Gr=C3=A9goire?= Date: Mon, 20 Apr 2026 18:04:41 +0200 Subject: [PATCH 3/4] Fix extra space --- public/client/TracySysTrace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/client/TracySysTrace.cpp b/public/client/TracySysTrace.cpp index df25f723..c9dd2a38 100644 --- a/public/client/TracySysTrace.cpp +++ b/public/client/TracySysTrace.cpp @@ -34,7 +34,7 @@ static int GetSamplingFrequency() #endif } -static int SamplingFrequencyToPeriodNs( int samplingHz ) +static int SamplingFrequencyToPeriodNs( int samplingHz ) { return 1000000000 / samplingHz; } From cb9ef7814ecbe51c70912e4ca6672804306e171d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Gr=C3=A9goire?= Date: Mon, 20 Apr 2026 18:05:31 +0200 Subject: [PATCH 4/4] Use ReadFile and atoi --- public/client/TracySysTrace.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/public/client/TracySysTrace.cpp b/public/client/TracySysTrace.cpp index c9dd2a38..4ae641aa 100644 --- a/public/client/TracySysTrace.cpp +++ b/public/client/TracySysTrace.cpp @@ -657,16 +657,15 @@ bool SysTraceStart( int64_t& samplingPeriod ) int samplingFrequency = GetSamplingFrequency(); if( samplingFrequency > 0 ) { - FILE* f = fopen( "/proc/sys/kernel/perf_event_max_sample_rate", "r" ); - if( f ) + const auto maxSampleRateStr = ReadFile( "/proc/sys/kernel/perf_event_max_sample_rate" ); + if( maxSampleRateStr ) { - int sysMax; - if( fscanf( f, "%d", &sysMax ) == 1 && samplingFrequency > sysMax ) + const int sysMax = atoi( maxSampleRateStr ); + if( sysMax > 0 && sysMax < samplingFrequency ) { TracyDebug( "Requested sampling frequency %d Hz is higher than system maximum of %d Hz, reducing to system maximum.", samplingFrequency, sysMax ); samplingFrequency = sysMax; } - fclose( f ); } } samplingPeriod = SamplingFrequencyToPeriodNs( samplingFrequency );