diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index d2556902..dbee67f5 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -1737,7 +1737,7 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks ) } } } - for( auto& v : counts ) UpdateSampleStatistics( v.first, v.second ); + for( auto& v : counts ) UpdateSampleStatistics( v.first, v.second, false ); } std::lock_guard lock( m_data.lock ); @@ -4743,7 +4743,7 @@ void Worker::ProcessCallstackSample( const QueueCallstackSample& ev ) } #ifndef TRACY_NO_STATISTICS - UpdateSampleStatistics( m_pendingCallstackId, 1 ); + UpdateSampleStatistics( m_pendingCallstackId, 1, true ); #endif } @@ -5246,14 +5246,54 @@ void Worker::ReconstructContextSwitchUsage() m_data.ctxUsageReady = true; } -void Worker::UpdateSampleStatistics( uint32_t callstack, uint32_t count ) +void Worker::UpdateSampleStatistics( uint32_t callstack, uint32_t count, bool canPostpone ) { const auto& cs = GetCallstack( callstack ); const auto cssz = cs.size(); - const auto fexcl = GetCallstackFrame( cs[0] ); - if( fexcl ) + auto frames = (const CallstackFrameData**)alloca( cssz * sizeof( CallstackFrameData* ) ); + for( uint8_t i=0; isecond += count; + } + } + return; + } + else + { + frames[i] = frame; + } + } + + if( canPostpone ) + { + auto it = m_data.postponedSamples.find( callstack ); + if( it != m_data.postponedSamples.end() ) + { + count += it->second; + m_data.postponedSamples.erase( it ); + } + } + + UpdateSampleStatisticsImpl( frames, cssz, count ); +} + +void Worker::UpdateSampleStatisticsImpl( const CallstackFrameData** frames, uint8_t framesCount, uint32_t count ) +{ + { + const auto fexcl = frames[0]; const auto fsz = fexcl->size; const auto& frame0 = fexcl->data[0]; auto sym = m_data.symbolStats.find( frame0.symAddr ); @@ -5267,19 +5307,16 @@ void Worker::UpdateSampleStatistics( uint32_t callstack, uint32_t count ) sym->second.incl += count; } } - for( uint8_t c=1; csize; + for( uint8_t f=0; fsize; - for( uint8_t f=0; fdata[f]; - auto sym = m_data.symbolStats.find( frame.symAddr ); - if( sym == m_data.symbolStats.end() ) sym = m_data.symbolStats.emplace( frame.symAddr, SymbolStats {} ).first; - sym->second.incl += count; - } + const auto& frame = fincl->data[f]; + auto sym = m_data.symbolStats.find( frame.symAddr ); + if( sym == m_data.symbolStats.end() ) sym = m_data.symbolStats.emplace( frame.symAddr, SymbolStats {} ).first; + sym->second.incl += count; } } } diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index 1001b053..2895126f 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -227,6 +227,7 @@ private: unordered_flat_map symbolStats; #ifndef TRACY_NO_STATISTICS + unordered_flat_map postponedSamples; bool callstackSamplesReady = false; #endif @@ -638,7 +639,8 @@ private: #ifndef TRACY_NO_STATISTICS void ReconstructContextSwitchUsage(); - void UpdateSampleStatistics( uint32_t callstack, uint32_t count ); + void UpdateSampleStatistics( uint32_t callstack, uint32_t count, bool canPostpone ); + void UpdateSampleStatisticsImpl( const CallstackFrameData** frames, uint8_t framesCount, uint32_t count ); #endif tracy_force_inline int64_t ReadTimeline( FileRead& f, ZoneEvent* zone, int64_t refTime, int32_t& childIdx );