Fix thread-sorting bug.

This commit is contained in:
Martijn Courteaux 2024-09-11 10:44:34 +02:00
parent b687831394
commit 46ec677702
3 changed files with 20 additions and 4 deletions

View File

@ -715,10 +715,17 @@ bool View::DrawImpl()
auto& threadHints = m_worker.GetPendingThreadHints(); auto& threadHints = m_worker.GetPendingThreadHints();
if( !threadHints.empty() ) if( !threadHints.empty() )
{ {
m_threadReinsert.reserve( threadHints.size() );
for( auto v : threadHints ) for( auto v : threadHints )
{ {
auto it = std::find_if( m_threadOrder.begin(), m_threadOrder.end(), [v]( const auto& t ) { return t->id == v; } ); auto it = std::find_if( m_threadOrder.begin(), m_threadOrder.end(), [v]( const auto& t ) { return t->id == v; } );
if( it != m_threadOrder.end() ) m_threadOrder.erase( it ); // Will be added in the correct place later, like any newly appearing thread if( it != m_threadOrder.end() )
{
// Will be reinserted in the correct place later.
// A separate list is kept of threads that were already known to avoid having to figure out which one is missing in m_threadOrder.
m_threadReinsert.push_back( *it );
m_threadOrder.erase( it );
}
} }
m_worker.ClearPendingThreadHints(); m_worker.ClearPendingThreadHints();
} }

View File

@ -386,6 +386,7 @@ private:
unordered_flat_map<const void*, int> m_gpuDrift; unordered_flat_map<const void*, int> m_gpuDrift;
unordered_flat_map<const PlotData*, PlotView> m_plotView; unordered_flat_map<const PlotData*, PlotView> m_plotView;
Vector<const ThreadData*> m_threadOrder; Vector<const ThreadData*> m_threadOrder;
Vector<const ThreadData*> m_threadReinsert;
Vector<float> m_threadDnd; Vector<float> m_threadDnd;
tracy_force_inline bool& VisibleMsgThread( uint64_t thread ) tracy_force_inline bool& VisibleMsgThread( uint64_t thread )

View File

@ -366,11 +366,19 @@ void View::DrawTimeline()
if( threadData.size() != m_threadOrder.size() ) if( threadData.size() != m_threadOrder.size() )
{ {
m_threadOrder.reserve( threadData.size() ); m_threadOrder.reserve( threadData.size() );
for( size_t i=m_threadOrder.size(); i<threadData.size(); i++ ) // 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++ )
{ {
auto it = std::upper_bound( m_threadOrder.begin(), m_threadOrder.end(), threadData[i]->groupHint, []( const auto& lhs, const auto& rhs ) { return lhs < rhs->groupHint; } ); const ThreadData *td = i < numReinsert ? m_threadReinsert[i] : threadData[m_threadOrder.size()];
m_threadOrder.insert( it, threadData[i] ); 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();
} }
for( const auto& v : m_threadOrder ) for( const auto& v : m_threadOrder )
{ {