1
0
mirror of https://github.com/wolfpld/tracy synced 2025-04-29 12:23:53 +00:00

Add non-C++ lock API

This commit is contained in:
Matej Mulej 2024-03-11 21:01:25 +01:00 committed by GitHub
parent 1ddecd4b99
commit 92511c9742
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -4505,6 +4505,175 @@ TRACY_API void ___tracy_emit_gpu_time_sync_serial( const struct ___tracy_gpu_tim
tracy::Profiler::QueueSerialFinish();
}
struct __tracy_lockable_context_data
{
uint32_t m_id;
#ifdef TRACY_ON_DEMAND
std::atomic<uint32_t> m_lockCount;
std::atomic<bool> m_active;
#endif
};
TRACY_API struct __tracy_lockable_context_data* ___tracy_announce_lockable_ctx(const struct ___tracy_source_location_data* srcloc )
{
struct __tracy_lockable_context_data *lockdata = (__tracy_lockable_context_data*)tracy::tracy_malloc( sizeof( __tracy_lockable_context_data ) );
lockdata->m_id =tracy:: GetLockCounter().fetch_add( 1, std::memory_order_relaxed );
#ifdef TRACY_ON_DEMAND
new(&lockdata->m_lockCount) std::atomic<uint32_t>( 0 );
new(&lockdata->m_active) std::atomic<bool>( false );
#endif
assert( lockdata->m_id != (std::numeric_limits<uint32_t>::max)() );
auto item = tracy::Profiler::QueueSerial();
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockAnnounce );
tracy::MemWrite( &item->lockAnnounce.id, lockdata->m_id );
tracy::MemWrite( &item->lockAnnounce.time, tracy::Profiler::GetTime() );
tracy::MemWrite( &item->lockAnnounce.lckloc, (uint64_t)srcloc );
tracy::MemWrite( &item->lockAnnounce.type, tracy::LockType::Lockable );
#ifdef TRACY_ON_DEMAND
tracy::GetProfiler().DeferItem( *item );
#endif
tracy::Profiler::QueueSerialFinish();
return lockdata;
}
TRACY_API void ___tracy_terminate_lockable_ctx( struct __tracy_lockable_context_data* lockdata)
{
auto item = tracy::Profiler::QueueSerial();
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockTerminate );
tracy::MemWrite( &item->lockTerminate.id, lockdata->m_id );
tracy::MemWrite( &item->lockTerminate.time, tracy::Profiler::GetTime() );
#ifdef TRACY_ON_DEMAND
tracy::GetProfiler().DeferItem( *item );
#endif
tracy::Profiler::QueueSerialFinish();
#ifdef TRACY_ON_DEMAND
lockdata->m_lockCount.~atomic();
lockdata->m_active.~atomic();
#endif
tracy::tracy_free((void*)lockdata);
}
TRACY_API int ___tracy_before_lock_lockable_ctx( struct __tracy_lockable_context_data* lockdata)
{
#ifdef TRACY_ON_DEMAND
bool queue = false;
const auto locks = lockdata->m_lockCount.fetch_add( 1, std::memory_order_relaxed );
const auto active = lockdata->m_active.load( std::memory_order_relaxed );
if( locks == 0 || active )
{
const bool connected = tracy::GetProfiler().IsConnected();
if( active != connected ) lockdata->m_active.store( connected, std::memory_order_relaxed );
if( connected ) queue = true;
}
if( !queue ) return false;
#endif
auto item = tracy::Profiler::QueueSerial();
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockWait );
tracy::MemWrite( &item->lockWait.thread, tracy::GetThreadHandle() );
tracy::MemWrite( &item->lockWait.id, lockdata->m_id );
tracy::MemWrite( &item->lockWait.time, tracy::Profiler::GetTime() );
tracy::Profiler::QueueSerialFinish();
return true;
}
TRACY_API void ___tracy_after_lock_lockable_ctx( struct __tracy_lockable_context_data* lockdata)
{
auto item = tracy::Profiler::QueueSerial();
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockObtain );
tracy::MemWrite( &item->lockObtain.thread, tracy::GetThreadHandle() );
tracy::MemWrite( &item->lockObtain.id, lockdata->m_id );
tracy::MemWrite( &item->lockObtain.time, tracy::Profiler::GetTime() );
tracy::Profiler::QueueSerialFinish();
}
TRACY_API void ___tracy_after_unlock_lockable_ctx( struct __tracy_lockable_context_data* lockdata)
{
#ifdef TRACY_ON_DEMAND
lockdata->m_lockCount.fetch_sub( 1, std::memory_order_relaxed );
if( !lockdata->m_active.load( std::memory_order_relaxed ) ) return;
if( !tracy::GetProfiler().IsConnected() )
{
lockdata->m_active.store( false, std::memory_order_relaxed );
return;
}
#endif
auto item = tracy::Profiler::QueueSerial();
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockRelease );
tracy::MemWrite( &item->lockRelease.id, lockdata->m_id );
tracy::MemWrite( &item->lockRelease.time, tracy::Profiler::GetTime() );
tracy::Profiler::QueueSerialFinish();
}
TRACY_API void ___tracy_after_try_lock_lockable_ctx( struct __tracy_lockable_context_data* lockdata, int acquired )
{
#ifdef TRACY_ON_DEMAND
if( !acquired ) return;
bool queue = false;
const auto locks = lockdata->m_lockCount.fetch_add( 1, std::memory_order_relaxed );
const auto active = lockdata->m_active.load( std::memory_order_relaxed );
if( locks == 0 || active )
{
const bool connected = tracy::GetProfiler().IsConnected();
if( active != connected ) lockdata->m_active.store( connected, std::memory_order_relaxed );
if( connected ) queue = true;
}
if( !queue ) return;
#endif
if( acquired )
{
auto item = tracy::Profiler::QueueSerial();
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockObtain );
tracy::MemWrite( &item->lockObtain.thread, tracy::GetThreadHandle() );
tracy::MemWrite( &item->lockObtain.id, lockdata->m_id );
tracy::MemWrite( &item->lockObtain.time, tracy::Profiler::GetTime() );
tracy::Profiler::QueueSerialFinish();
}
}
TRACY_API void ___tracy_mark_lockable_ctx( struct __tracy_lockable_context_data* lockdata, const struct ___tracy_source_location_data* srcloc )
{
#ifdef TRACY_ON_DEMAND
const auto active = lockdata->m_active.load( std::memory_order_relaxed );
if( !active ) return;
const auto connected = tracy::GetProfiler().IsConnected();
if( !connected )
{
if( active ) lockdata->m_active.store( false, std::memory_order_relaxed );
return;
}
#endif
auto item = tracy::Profiler::QueueSerial();
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockMark );
tracy::MemWrite( &item->lockMark.thread, tracy::GetThreadHandle() );
tracy::MemWrite( &item->lockMark.id, lockdata->m_id );
tracy::MemWrite( &item->lockMark.srcloc, (uint64_t)srcloc );
tracy::Profiler::QueueSerialFinish();
}
TRACY_API void ___tracy_custom_name_lockable_ctx( struct __tracy_lockable_context_data* lockdata, const char* name, size_t nameSz )
{
assert( nameSz < (std::numeric_limits<uint16_t>::max)() );
auto ptr = (char*)tracy::tracy_malloc( nameSz );
memcpy( ptr, name, nameSz );
auto item = tracy::Profiler::QueueSerial();
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockName );
tracy::MemWrite( &item->lockNameFat.id, lockdata->m_id );
tracy::MemWrite( &item->lockNameFat.name, (uint64_t)ptr );
tracy::MemWrite( &item->lockNameFat.size, (uint16_t)nameSz );
#ifdef TRACY_ON_DEMAND
tracy::GetProfiler().DeferItem( *item );
#endif
tracy::Profiler::QueueSerialFinish();
}
TRACY_API int ___tracy_connected( void )
{
return tracy::GetProfiler().IsConnected();