diff --git a/profiler/src/profiler/TracyTimelineItemThread.cpp b/profiler/src/profiler/TracyTimelineItemThread.cpp index 865aaec1..091f4e2e 100644 --- a/profiler/src/profiler/TracyTimelineItemThread.cpp +++ b/profiler/src/profiler/TracyTimelineItemThread.cpp @@ -749,7 +749,7 @@ void TimelineItemThread::PreprocessLocks( const TimelineContext& ctx, const unor const auto& lockmap = *v.second; if( !lockmap.valid ) continue; if( !m_view.Vis( &lockmap ) ) continue; - if( vd.onlyContendedLocks && lockInfoWindow != v.first && ( lockmap.threads.size() == 1 || !lockmap.isContended ) ) continue; + if( vd.onlyContendedLocks && lockInfoWindow != v.first && ( lockmap.threads.size() == 1 || !lockmap.isContended ) && !m_worker.IsDeadlockedPair( tid, v.first ) ) continue; auto it = lockmap.threadMap.find( tid ); if( it == lockmap.threadMap.end() ) continue; diff --git a/profiler/src/profiler/TracyView_Locks.cpp b/profiler/src/profiler/TracyView_Locks.cpp index a2005f56..e6cf27d2 100644 --- a/profiler/src/profiler/TracyView_Locks.cpp +++ b/profiler/src/profiler/TracyView_Locks.cpp @@ -186,6 +186,7 @@ int View::DrawLocks( const TimelineContext& ctx, const std::vectornextEv == LockEvent::NoEvent && ( v.seg->flags & ( LockEventFlags::Waiting | LockEventFlags::SharedWaiting ) ) != 0 && m_worker.IsDeadlockedPair( tid, lock.id ); bool itemHovered = hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( px1, offset + ostep ) ); if( itemHovered ) @@ -338,6 +339,10 @@ int View::DrawLocks( const TimelineContext& ctx, const std::vectorAddRectFilled( wpos + ImVec2( std::max( px0, -10.0 ), offset ), wpos + ImVec2( std::min( px1, double( w + 10 ) ), offset + ty ), cfilled ); + if( deadlockWait ) + { + ImGui::PushFont( g_fonts.normal, FontSmall ); + DrawTextContrast( draw, wpos + ImVec2( std::max( px0, -10.0 ), offset ), 0xFF2222FF, ICON_FA_ARROWS_SPIN ); + ImGui::PopFont(); + } if( m_lockHighlight.thread != lock.thread && ( v.state == LockEventState::HasBlockingLock ) != m_lockHighlight.blocked && v.seg->nextEv != LockEvent::NoEvent && m_lockHighlight.id == int64_t( lock.id ) && m_lockHighlight.begin <= t1 && m_lockHighlight.end >= t0 ) { const auto t = uint8_t( ( sin( std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch() ).count() * 0.01 ) * 0.5 + 0.5 ) * 255 ); @@ -454,7 +473,7 @@ int View::DrawLocks( const TimelineContext& ctx, const std::vectorAddRect( wpos + ImVec2( std::max( px0, -10.0 ), offset ), wpos + ImVec2( std::min( px1, double( w + 10 ) ), offset + ty ), coutline ); } else @@ -511,6 +530,7 @@ void View::DrawLockInfoWindow() ImGui::PushFont( g_fonts.normal, FontBig ); ImGui::Text( "Lock #%" PRIu32 ": %s", m_lockInfoWindow, GetLockDisplayName( m_worker, lock ) ); ImGui::PopFont(); + if( lock.customName.Active() ) { TextFocused( "Name:", m_worker.GetString( srcloc.function ) ); @@ -578,8 +598,10 @@ void View::DrawLockInfoWindow() ImGui::SameLine(); ImGui::TextDisabled( "(%.2f%% of lock lifetime)", lock.waitTotalAgg / float( lifetime ) * 100.f ); TextFocused( "Max waiting threads:", RealToString( lock.maxWaiting ) ); - ImGui::Separator(); + DrawDeadlockDetail( AnyThread, m_lockInfoWindow ); + + ImGui::Separator(); const auto threadList = ImGui::TreeNode( "Thread list" ); ImGui::SameLine(); ImGui::TextDisabled( "(%zu)", lock.threads.size() ); diff --git a/profiler/src/profiler/TracyView_ZoneTimeline.cpp b/profiler/src/profiler/TracyView_ZoneTimeline.cpp index d42a8a78..190929d3 100644 --- a/profiler/src/profiler/TracyView_ZoneTimeline.cpp +++ b/profiler/src/profiler/TracyView_ZoneTimeline.cpp @@ -201,6 +201,40 @@ void View::DrawThreadMessagesList( const TimelineContext& ctx, const std::vector } } } + + { + const auto& dgroups = m_worker.GetDeadlockGroups(); + const auto& dmembers = m_worker.GetDeadlockMembers(); + for( const auto& dlk : dgroups ) + { + for( uint32_t mi=dlk.first; mi vEnd ) continue; + const auto px = ( m.waitTime - vStart ) * pxns; + + draw->AddTriangleFilled( wpos + ImVec2( px - (ty - to) * 0.25f, offset + to + th * 0.5f ), wpos + ImVec2( px + (ty - to) * 0.25f, offset + to + th * 0.5f ), wpos + ImVec2( px, offset + to + th ), 0xFF2222FF ); + draw->AddTriangle( wpos + ImVec2( px - (ty - to) * 0.25f, offset + to + th * 0.5f ), wpos + ImVec2( px + (ty - to) * 0.25f, offset + to + th * 0.5f ), wpos + ImVec2( px, offset + to + th ), 0xFF2222FF, 2.0f ); + + const auto dlkText = "deadlock"; + const auto dtw = ImGui::CalcTextSize( dlkText ).x; + DrawTextContrast( draw, wpos + ImVec2( px - dtw * 0.5f, offset + to + th * 0.5f - ty ), 0xFF2222FF, dlkText ); + + if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px - (ty - to) * 0.5 - 1, offset ), wpos + ImVec2( px + (ty - to) * 0.5 + 1, offset + ty ) ) ) + { + DeadlockTooltip( dlk, dmembers ); + if( IsMouseClicked( ImGuiMouseButton_Left ) ) + { + m_lockInfoWindow = m.lock; + } + if( IsMouseClicked( ImGuiMouseButton_Middle ) ) + { + CenterAtTime( m.waitTime ); + } + } + } + } + } } void View::DrawThreadOverlays( const ThreadData& thread, const ImVec2& ul, const ImVec2& dr )