diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index 049d4fad..02c52f6f 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -4868,6 +4868,94 @@ void Worker::ReconstructMemAllocPlot() #ifndef TRACY_NO_STATISTICS void Worker::ReconstructContextSwitchUsage() { + assert( m_data.cpuDataCount != 0 ); + const auto cpucnt = m_data.cpuDataCount; + + auto& vec = m_data.ctxUsage; + vec.push_back( ContextSwitchUsage( 0, 0, 0 ) ); + + struct Cpu + { + bool startDone; + Vector::iterator it; + Vector::iterator end; + }; + std::vector cpus; + cpus.reserve( cpucnt ); + for( int i=0; i::max(); + bool atEnd = true; + for( int i=0; iStart() : cpus[i].it->End(); + if( ct < nextTime ) nextTime = ct; + } + } + if( atEnd ) break; + for( int i=0; iStart() : cpus[i].it->End(); + if( nextTime != ct ) break; + const auto isOwn = GetPidFromTid( DecompressThreadExternal( cpus[i].it->Thread() ) ) == m_pid; + if( !cpus[i].startDone ) + { + if( isOwn ) + { + own++; + assert( own <= cpucnt ); + } + else + { + other++; + assert( other <= cpucnt ); + } + if( cpus[i].it->End() < 0 ) + { + cpus[i].it++; + assert( cpus[i].it = cpus[i].end ); + } + else + { + cpus[i].startDone = true; + } + } + else + { + if( isOwn ) + { + assert( own > 0 ); + own--; + } + else + { + assert( other > 0 ); + other--; + } + cpus[i].startDone = false; + cpus[i].it++; + } + } + } + const auto& back = vec.back(); + if( back.Other() != other || back.Own() != own ) + { + vec.push_back( ContextSwitchUsage( nextTime, other, own ) ); + } + } + std::lock_guard lock( m_data.lock ); m_data.ctxUsageReady = true; }