diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index aa4f420b..acb4e14c 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -3037,8 +3037,12 @@ void Worker::Exec() HandlePostponedPlots(); #ifndef TRACY_NO_STATISTICS - HandlePostponedSamples(); - m_data.newFramesWereReceived = false; + if( m_data.newFramesWereReceived ) + { + HandlePostponedSamples(); + HandlePostponedGhostZones(); + m_data.newFramesWereReceived = false; + } #endif if( m_data.newSymbolsWereAdded ) { @@ -4085,7 +4089,7 @@ void Worker::HandlePostponedPlots() #ifndef TRACY_NO_STATISTICS void Worker::HandlePostponedSamples() { - if( !m_data.newFramesWereReceived ) return; + assert( m_data.newFramesWereReceived ); if( m_data.postponedSamples.empty() ) return; auto it = m_data.postponedSamples.begin(); do @@ -4094,6 +4098,119 @@ void Worker::HandlePostponedSamples() } while( it != m_data.postponedSamples.end() ); } + +void Worker::HandlePostponedGhostZones() +{ + assert( m_data.newFramesWereReceived ); + if( !m_data.ghostZonesPostponed ) return; + bool postponed = false; + for( auto& td : m_data.threads ) + { + while( td->ghostIdx != td->samples.size() ) + { + const auto& sample = td->samples[td->ghostIdx]; + const auto& cs = GetCallstack( sample.callstack.Val() ); + const auto cssz = cs.size(); + + uint16_t i; + for( i=0; ighostIdx++; + int gcnt = 0; + int idx = cs.size() - 1; + auto vec = &td->ghostZones; + do + { + auto& entry = cs[idx]; + uint32_t fid; + auto it = m_data.ghostFramesMap.find( entry.data ); + if( it == m_data.ghostFramesMap.end() ) + { + fid = uint32_t( m_data.ghostFrames.size() ); + m_data.ghostFrames.push_back( entry ); + m_data.ghostFramesMap.emplace( entry.data, fid ); + } + else + { + fid = it->second; + } + if( vec->empty() ) + { + gcnt++; + auto& zone = vec->push_next(); + zone.start.SetVal( t ); + zone.end.SetVal( t + m_samplingPeriod ); + zone.frame.SetVal( fid ); + zone.child = -1; + } + else + { + auto& back = vec->back(); + const auto backFrame = GetCallstackFrame( m_data.ghostFrames[back.frame.Val()] ); + const auto thisFrame = GetCallstackFrame( entry ); + bool match = false; + if( backFrame && thisFrame ) + { + match = backFrame->size == thisFrame->size; + if( match ) + { + for( uint8_t i=0; isize; i++ ) + { + if( backFrame->data[i].symAddr != thisFrame->data[i].symAddr ) + { + match = false; + break; + } + } + } + } + if( match ) + { + back.end.SetVal( t + m_samplingPeriod ); + } + else + { + gcnt++; + auto ptr = &back; + for(;;) + { + ptr->end.SetVal( t ); + if( ptr->child < 0 ) break; + ptr = &GetGhostChildrenMutable( ptr->child ).back(); + } + auto& zone = vec->push_next_non_empty(); + zone.start.SetVal( t ); + zone.end.SetVal( t + m_samplingPeriod ); + zone.frame.SetVal( fid ); + zone.child = -1; + } + } + if( idx > 0 ) + { + auto& zone = vec->back(); + if( zone.child < 0 ) + { + zone.child = m_data.ghostChildren.size(); + vec = &m_data.ghostChildren.push_next(); + } + else + { + vec = &m_data.ghostChildren[zone.child]; + } + } + } + while( idx-- > 0 ); + m_data.ghostCnt += gcnt; + } + } + m_data.ghostZonesPostponed = postponed; +} #endif StringLocation Worker::StoreString( const char* str, size_t sz ) diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index 64bf03e2..954fa605 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -712,6 +712,7 @@ private: void HandlePostponedPlots(); void HandlePostponedSamples(); + void HandlePostponedGhostZones(); bool IsThreadStringRetrieved( uint64_t id ); bool IsSourceLocationRetrieved( int16_t srcloc );