mirror of
https://github.com/wolfpld/tracy.git
synced 2026-08-07 13:59:17 +00:00
Keep context switch sample vectors sorted.
Context switch samples were appended in arrival order. Samples which were postponed due to missing context switch data are replayed after newer samples were already classified, so the vector could become unordered. Everything that reads it assumes time order: the wait stacks range filter, the sampling statistics percentage denominator, and the context switch sample filters in the trace load jobs. In the load jobs an unordered vector could silently disable the filtering for the rest of a thread, reintroducing the context switch samples into the symbol and child sample maps. Use a SortedVector and restore the ordering at the points where it can break: after the postponed sample replay and when saving a trace. The save file version is bumped, so that the sort order check on load is only performed for traces saved by previous versions.
This commit is contained in:
@@ -163,7 +163,7 @@ void View::DrawSamplesStatistics( Vector<SymList>& data, int64_t timeRange, Accu
|
||||
uint64_t totalSamples;
|
||||
if( m_statRange.active )
|
||||
{
|
||||
static const auto CountInRange = []( const Vector<SampleData>& vec, int64_t min, int64_t max ) -> uint64_t {
|
||||
static const auto CountInRange = []( const auto& vec, int64_t min, int64_t max ) -> uint64_t {
|
||||
auto it = std::lower_bound( vec.begin(), vec.end(), min, []( const auto& lhs, const auto& rhs ) { return lhs.time.Val() < rhs; } );
|
||||
auto end = std::lower_bound( it, vec.end(), max, []( const auto& lhs, const auto& rhs ) { return lhs.time.Val() < rhs; } );
|
||||
return end - it;
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace tracy::Version
|
||||
{
|
||||
constexpr int Major = 0;
|
||||
constexpr int Minor = 13;
|
||||
constexpr int Patch = 5;
|
||||
constexpr int Patch = 6;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -714,7 +714,7 @@ struct ThreadData
|
||||
#endif
|
||||
Vector<SampleData> samples;
|
||||
SampleData pendingSample;
|
||||
Vector<SampleData> ctxSwitchSamples;
|
||||
SortedVector<SampleData, SampleDataSort> ctxSwitchSamples;
|
||||
uint64_t kernelSampleCnt;
|
||||
uint8_t isFiber;
|
||||
ThreadData* fiber;
|
||||
|
||||
@@ -1100,6 +1100,11 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks, bool allow
|
||||
f.Read( &ptr->callstack, sizeof( ptr->callstack ) );
|
||||
ptr++;
|
||||
}
|
||||
if( fileVer < FileVersion( 0, 13, 6 ) && !std::is_sorted( td->ctxSwitchSamples.begin(), td->ctxSwitchSamples.end(), SampleDataSort() ) )
|
||||
{
|
||||
td->ctxSwitchSamples.mark_unsorted();
|
||||
td->ctxSwitchSamples.ensure_sorted();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4379,6 +4384,7 @@ void Worker::DoPostponedWork()
|
||||
{
|
||||
td->postponedSamples.erase( td->postponedSamples.begin(), sit );
|
||||
}
|
||||
td->ctxSwitchSamples.ensure_sorted();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8494,6 +8500,7 @@ void Worker::Write( FileWrite& f, bool fiDict )
|
||||
auto ptr = uint64_t( (MessageData*)v );
|
||||
f.Write( &ptr, sizeof( ptr ) );
|
||||
}
|
||||
thread->ctxSwitchSamples.ensure_sorted();
|
||||
sz = thread->ctxSwitchSamples.size();
|
||||
f.Write( &sz, sizeof( sz ) );
|
||||
refTime = 0;
|
||||
|
||||
Reference in New Issue
Block a user