From 433a80c2dfd5ca5cd190816576414dc7431c06d9 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Sat, 28 Oct 2017 13:44:46 +0200 Subject: [PATCH] Move lock state progression to a separate function. --- server/TracyVector.hpp | 2 + server/TracyView.cpp | 224 +++++++++++++++++++++-------------------- 2 files changed, 118 insertions(+), 108 deletions(-) diff --git a/server/TracyVector.hpp b/server/TracyVector.hpp index 6cbc64d6..3567d6cb 100644 --- a/server/TracyVector.hpp +++ b/server/TracyVector.hpp @@ -17,6 +17,8 @@ template class Vector { public: + using iterator = T*; + Vector() : m_ptr( nullptr ) , m_size( 0 ) diff --git a/server/TracyView.cpp b/server/TracyView.cpp index 00d6ed0c..18f3c987 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -2157,16 +2157,111 @@ static inline bool AreOtherWaiting( uint64_t bitlist, uint8_t thread ) return ( bitlist & ~( uint64_t( 1 ) << thread ) ) != 0; } +enum class LockState +{ + Nothing, + HasLock, // green + HasBlockingLock, // yellow + WaitLock // red +}; + +static Vector::iterator GetNextLockEvent( const Vector::iterator& it, const Vector::iterator& end, LockState state, LockState& nextState, uint8_t thread ) +{ + nextState = LockState::Nothing; + auto next = it; + next++; + + switch( state ) + { + case LockState::Nothing: + while( next < end ) + { + if( (*next)->lockCount != 0 ) + { + if( (*next)->lockingThread == thread ) + { + nextState = AreOtherWaiting( (*next)->waitList, thread ) ? LockState::HasBlockingLock : LockState::HasLock; + break; + } + else if( IsThreadWaiting( (*next)->waitList, thread ) ) + { + nextState = LockState::WaitLock; + break; + } + } + next++; + } + break; + case LockState::HasLock: + nextState = LockState::HasLock; + while( next < end ) + { + if( (*next)->lockCount == 0 ) + { + nextState = LockState::Nothing; + break; + } + if( (*next)->waitList != 0 ) + { + if( AreOtherWaiting( (*next)->waitList, thread ) ) + { + nextState = LockState::HasBlockingLock; + } + break; + } + if( (*next)->waitList != (*it)->waitList || (*next)->lockCount != (*it)->lockCount ) + { + break; + } + next++; + } + break; + case LockState::HasBlockingLock: + nextState = LockState::HasBlockingLock; + while( next < end ) + { + if( (*next)->lockCount == 0 ) + { + nextState = LockState::Nothing; + break; + } + if( (*next)->waitList != (*it)->waitList || (*next)->lockCount != (*it)->lockCount ) + { + break; + } + next++; + } + break; + case LockState::WaitLock: + nextState = LockState::WaitLock; + while( next < end ) + { + if( (*next)->lockingThread == thread ) + { + nextState = AreOtherWaiting( (*next)->waitList, thread ) ? LockState::HasBlockingLock : LockState::HasLock; + break; + } + if( (*next)->lockingThread != (*it)->lockingThread ) + { + break; + } + if( (*next)->lockCount == 0 ) + { + break; + } + next++; + } + break; + default: + assert( false ); + break; + } + + return next; +} + int View::DrawLocks( uint64_t tid, bool hover, double pxns, const ImVec2& wpos, int _offset, LockHighlight& highlight ) { - enum class State - { - Nothing, - HasLock, // green - HasBlockingLock, // yellow - WaitLock // red - }; - int cnt = 0; for( auto& v : m_lockMap ) { @@ -2198,112 +2293,25 @@ int View::DrawLocks( uint64_t tid, bool hover, double pxns, const ImVec2& wpos, const auto dsz = m_delay * pxns; const auto rsz = m_resolution * pxns; - State state = State::Nothing; + LockState state = LockState::Nothing; if( (*vbegin)->lockCount != 0 ) { if( (*vbegin)->lockingThread == thread ) { - state = AreOtherWaiting( (*vbegin)->waitList, thread ) ? State::HasBlockingLock : State::HasLock; + state = AreOtherWaiting( (*vbegin)->waitList, thread ) ? LockState::HasBlockingLock : LockState::HasLock; } else if( IsThreadWaiting( (*vbegin)->waitList, thread ) ) { - state = State::WaitLock; + state = LockState::WaitLock; } } while( vbegin < vend ) { - State nextState = State::Nothing; - auto next = vbegin; - next++; + LockState nextState; + auto next = GetNextLockEvent( vbegin, vend, state, nextState, thread ); - switch( state ) - { - case State::Nothing: - while( next < vendn ) - { - if( (*next)->lockCount != 0 ) - { - if( (*next)->lockingThread == thread ) - { - nextState = AreOtherWaiting( (*next)->waitList, thread ) ? State::HasBlockingLock : State::HasLock; - break; - } - else if( IsThreadWaiting( (*next)->waitList, thread ) ) - { - nextState = State::WaitLock; - break; - } - } - next++; - } - break; - case State::HasLock: - nextState = State::HasLock; - while( next < vendn ) - { - if( (*next)->lockCount == 0 ) - { - nextState = State::Nothing; - break; - } - if( (*next)->waitList != 0 ) - { - if( AreOtherWaiting( (*next)->waitList, thread ) ) - { - nextState = State::HasBlockingLock; - } - break; - } - if( (*next)->waitList != (*vbegin)->waitList || (*next)->lockCount != (*vbegin)->lockCount ) - { - break; - } - next++; - } - break; - case State::HasBlockingLock: - nextState = State::HasBlockingLock; - while( next < vendn ) - { - if( (*next)->lockCount == 0 ) - { - nextState = State::Nothing; - break; - } - if( (*next)->waitList != (*vbegin)->waitList || (*next)->lockCount != (*vbegin)->lockCount ) - { - break; - } - next++; - } - break; - case State::WaitLock: - nextState = State::WaitLock; - while( next < vendn ) - { - if( (*next)->lockingThread == thread ) - { - nextState = AreOtherWaiting( (*next)->waitList, thread ) ? State::HasBlockingLock : State::HasLock; - break; - } - if( (*next)->lockingThread != (*vbegin)->lockingThread ) - { - break; - } - if( (*next)->lockCount == 0 ) - { - break; - } - next++; - } - break; - default: - assert( false ); - break; - } - - if( state != State::Nothing && ( !m_onlyContendedLocks || state != State::HasLock ) ) + if( state != LockState::Nothing && ( !m_onlyContendedLocks || state != LockState::HasLock ) ) { drawn = true; const auto t0 = (*vbegin)->time; @@ -2314,7 +2322,7 @@ int View::DrawLocks( uint64_t tid, bool hover, double pxns, const ImVec2& wpos, bool itemHovered = hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( std::max( px0, -10.0 ), offset ), wpos + ImVec2( std::min( px1, double( w + 10 ) ), offset + ty ) ); if( itemHovered ) { - highlight.blocked = state == State::HasBlockingLock; + highlight.blocked = state == LockState::HasBlockingLock; if( !highlight.blocked ) { highlight.id = v.first; @@ -2384,7 +2392,7 @@ int View::DrawLocks( uint64_t tid, bool hover, double pxns, const ImVec2& wpos, switch( state ) { - case State::HasLock: + case LockState::HasLock: if( (*vbegin)->lockCount == 1 ) { ImGui::Text( "Thread \"%s\" has lock. No other threads are waiting.", GetThreadString( tid ) ); @@ -2399,7 +2407,7 @@ int View::DrawLocks( uint64_t tid, bool hover, double pxns, const ImVec2& wpos, ImGui::Text( "Recursive lock acquire in thread." ); } break; - case State::HasBlockingLock: + case LockState::HasBlockingLock: { if( (*vbegin)->lockCount == 1 ) { @@ -2422,7 +2430,7 @@ int View::DrawLocks( uint64_t tid, bool hover, double pxns, const ImVec2& wpos, } break; } - case State::WaitLock: + case LockState::WaitLock: { ImGui::Text( "Thread \"%s\" is blocked by other thread:", GetThreadString( tid ) ); ImGui::Text( "\"%s\"", GetThreadString( lockmap.threadList[(*vbegin)->lockingThread] ) ); @@ -2435,16 +2443,16 @@ int View::DrawLocks( uint64_t tid, bool hover, double pxns, const ImVec2& wpos, ImGui::EndTooltip(); } - const auto cfilled = state == State::HasLock ? 0xFF228A22 : ( state == State::HasBlockingLock ? 0xFF228A8A : 0xFF2222BD ); + const auto cfilled = state == LockState::HasLock ? 0xFF228A22 : ( state == LockState::HasBlockingLock ? 0xFF228A8A : 0xFF2222BD ); draw->AddRectFilled( wpos + ImVec2( std::max( px0, -10.0 ), offset ), wpos + ImVec2( std::min( px1, double( w + 10 ) ), offset + ty ), cfilled, 2.f ); - if( m_lockHighlight.thread != thread && ( state == State::HasBlockingLock ) != m_lockHighlight.blocked && next != tl.end() && m_lockHighlight.id == v.first && m_lockHighlight.begin <= (*vbegin)->time && m_lockHighlight.end >= (*next)->time ) + if( m_lockHighlight.thread != thread && ( state == LockState::HasBlockingLock ) != m_lockHighlight.blocked && next != tl.end() && m_lockHighlight.id == v.first && m_lockHighlight.begin <= (*vbegin)->time && m_lockHighlight.end >= (*next)->time ) { 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 ); draw->AddRect( wpos + ImVec2( std::max( px0, -10.0 ), offset ), wpos + ImVec2( std::min( px1, double( w + 10 ) ), offset + ty ), 0x00FFFFFF | ( t << 24 ), 2.f, -1, 2.f ); } else { - const auto coutline = state == State::HasLock ? 0xFF3BA33B : ( state == State::HasBlockingLock ? 0xFF3BA3A3 : 0xFF3B3BD6 ); + const auto coutline = state == LockState::HasLock ? 0xFF3BA33B : ( state == LockState::HasBlockingLock ? 0xFF3BA3A3 : 0xFF3B3BD6 ); draw->AddRect( wpos + ImVec2( std::max( px0, -10.0 ), offset ), wpos + ImVec2( std::min( px1, double( w + 10 ) ), offset + ty ), coutline, 2.f ); } if( dsz >= MinVisSize )