mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-10 02:31:48 +00:00
Extract lock state handling to a separate context class.
This commit is contained in:
parent
4c736aecfa
commit
a221f121ba
@ -11,11 +11,10 @@
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
template<class T>
|
||||
class Lockable
|
||||
class LockableCtx
|
||||
{
|
||||
public:
|
||||
tracy_force_inline Lockable( const SourceLocationData* srcloc )
|
||||
tracy_force_inline LockableCtx( const SourceLocationData* srcloc )
|
||||
: m_id( GetLockCounter().fetch_add( 1, std::memory_order_relaxed ) )
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
, m_lockCount( 0 )
|
||||
@ -33,18 +32,16 @@ public:
|
||||
MemWrite( &item->lockAnnounce.time, Profiler::GetTime() );
|
||||
MemWrite( &item->lockAnnounce.lckloc, (uint64_t)srcloc );
|
||||
MemWrite( &item->lockAnnounce.type, LockType::Lockable );
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
|
||||
tail.store( magic + 1, std::memory_order_release );
|
||||
}
|
||||
|
||||
Lockable( const Lockable& ) = delete;
|
||||
Lockable& operator=( const Lockable& ) = delete;
|
||||
LockableCtx( const LockableCtx& ) = delete;
|
||||
LockableCtx& operator=( const LockableCtx& ) = delete;
|
||||
|
||||
~Lockable()
|
||||
tracy_force_inline ~LockableCtx()
|
||||
{
|
||||
Magic magic;
|
||||
auto token = GetToken();
|
||||
@ -54,15 +51,13 @@ public:
|
||||
MemWrite( &item->lockTerminate.id, m_id );
|
||||
MemWrite( &item->lockTerminate.time, Profiler::GetTime() );
|
||||
MemWrite( &item->lockTerminate.type, LockType::Lockable );
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
|
||||
tail.store( magic + 1, std::memory_order_release );
|
||||
}
|
||||
|
||||
tracy_force_inline void lock()
|
||||
tracy_force_inline bool BeforeLock()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
bool queue = false;
|
||||
@ -74,40 +69,31 @@ public:
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue )
|
||||
{
|
||||
m_lockable.lock();
|
||||
return;
|
||||
}
|
||||
if( !queue ) return false;
|
||||
#endif
|
||||
const auto thread = GetThreadHandle();
|
||||
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockWait );
|
||||
MemWrite( &item->lockWait.thread, thread );
|
||||
MemWrite( &item->lockWait.id, m_id );
|
||||
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||
MemWrite( &item->lockWait.type, LockType::Lockable );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
m_lockable.lock();
|
||||
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||
MemWrite( &item->lockObtain.thread, thread );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockWait );
|
||||
MemWrite( &item->lockWait.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockWait.id, m_id );
|
||||
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||
MemWrite( &item->lockWait.type, LockType::Lockable );
|
||||
Profiler::QueueSerialFinish();
|
||||
return true;
|
||||
}
|
||||
|
||||
tracy_force_inline void unlock()
|
||||
tracy_force_inline void AfterLock()
|
||||
{
|
||||
m_lockable.unlock();
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterUnlock()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
m_lockCount.fetch_sub( 1, std::memory_order_relaxed );
|
||||
if( !m_active.load( std::memory_order_relaxed ) ) return;
|
||||
@ -126,12 +112,10 @@ public:
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline bool try_lock()
|
||||
tracy_force_inline void AfterTryLock( bool acquired )
|
||||
{
|
||||
const auto ret = m_lockable.try_lock();
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !ret ) return ret;
|
||||
if( !acquired ) return;
|
||||
|
||||
bool queue = false;
|
||||
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
@ -142,10 +126,10 @@ public:
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue ) return ret;
|
||||
if( !queue ) return;
|
||||
#endif
|
||||
|
||||
if( ret )
|
||||
if( acquired )
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||
@ -154,8 +138,6 @@ public:
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||
@ -180,7 +162,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_lockable;
|
||||
uint32_t m_id;
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
@ -189,12 +170,53 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
class SharedLockable
|
||||
class Lockable
|
||||
{
|
||||
public:
|
||||
tracy_force_inline SharedLockable( const SourceLocationData* srcloc )
|
||||
tracy_force_inline Lockable( const SourceLocationData* srcloc )
|
||||
: m_ctx( srcloc )
|
||||
{
|
||||
}
|
||||
|
||||
Lockable( const Lockable& ) = delete;
|
||||
Lockable& operator=( const Lockable& ) = delete;
|
||||
|
||||
tracy_force_inline void lock()
|
||||
{
|
||||
const auto runAfter = m_ctx.BeforeLock();
|
||||
m_lockable.lock();
|
||||
if( runAfter ) m_ctx.AfterLock();
|
||||
}
|
||||
|
||||
tracy_force_inline void unlock()
|
||||
{
|
||||
m_lockable.unlock();
|
||||
m_ctx.AfterUnlock();
|
||||
}
|
||||
|
||||
tracy_force_inline bool try_lock()
|
||||
{
|
||||
const auto acquired = m_lockable.try_lock();
|
||||
m_ctx.AfterTryLock( acquired );
|
||||
return acquired;
|
||||
}
|
||||
|
||||
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||
{
|
||||
m_ctx.Mark( srcloc );
|
||||
}
|
||||
|
||||
private:
|
||||
T m_lockable;
|
||||
LockableCtx m_ctx;
|
||||
};
|
||||
|
||||
|
||||
class SharedLockableCtx
|
||||
{
|
||||
public:
|
||||
tracy_force_inline SharedLockableCtx( const SourceLocationData* srcloc )
|
||||
: m_id( GetLockCounter().fetch_add( 1, std::memory_order_relaxed ) )
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
, m_lockCount( 0 )
|
||||
@ -220,10 +242,10 @@ public:
|
||||
tail.store( magic + 1, std::memory_order_release );
|
||||
}
|
||||
|
||||
SharedLockable( const SharedLockable& ) = delete;
|
||||
SharedLockable& operator=( const SharedLockable& ) = delete;
|
||||
SharedLockableCtx( const SharedLockableCtx& ) = delete;
|
||||
SharedLockableCtx& operator=( const SharedLockableCtx& ) = delete;
|
||||
|
||||
~SharedLockable()
|
||||
tracy_force_inline ~SharedLockableCtx()
|
||||
{
|
||||
Magic magic;
|
||||
auto token = GetToken();
|
||||
@ -241,7 +263,7 @@ public:
|
||||
tail.store( magic + 1, std::memory_order_release );
|
||||
}
|
||||
|
||||
tracy_force_inline void lock()
|
||||
tracy_force_inline bool BeforeLock()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
bool queue = false;
|
||||
@ -253,40 +275,31 @@ public:
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue )
|
||||
{
|
||||
m_lockable.lock();
|
||||
return;
|
||||
}
|
||||
if( !queue ) return false;
|
||||
#endif
|
||||
const auto thread = GetThreadHandle();
|
||||
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockWait );
|
||||
MemWrite( &item->lockWait.thread, thread );
|
||||
MemWrite( &item->lockWait.id, m_id );
|
||||
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||
MemWrite( &item->lockWait.type, LockType::SharedLockable );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
m_lockable.lock();
|
||||
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||
MemWrite( &item->lockObtain.thread, thread );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockWait );
|
||||
MemWrite( &item->lockWait.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockWait.id, m_id );
|
||||
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||
MemWrite( &item->lockWait.type, LockType::SharedLockable );
|
||||
Profiler::QueueSerialFinish();
|
||||
return true;
|
||||
}
|
||||
|
||||
tracy_force_inline void unlock()
|
||||
tracy_force_inline void AfterLock()
|
||||
{
|
||||
m_lockable.unlock();
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterUnlock()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
m_lockCount.fetch_sub( 1, std::memory_order_relaxed );
|
||||
if( !m_active.load( std::memory_order_relaxed ) ) return;
|
||||
@ -305,12 +318,10 @@ public:
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline bool try_lock()
|
||||
tracy_force_inline void AfterTryLock( bool acquired )
|
||||
{
|
||||
const auto ret = m_lockable.try_lock();
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !ret ) return ret;
|
||||
if( !acquired ) return;
|
||||
|
||||
bool queue = false;
|
||||
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
@ -321,10 +332,10 @@ public:
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue ) return ret;
|
||||
if( !queue ) return;
|
||||
#endif
|
||||
|
||||
if( ret )
|
||||
if( acquired )
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||
@ -333,11 +344,9 @@ public:
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
tracy_force_inline void lock_shared()
|
||||
tracy_force_inline bool BeforeLockShared()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
bool queue = false;
|
||||
@ -349,40 +358,31 @@ public:
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue )
|
||||
{
|
||||
m_lockable.lock_shared();
|
||||
return;
|
||||
}
|
||||
if( !queue ) return false;
|
||||
#endif
|
||||
const auto thread = GetThreadHandle();
|
||||
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockSharedWait );
|
||||
MemWrite( &item->lockWait.thread, thread );
|
||||
MemWrite( &item->lockWait.id, m_id );
|
||||
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||
MemWrite( &item->lockWait.type, LockType::SharedLockable );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
m_lockable.lock_shared();
|
||||
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockSharedObtain );
|
||||
MemWrite( &item->lockObtain.thread, thread );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockSharedWait );
|
||||
MemWrite( &item->lockWait.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockWait.id, m_id );
|
||||
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||
MemWrite( &item->lockWait.type, LockType::SharedLockable );
|
||||
Profiler::QueueSerialFinish();
|
||||
return true;
|
||||
}
|
||||
|
||||
tracy_force_inline void unlock_shared()
|
||||
tracy_force_inline void AfterLockShared()
|
||||
{
|
||||
m_lockable.unlock_shared();
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockSharedObtain );
|
||||
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterUnlockShared()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
m_lockCount.fetch_sub( 1, std::memory_order_relaxed );
|
||||
if( !m_active.load( std::memory_order_relaxed ) ) return;
|
||||
@ -401,12 +401,10 @@ public:
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline bool try_lock_shared()
|
||||
tracy_force_inline void AfterTryLockShared( bool acquired )
|
||||
{
|
||||
const auto ret = m_lockable.try_lock_shared();
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !ret ) return ret;
|
||||
if( !acquired ) return;
|
||||
|
||||
bool queue = false;
|
||||
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
@ -417,10 +415,10 @@ public:
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue ) return ret;
|
||||
if( !queue ) return;
|
||||
#endif
|
||||
|
||||
if( ret )
|
||||
if( acquired )
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockSharedObtain );
|
||||
@ -429,8 +427,6 @@ public:
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||
@ -455,7 +451,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
T m_lockable;
|
||||
uint32_t m_id;
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
@ -464,6 +459,68 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class SharedLockable
|
||||
{
|
||||
public:
|
||||
tracy_force_inline SharedLockable( const SourceLocationData* srcloc )
|
||||
: m_ctx( srcloc )
|
||||
{
|
||||
}
|
||||
|
||||
SharedLockable( const SharedLockable& ) = delete;
|
||||
SharedLockable& operator=( const SharedLockable& ) = delete;
|
||||
|
||||
tracy_force_inline void lock()
|
||||
{
|
||||
const auto runAfter = m_ctx.BeforeLock();
|
||||
m_lockable.lock();
|
||||
if( runAfter ) m_ctx.AfterLock();
|
||||
}
|
||||
|
||||
tracy_force_inline void unlock()
|
||||
{
|
||||
m_lockable.unlock();
|
||||
m_ctx.AfterUnlock();
|
||||
}
|
||||
|
||||
tracy_force_inline bool try_lock()
|
||||
{
|
||||
const auto acquired = m_lockable.try_lock();
|
||||
m_ctx.AfterTryLock( acquired );
|
||||
return acquired;
|
||||
}
|
||||
|
||||
tracy_force_inline void lock_shared()
|
||||
{
|
||||
const auto runAfter = m_ctx.BeforeLockShared();
|
||||
m_lockable.lock_shared();
|
||||
if( runAfter ) m_ctx.AfterLockShared();
|
||||
}
|
||||
|
||||
tracy_force_inline void unlock_shared()
|
||||
{
|
||||
m_lockable.unlock_shared();
|
||||
m_ctx.AfterUnlockShared();
|
||||
}
|
||||
|
||||
tracy_force_inline bool try_lock_shared()
|
||||
{
|
||||
const auto acquired = m_lockable.try_lock_shared();
|
||||
m_ctx.AfterTryLockShared( acquired );
|
||||
return acquired;
|
||||
}
|
||||
|
||||
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||
{
|
||||
m_ctx.Mark( srcloc );
|
||||
}
|
||||
|
||||
private:
|
||||
T m_lockable;
|
||||
SharedLockableCtx m_ctx;
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user