mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-23 06:44:35 +00:00
Allow limiting wait stacks to certain threads.
This commit is contained in:
parent
265a39e7c9
commit
94d4272c9c
@ -16320,14 +16320,17 @@ void View::DrawRangeEntry( Range& range, const char* label, uint32_t color, cons
|
|||||||
void View::DrawWaitStacks()
|
void View::DrawWaitStacks()
|
||||||
{
|
{
|
||||||
ImGui::SetNextWindowSize( ImVec2( 1400, 500 ), ImGuiCond_FirstUseEver );
|
ImGui::SetNextWindowSize( ImVec2( 1400, 500 ), ImGuiCond_FirstUseEver );
|
||||||
ImGui::Begin( "Wait stacks", &m_showWaitStacks, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse );
|
ImGui::Begin( "Wait stacks", &m_showWaitStacks );
|
||||||
#ifdef TRACY_NO_STATISTICS
|
#ifdef TRACY_NO_STATISTICS
|
||||||
ImGui::TextWrapped( "Rebuild without the TRACY_NO_STATISTICS macro to enable wait stacks." );
|
ImGui::TextWrapped( "Rebuild without the TRACY_NO_STATISTICS macro to enable wait stacks." );
|
||||||
#else
|
#else
|
||||||
|
uint64_t totalCount = 0;
|
||||||
unordered_flat_map<uint32_t, uint64_t> stacks;
|
unordered_flat_map<uint32_t, uint64_t> stacks;
|
||||||
auto& td = m_worker.GetThreadData();
|
for( auto& t : m_threadOrder )
|
||||||
for( auto& t : td )
|
|
||||||
{
|
{
|
||||||
|
if( WaitStackThread( t->id ) )
|
||||||
|
{
|
||||||
|
totalCount += t->ctxSwitchSamples.size();
|
||||||
for( auto& sd : t->ctxSwitchSamples )
|
for( auto& sd : t->ctxSwitchSamples )
|
||||||
{
|
{
|
||||||
auto cs = sd.callstack.Val();
|
auto cs = sd.callstack.Val();
|
||||||
@ -16342,12 +16345,78 @@ void View::DrawWaitStacks()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const auto totalSamples = m_worker.GetContextSwitchSampleCount();
|
TextFocused( "Total wait stacks:", RealToString( m_worker.GetContextSwitchSampleCount() ) );
|
||||||
TextFocused( "Total wait stacks:", RealToString( totalSamples ) );
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
TextFocused( "Selected:", RealToString( totalCount ) );
|
||||||
|
|
||||||
|
bool threadsChanged = false;
|
||||||
|
auto expand = ImGui::TreeNode( ICON_FA_RANDOM " Visible threads:" );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextDisabled( "(%zu)", m_threadOrder.size() );
|
||||||
|
if( expand )
|
||||||
|
{
|
||||||
|
auto& crash = m_worker.GetCrashEvent();
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
if( ImGui::SmallButton( "Select all" ) )
|
||||||
|
{
|
||||||
|
for( const auto& t : m_threadOrder )
|
||||||
|
{
|
||||||
|
WaitStackThread( t->id ) = true;
|
||||||
|
}
|
||||||
|
threadsChanged = true;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if( ImGui::SmallButton( "Unselect all" ) )
|
||||||
|
{
|
||||||
|
for( const auto& t : m_threadOrder )
|
||||||
|
{
|
||||||
|
WaitStackThread( t->id ) = false;
|
||||||
|
}
|
||||||
|
threadsChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
for( const auto& t : m_threadOrder )
|
||||||
|
{
|
||||||
|
if( t->ctxSwitchSamples.empty() ) continue;
|
||||||
|
ImGui::PushID( idx++ );
|
||||||
|
const auto threadColor = GetThreadColor( t->id, 0 );
|
||||||
|
SmallColorBox( threadColor );
|
||||||
|
ImGui::SameLine();
|
||||||
|
if( SmallCheckbox( m_worker.GetThreadName( t->id ), &WaitStackThread( t->id ) ) )
|
||||||
|
{
|
||||||
|
threadsChanged = true;
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextDisabled( "(%s)", RealToString( t->ctxSwitchSamples.size() ) );
|
||||||
|
if( crash.thread == t->id )
|
||||||
|
{
|
||||||
|
ImGui::SameLine();
|
||||||
|
TextColoredUnformatted( ImVec4( 1.f, 0.2f, 0.2f, 1.f ), ICON_FA_SKULL " Crashed" );
|
||||||
|
}
|
||||||
|
if( t->isFiber )
|
||||||
|
{
|
||||||
|
ImGui::SameLine();
|
||||||
|
TextColoredUnformatted( ImVec4( 0.2f, 0.6f, 0.2f, 1.f ), "Fiber" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
if( threadsChanged ) m_waitStack = 0;
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
if( stacks.empty() )
|
||||||
|
{
|
||||||
|
ImGui::TextUnformatted( "No wait stacks to display." );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
TextDisabledUnformatted( "Wait stack:" );
|
TextDisabledUnformatted( "Wait stack:" );
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if( ImGui::SmallButton( " " ICON_FA_CARET_LEFT " " ) )
|
if( ImGui::SmallButton( " " ICON_FA_CARET_LEFT " " ) )
|
||||||
@ -16370,18 +16439,21 @@ void View::DrawWaitStacks()
|
|||||||
if( clicked ) m_waitStack = std::min( std::max( sel, 1 ), int( stacks.size() ) ) - 1;
|
if( clicked ) m_waitStack = std::min( std::max( sel, 1 ), int( stacks.size() ) ) - 1;
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::SameLine();
|
||||||
Vector<decltype(stacks.begin())> data;
|
Vector<decltype(stacks.begin())> data;
|
||||||
data.reserve( stacks.size() );
|
data.reserve( stacks.size() );
|
||||||
for( auto it = stacks.begin(); it != stacks.end(); ++it ) data.push_back( it );
|
for( auto it = stacks.begin(); it != stacks.end(); ++it ) data.push_back( it );
|
||||||
pdqsort_branchless( data.begin(), data.end(), []( const auto& l, const auto& r ) { return l->second > r->second; } );
|
pdqsort_branchless( data.begin(), data.end(), []( const auto& l, const auto& r ) { return l->second > r->second; } );
|
||||||
ImGui::SameLine();
|
|
||||||
TextFocused( "Counts:", RealToString( data[m_waitStack]->second ) );
|
TextFocused( "Counts:", RealToString( data[m_waitStack]->second ) );
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
char buf[64];
|
char buf[64];
|
||||||
PrintStringPercent( buf, 100. * data[m_waitStack]->second / totalSamples );
|
PrintStringPercent( buf, 100. * data[m_waitStack]->second / totalCount );
|
||||||
TextDisabledUnformatted( buf );
|
TextDisabledUnformatted( buf );
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
DrawCallstackTable( data[m_waitStack]->first, false );
|
DrawCallstackTable( data[m_waitStack]->first, false );
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
@ -313,6 +313,7 @@ private:
|
|||||||
|
|
||||||
unordered_flat_map<const void*, VisData> m_visData;
|
unordered_flat_map<const void*, VisData> m_visData;
|
||||||
unordered_flat_map<uint64_t, bool> m_visibleMsgThread;
|
unordered_flat_map<uint64_t, bool> m_visibleMsgThread;
|
||||||
|
unordered_flat_map<uint64_t, bool> m_waitStackThread;
|
||||||
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;
|
||||||
@ -338,6 +339,16 @@ private:
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tracy_force_inline bool& WaitStackThread( uint64_t thread )
|
||||||
|
{
|
||||||
|
auto it = m_waitStackThread.find( thread );
|
||||||
|
if( it == m_waitStackThread.end() )
|
||||||
|
{
|
||||||
|
it = m_waitStackThread.emplace( thread, true ).first;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
tracy_force_inline int& GpuDrift( const void* ptr )
|
tracy_force_inline int& GpuDrift( const void* ptr )
|
||||||
{
|
{
|
||||||
auto it = m_gpuDrift.find( ptr );
|
auto it = m_gpuDrift.find( ptr );
|
||||||
|
Loading…
Reference in New Issue
Block a user