Display threads in a consistent order

This commit is contained in:
Alexey Shekhirin
2026-06-17 12:48:19 +01:00
parent a98956f2d9
commit 066cb89f75
4 changed files with 24 additions and 19 deletions

View File

@@ -249,6 +249,26 @@ void View::ViewSymbol( const char* fileName, int line, uint64_t baseAddr, uint64
m_sourceView->OpenSymbol( fileName, line, baseAddr, symAddr, m_worker, *this );
}
void View::UpdateThreadOrder()
{
const auto& threadData = m_worker.GetThreadData();
if( threadData.size() == m_threadOrder.size() ) return;
m_threadOrder.reserve( threadData.size() );
// Only new threads are in the end of the worker's ThreadData vector.
// Threads which get reordered by received thread hints are not new, yet removed from m_threadOrder.
// Therefore, those are kept in m_threadReinsert and are gathered before the remaining new threads.
const size_t numReinsert = m_threadReinsert.size();
const size_t numNew = threadData.size() - m_threadOrder.size() - numReinsert;
for( size_t i = 0; i < numReinsert + numNew; i++ )
{
const ThreadData* td = i < numReinsert ? m_threadReinsert[i] : threadData[m_threadOrder.size()];
auto it = std::find_if( m_threadOrder.begin(), m_threadOrder.end(), [td]( const auto t ) { return td->groupHint < t->groupHint; } );
m_threadOrder.insert( it, td );
}
m_threadReinsert.clear();
}
bool View::ViewDispatch( const char* fileName, int line, uint64_t symAddr )
{
if( line == 0 )

View File

@@ -437,6 +437,7 @@ private:
void UpdateTitle();
void ValidateSourceRegex();
void UpdateThreadOrder();
unordered_flat_map<uint64_t, int> m_threadDepthLimit;
unordered_flat_map<uint64_t, bool> m_visibleMsgThread;

View File

@@ -1026,7 +1026,8 @@ void View::DrawFlameGraph()
m_flameGraphPan = 0;
}
auto& td = m_worker.GetThreadData();
UpdateThreadOrder();
const auto& td = m_threadOrder;
auto expand = ImGui::TreeNode( ICON_FA_SHUFFLE " Visible threads:" );
ImGui::SameLine();
size_t visibleThreads = 0;

View File

@@ -393,24 +393,7 @@ void View::DrawTimeline()
}
if( m_vd.drawZones )
{
const auto& threadData = m_worker.GetThreadData();
if( threadData.size() != m_threadOrder.size() )
{
m_threadOrder.reserve( threadData.size() );
// Only new threads are in the end of the worker's ThreadData vector.
// Threads which get reordered by received thread hints are not new, yet removed from m_threadOrder.
// Therefore, those are kept in the m_threadReinsert vector. As such, we will gather first threads from the
// reinsert vector, and afterwards the remaining ones must be new (and thus found at the end of threadData).
size_t numReinsert = m_threadReinsert.size();
size_t numNew = threadData.size() - m_threadOrder.size() - numReinsert;
for( size_t i = 0; i < numReinsert + numNew; i++ )
{
const ThreadData *td = i < numReinsert ? m_threadReinsert[i] : threadData[m_threadOrder.size()];
auto it = std::find_if( m_threadOrder.begin(), m_threadOrder.end(), [td]( const auto t ) { return td->groupHint < t->groupHint; } );
m_threadOrder.insert( it, td );
}
m_threadReinsert.clear();
}
UpdateThreadOrder();
for( const auto& v : m_threadOrder )
{
m_tc.AddItem<TimelineItemThread>( v );