Add wait stacks window.

This commit is contained in:
Bartosz Taudul 2021-11-13 15:58:25 +01:00
parent 45df37e3a9
commit 9ba5180b04
No known key found for this signature in database
GPG Key ID: B7FE2008B7575DF3
2 changed files with 79 additions and 1 deletions

View File

@ -925,6 +925,11 @@ bool View::DrawImpl()
m_showAnnotationList = true; m_showAnnotationList = true;
} }
ToggleButton( ICON_FA_RULER " Limits", m_showRanges ); ToggleButton( ICON_FA_RULER " Limits", m_showRanges );
const auto cscnt = m_worker.GetContextSwitchSampleCount();
if( ButtonDisablable( ICON_FA_HOURGLASS_HALF " Wait stacks", cscnt == 0 ) )
{
m_showWaitStacks = true;
}
ImGui::EndPopup(); ImGui::EndPopup();
} }
ImGui::SameLine(); ImGui::SameLine();
@ -1095,6 +1100,7 @@ bool View::DrawImpl()
if( m_showAnnotationList ) DrawAnnotationList(); if( m_showAnnotationList ) DrawAnnotationList();
if( m_sampleParents.symAddr != 0 ) DrawSampleParents(); if( m_sampleParents.symAddr != 0 ) DrawSampleParents();
if( m_showRanges ) DrawRanges(); if( m_showRanges ) DrawRanges();
if( m_showWaitStacks ) DrawWaitStacks();
if( m_setRangePopup.active ) if( m_setRangePopup.active )
{ {
@ -3972,7 +3978,7 @@ void View::DrawContextSwitches( const ContextSwitch* ctx, const Vector<SampleDat
if( sdit != sampleData.end() && sdit->time.Val() == ev.Start() ) if( sdit != sampleData.end() && sdit->time.Val() == ev.Start() )
{ {
ImGui::Separator(); ImGui::Separator();
TextDisabledUnformatted( "Wait stack:" ); TextDisabledUnformatted( ICON_FA_HOURGLASS_HALF " Wait stack:" );
CallstackTooltipContents( sdit->callstack.Val() ); CallstackTooltipContents( sdit->callstack.Val() );
if( ImGui::IsMouseClicked( 0 ) ) if( ImGui::IsMouseClicked( 0 ) )
{ {
@ -16311,6 +16317,75 @@ void View::DrawRangeEntry( Range& range, const char* label, uint32_t color, cons
} }
} }
void View::DrawWaitStacks()
{
ImGui::SetNextWindowSize( ImVec2( 1400, 500 ), ImGuiCond_FirstUseEver );
ImGui::Begin( "Wait stacks", &m_showWaitStacks, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse );
#ifdef TRACY_NO_STATISTICS
ImGui::TextWrapped( "Rebuild without the TRACY_NO_STATISTICS macro to enable wait stacks." );
#else
unordered_flat_map<uint32_t, uint64_t> stacks;
auto& td = m_worker.GetThreadData();
for( auto& t : td )
{
for( auto& sd : t->ctxSwitchSamples )
{
auto cs = sd.callstack.Val();
auto it = stacks.find( cs );
if( it == stacks.end() )
{
stacks.emplace( cs, 1 );
}
else
{
it->second++;
}
}
}
const auto totalSamples = m_worker.GetContextSwitchSampleCount();
TextFocused( "Total wait stacks:", RealToString( totalSamples ) );
ImGui::SameLine();
ImGui::Spacing();
ImGui::SameLine();
TextDisabledUnformatted( "Wait stack:" );
ImGui::SameLine();
if( ImGui::SmallButton( " " ICON_FA_CARET_LEFT " " ) )
{
m_waitStack = std::max( m_waitStack - 1, 0 );
}
ImGui::SameLine();
ImGui::Text( "%s / %s", RealToString( m_waitStack + 1 ), RealToString( stacks.size() ) );
if( ImGui::IsItemClicked() ) ImGui::OpenPopup( "WaitStacksPopup" );
ImGui::SameLine();
if( ImGui::SmallButton( " " ICON_FA_CARET_RIGHT " " ) )
{
m_waitStack = std::min<int>( m_waitStack + 1, stacks.size() - 1 );
}
if( ImGui::BeginPopup( "WaitStacksPopup" ) )
{
int sel = m_waitStack + 1;
ImGui::SetNextItemWidth( 120 );
const bool clicked = ImGui::InputInt( "##waitStack", &sel, 1, 100, ImGuiInputTextFlags_EnterReturnsTrue );
if( clicked ) m_waitStack = std::min( std::max( sel, 1 ), int( stacks.size() ) ) - 1;
ImGui::EndPopup();
}
Vector<decltype(stacks.begin())> data;
data.reserve( stacks.size() );
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; } );
ImGui::SameLine();
TextFocused( "Counts:", RealToString( data[m_waitStack]->second ) );
ImGui::SameLine();
char buf[64];
PrintStringPercent( buf, 100. * data[m_waitStack]->second / totalSamples );
TextDisabledUnformatted( buf );
ImGui::Separator();
DrawCallstackTable( data[m_waitStack]->first, false );
#endif
ImGui::End();
}
void View::ListMemData( std::vector<const MemEvent*>& vec, std::function<void(const MemEvent*)> DrawAddress, const char* id, int64_t startTime, uint64_t pool ) void View::ListMemData( std::vector<const MemEvent*>& vec, std::function<void(const MemEvent*)> DrawAddress, const char* id, int64_t startTime, uint64_t pool )
{ {
if( startTime == -1 ) startTime = 0; if( startTime == -1 ) startTime = 0;

View File

@ -221,6 +221,7 @@ private:
void DrawRanges(); void DrawRanges();
void DrawRangeEntry( Range& range, const char* label, uint32_t color, const char* popupLabel, int id ); void DrawRangeEntry( Range& range, const char* label, uint32_t color, const char* popupLabel, int id );
void DrawSourceTooltip( const char* filename, uint32_t line, int before = 3, int after = 3, bool separateTooltip = true ); void DrawSourceTooltip( const char* filename, uint32_t line, int before = 3, int after = 3, bool separateTooltip = true );
void DrawWaitStacks();
void ListMemData( std::vector<const MemEvent*>& vec, std::function<void(const MemEvent*)> DrawAddress, const char* id = nullptr, int64_t startTime = -1, uint64_t pool = 0 ); void ListMemData( std::vector<const MemEvent*>& vec, std::function<void(const MemEvent*)> DrawAddress, const char* id = nullptr, int64_t startTime = -1, uint64_t pool = 0 );
@ -411,6 +412,7 @@ private:
bool m_showPlayback = false; bool m_showPlayback = false;
bool m_showCpuDataWindow = false; bool m_showCpuDataWindow = false;
bool m_showAnnotationList = false; bool m_showAnnotationList = false;
bool m_showWaitStacks = false;
AccumulationMode m_statAccumulationMode = AccumulationMode::SelfOnly; AccumulationMode m_statAccumulationMode = AccumulationMode::SelfOnly;
bool m_statSampleTime = true; bool m_statSampleTime = true;
@ -428,6 +430,7 @@ private:
bool m_ctxSwitchTimeRelativeToZone = true; bool m_ctxSwitchTimeRelativeToZone = true;
bool m_messageTimeRelativeToZone = true; bool m_messageTimeRelativeToZone = true;
uint64_t m_zoneInfoMemPool = 0; uint64_t m_zoneInfoMemPool = 0;
int m_waitStack = 0;
ShortcutAction m_shortcut = ShortcutAction::None; ShortcutAction m_shortcut = ShortcutAction::None;
Namespace m_namespace = Namespace::Short; Namespace m_namespace = Namespace::Short;