mirror of
https://github.com/wolfpld/tracy.git
synced 2026-10-23 01:00:54 +00:00
Show a deadlock notification with cycle details.
This commit is contained in:
@@ -758,6 +758,8 @@ bool View::DrawImpl()
|
||||
return keepOpen;
|
||||
}
|
||||
|
||||
m_worker.UpdateDeadlocks();
|
||||
|
||||
if( m_achievements )
|
||||
{
|
||||
if( m_worker.IsConnected() ) Achieve( "connectToClient" );
|
||||
|
||||
@@ -68,6 +68,8 @@ struct MessagesDraw;
|
||||
struct CpuUsageDraw;
|
||||
struct CpuCtxDraw;
|
||||
struct LockDraw;
|
||||
struct DeadlockGroup;
|
||||
struct DeadlockMember;
|
||||
struct PlotDraw;
|
||||
struct FlameGraphContext;
|
||||
|
||||
@@ -211,6 +213,12 @@ public:
|
||||
void DrawThread( const TimelineContext& ctx, const ThreadData& thread, const std::vector<TimelineDraw>& draw, const std::vector<ContextSwitchDraw>& ctxDraw, const std::vector<SamplesDraw>& samplesDraw, const std::vector<std::unique_ptr<LockDraw>>& lockDraw, int& offset, int depth, bool hasCtxSwitches, bool hasSamples );
|
||||
void DrawThreadMessagesList( const TimelineContext& ctx, const std::vector<MessagesDraw>& drawList, int offset, uint64_t tid );
|
||||
void DrawThreadOverlays( const ThreadData& thread, const ImVec2& ul, const ImVec2& dr );
|
||||
|
||||
static constexpr uint64_t AnyThread = ~0ull;
|
||||
static constexpr uint32_t AnyLock = ~0u;
|
||||
void DrawDeadlockMembers( const DeadlockGroup& group, const Vector<DeadlockMember>& members ) const;
|
||||
void DrawDeadlockDetail( uint64_t thread, uint32_t lock ) const;
|
||||
|
||||
bool DrawGpu( const TimelineContext& ctx, const GpuCtxData& gpu, int& offset );
|
||||
bool DrawCpuData( const TimelineContext& ctx, const std::vector<CpuUsageDraw>& cpuDraw, const std::vector<std::vector<CpuCtxDraw>>& ctxDraw, int& offset, bool hasCpuData );
|
||||
void DrawThreadMigrations( const TimelineContext& ctx, const int origOffset, uint64_t thread );
|
||||
@@ -419,7 +427,8 @@ private:
|
||||
|
||||
void ShowZoneInfo( const ZoneEvent& ev );
|
||||
void ShowZoneInfo( const GpuEvent& ev, uint64_t thread );
|
||||
|
||||
void DeadlockTooltip( const DeadlockGroup& group, const Vector<DeadlockMember>& members ) const;
|
||||
void DeadlocksTooltip();
|
||||
void ZoneTooltip( const ZoneEvent& ev );
|
||||
void ZoneTooltip( const GpuEvent& ev );
|
||||
void CallstackTooltip( uint32_t idx );
|
||||
|
||||
@@ -10,6 +10,82 @@ namespace tracy
|
||||
|
||||
extern double s_time;
|
||||
|
||||
void View::DrawDeadlockMembers( const DeadlockGroup& group, const Vector<DeadlockMember>& members ) const
|
||||
{
|
||||
const auto& lockMap = m_worker.GetLockMap();
|
||||
for( uint32_t i=group.first; i<group.first+group.cnt; i++ )
|
||||
{
|
||||
const auto& m = members[i];
|
||||
const auto it = lockMap.find( m.lock );
|
||||
assert( it != lockMap.end() );
|
||||
if( m.holder == m.thread )
|
||||
{
|
||||
ImGui::Text( "\"%s\" waits for %u: %s (upgrade request)", m_worker.GetThreadName( m.thread ), m.lock, GetLockDisplayName( m_worker, *it->second ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Text( "\"%s\" waits for %u: %s, held by \"%s\"", m_worker.GetThreadName( m.thread ), m.lock, GetLockDisplayName( m_worker, *it->second ), m_worker.GetThreadName( m.holder ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void View::DrawDeadlockDetail( uint64_t thread, uint32_t lock ) const
|
||||
{
|
||||
const auto& dgroups = m_worker.GetDeadlockGroups();
|
||||
const auto& dmembers = m_worker.GetDeadlockMembers();
|
||||
for( const auto& g : dgroups )
|
||||
{
|
||||
bool match = false;
|
||||
for( uint32_t i=g.first; i<g.first+g.cnt; i++ )
|
||||
{
|
||||
const auto& m = dmembers[i];
|
||||
if( ( thread == AnyThread || m.thread == thread ) && ( lock == AnyLock || m.lock == lock ) )
|
||||
{
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !match ) continue;
|
||||
ImGui::Separator();
|
||||
TextColoredUnformatted( ImVec4( 1.f, 0.2f, 0.2f, 1.f ), "Deadlock detected" );
|
||||
TextFocused( "Cycle closed at:", TimeToString( g.time ) );
|
||||
DrawDeadlockMembers( g, dmembers );
|
||||
}
|
||||
}
|
||||
|
||||
void View::DeadlockTooltip( const DeadlockGroup& group, const Vector<DeadlockMember>& members ) const
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::TextUnformatted( "Deadlock detected" );
|
||||
TextFocused( "Cycle closed at:", TimeToString( group.time ) );
|
||||
ImGui::Separator();
|
||||
DrawDeadlockMembers( group, members );
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
void View::DeadlocksTooltip()
|
||||
{
|
||||
const auto& groups = m_worker.GetDeadlockGroups();
|
||||
const auto& members = m_worker.GetDeadlockMembers();
|
||||
if( groups.size() == 1 )
|
||||
{
|
||||
DeadlockTooltip( groups[0], members );
|
||||
return;
|
||||
}
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text( "%zu deadlocks detected", groups.size() );
|
||||
for( size_t gi=0; gi<groups.size(); gi++ )
|
||||
{
|
||||
const auto& g = groups[gi];
|
||||
ImGui::Separator();
|
||||
ImGui::Text( "Cycle #%zu closed at: %s", gi+1, TimeToString( g.time ) );
|
||||
ImGui::Indent( ImGui::GetTextLineHeight() );
|
||||
DrawDeadlockMembers( g, members );
|
||||
ImGui::Unindent( ImGui::GetTextLineHeight() );
|
||||
}
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
void View::DrawNotificationArea()
|
||||
{
|
||||
if( m_sendQueueWarning.enabled )
|
||||
@@ -90,6 +166,20 @@ void View::DrawNotificationArea()
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto& deadlocks = m_worker.GetDeadlockGroups();
|
||||
if( !deadlocks.empty() )
|
||||
{
|
||||
ImGui::SameLine();
|
||||
TextColoredUnformatted( ImVec4( 1, 0, 0, 1 ), ICON_FA_ARROWS_SPIN );
|
||||
if( ImGui::IsItemHovered() )
|
||||
{
|
||||
DeadlocksTooltip();
|
||||
if( IsMouseClicked( ImGuiMouseButton_Left ) )
|
||||
{
|
||||
m_showInfo = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( m_worker.AreSamplesInconsistent() )
|
||||
{
|
||||
ImGui::SameLine();
|
||||
|
||||
Reference in New Issue
Block a user