mirror of
https://github.com/wolfpld/tracy.git
synced 2026-10-12 11:55:22 +00:00
Merge pull request #1395 from MaximeCoutantSonos/master
Add support for Shared Locks in the C API
This commit is contained in:
@@ -2273,6 +2273,31 @@ TracyCLockAfterUnlock(tracy_lock_ctx);
|
||||
|
||||
You can optionally mark the location of where the lock is held by using the \texttt{TracyCLockMark} macro, this should be done after acquiring the lock.
|
||||
|
||||
Similarly, you can use the following macros to mark a shared lock using the C API:
|
||||
\begin{itemize}
|
||||
\item \texttt{TracyCSharedLockAnnounce(lock\_ctx)}
|
||||
\item \texttt{TracyCSharedLockTerminate(lock\_ctx)}
|
||||
\item \texttt{TracyCSharedLockBeforeLock(lock\_ctx)}
|
||||
\item \texttt{TracyCSharedLockAfterLock(lock\_ctx)}
|
||||
\item \texttt{TracyCSharedLockAfterUnlock(lock\_ctx)}
|
||||
\item \texttt{TracyCSharedLockAfterTryLock(lock\_ctx, acquired)}
|
||||
\item \texttt{TracyCSharedLockBeforeSharedLock(lock\_ctx)}
|
||||
\item \texttt{TracyCSharedLockAfterSharedLock(lock\_ctx)}
|
||||
\item \texttt{TracyCSharedLockAfterSharedUnlock(lock\_ctx)}
|
||||
\item \texttt{TracyCSharedLockAfterTrySharedLock(lock\_ctx, acquired)}
|
||||
\item \texttt{TracyCSharedLockMark(lock\_ctx)}
|
||||
\item \texttt{TracyCSharedLockCustomName(lock\_ctx, name, size)}
|
||||
\end{itemize}
|
||||
|
||||
A shared lock context has to be defined next to the shared lock that it will be marking:
|
||||
\begin{lstlisting}
|
||||
TracyCSharedLockCtx tracy_shared_lock_ctx;
|
||||
HANDLE shared_lock;
|
||||
\end{lstlisting}
|
||||
|
||||
The same rules apply to shared locks as to regular locks, but you need to use the shared lock macros instead.
|
||||
Lock implementations in classes \texttt{Lockable} and \texttt{SharedLockable} show how to properly perform context handling.
|
||||
|
||||
\subsubsection{Memory profiling}
|
||||
\label{cmemoryprofiling}
|
||||
|
||||
|
||||
@@ -5167,6 +5167,164 @@ TRACY_API void ___tracy_custom_name_lockable_ctx( struct __tracy_lockable_contex
|
||||
tracy::Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
struct __tracy_shared_lockable_context_data {
|
||||
struct __tracy_lockable_context_data m_base;
|
||||
};
|
||||
|
||||
TRACY_API struct __tracy_shared_lockable_context_data* ___tracy_announce_shared_lockable_ctx( const struct ___tracy_source_location_data* srcloc )
|
||||
{
|
||||
struct __tracy_shared_lockable_context_data *lockdata = (__tracy_shared_lockable_context_data*)tracy::tracy_malloc( sizeof( __tracy_shared_lockable_context_data ) );
|
||||
lockdata->m_base.m_id = tracy::GetLockCounter().fetch_add( 1, std::memory_order_relaxed );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
new(&lockdata->m_base.m_lockCount) std::atomic<uint32_t>( 0 );
|
||||
new(&lockdata->m_base.m_active) std::atomic<bool>( false );
|
||||
#endif
|
||||
assert( lockdata->m_base.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_base.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::SharedLockable );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
tracy::GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
tracy::Profiler::QueueSerialFinish();
|
||||
|
||||
return lockdata;
|
||||
}
|
||||
|
||||
TRACY_API void ___tracy_terminate_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata )
|
||||
{
|
||||
auto item = tracy::Profiler::QueueSerial();
|
||||
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockTerminate );
|
||||
tracy::MemWrite( &item->lockTerminate.id, lockdata->m_base.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_base.m_lockCount.~atomic();
|
||||
lockdata->m_base.m_active.~atomic();
|
||||
#endif
|
||||
tracy::tracy_free((void*)lockdata);
|
||||
}
|
||||
|
||||
TRACY_API int32_t ___tracy_before_lock_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata )
|
||||
{
|
||||
return ___tracy_before_lock_lockable_ctx( &lockdata->m_base );
|
||||
}
|
||||
|
||||
TRACY_API void ___tracy_after_lock_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata )
|
||||
{
|
||||
___tracy_after_lock_lockable_ctx( &lockdata->m_base );
|
||||
}
|
||||
|
||||
TRACY_API void ___tracy_after_unlock_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata )
|
||||
{
|
||||
___tracy_after_unlock_lockable_ctx( &lockdata->m_base );
|
||||
}
|
||||
|
||||
TRACY_API void ___tracy_after_try_lock_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata, int32_t acquired )
|
||||
{
|
||||
___tracy_after_try_lock_lockable_ctx( &lockdata->m_base, acquired );
|
||||
}
|
||||
|
||||
TRACY_API int32_t ___tracy_before_lock_shared_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
bool queue = false;
|
||||
const auto locks = lockdata->m_base.m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
const auto active = lockdata->m_base.m_active.load( std::memory_order_relaxed );
|
||||
if( locks == 0 || active )
|
||||
{
|
||||
const bool connected = tracy::GetProfiler().IsConnected();
|
||||
if( active != connected ) lockdata->m_base.m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue ) return static_cast<int32_t>(false);
|
||||
#endif
|
||||
|
||||
auto item = tracy::Profiler::QueueSerial();
|
||||
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockSharedWait );
|
||||
tracy::MemWrite( &item->lockWait.thread, tracy::GetThreadHandle() );
|
||||
tracy::MemWrite( &item->lockWait.id, lockdata->m_base.m_id );
|
||||
tracy::MemWrite( &item->lockWait.time, tracy::Profiler::GetTime() );
|
||||
tracy::Profiler::QueueSerialFinish();
|
||||
return static_cast<int32_t>(true);
|
||||
}
|
||||
|
||||
TRACY_API void ___tracy_after_locked_shared_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata )
|
||||
{
|
||||
auto item = tracy::Profiler::QueueSerial();
|
||||
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockSharedObtain );
|
||||
tracy::MemWrite( &item->lockObtain.thread, tracy::GetThreadHandle() );
|
||||
tracy::MemWrite( &item->lockObtain.id, lockdata->m_base.m_id );
|
||||
tracy::MemWrite( &item->lockObtain.time, tracy::Profiler::GetTime() );
|
||||
tracy::Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
TRACY_API void ___tracy_after_unlock_shared_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
lockdata->m_base.m_lockCount.fetch_sub( 1, std::memory_order_relaxed );
|
||||
if( !lockdata->m_base.m_active.load( std::memory_order_relaxed ) ) return;
|
||||
if( !tracy::GetProfiler().IsConnected() )
|
||||
{
|
||||
lockdata->m_base.m_active.store( false, std::memory_order_relaxed );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto item = tracy::Profiler::QueueSerial();
|
||||
tracy::MemWrite( &item->hdr.type, tracy::QueueType::LockSharedRelease );
|
||||
tracy::MemWrite( &item->lockReleaseShared.thread, tracy::GetThreadHandle() );
|
||||
tracy::MemWrite( &item->lockReleaseShared.id, lockdata->m_base.m_id );
|
||||
tracy::MemWrite( &item->lockReleaseShared.time, tracy::Profiler::GetTime() );
|
||||
tracy::Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
TRACY_API void ___tracy_after_try_lock_shared_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata, int32_t acquired )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !acquired ) return;
|
||||
|
||||
bool queue = false;
|
||||
const auto locks = lockdata->m_base.m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
const auto active = lockdata->m_base.m_active.load( std::memory_order_relaxed );
|
||||
if( locks == 0 || active )
|
||||
{
|
||||
const bool connected = tracy::GetProfiler().IsConnected();
|
||||
if( active != connected ) lockdata->m_base.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_base.m_id );
|
||||
tracy::MemWrite( &item->lockObtain.time, tracy::Profiler::GetTime() );
|
||||
tracy::Profiler::QueueSerialFinish();
|
||||
}
|
||||
}
|
||||
|
||||
TRACY_API void ___tracy_mark_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata, const struct ___tracy_source_location_data* srcloc )
|
||||
{
|
||||
___tracy_mark_lockable_ctx( &lockdata->m_base, srcloc );
|
||||
}
|
||||
|
||||
TRACY_API void ___tracy_custom_name_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata, const char* name, size_t nameSz )
|
||||
{
|
||||
___tracy_custom_name_lockable_ctx( &lockdata->m_base, name, nameSz );
|
||||
}
|
||||
|
||||
TRACY_API int32_t ___tracy_connected( void )
|
||||
{
|
||||
return static_cast<int32_t>( tracy::GetProfiler().IsConnected() );
|
||||
|
||||
@@ -49,6 +49,7 @@ TRACY_API void ___tracy_set_thread_name( const char* name );
|
||||
typedef const void* TracyCZoneCtx;
|
||||
|
||||
typedef const void* TracyCLockCtx;
|
||||
typedef const void* TracyCSharedLockCtx;
|
||||
|
||||
#define TracyCZone(c,x)
|
||||
#define TracyCZoneN(c,x,y)
|
||||
@@ -121,6 +122,20 @@ typedef const void* TracyCLockCtx;
|
||||
#define TracyCLockMark(l)
|
||||
#define TracyCLockCustomName(l,x,y)
|
||||
|
||||
#define TracyCSharedLockCtx(l)
|
||||
#define TracyCSharedLockAnnonce(l)
|
||||
#define TracyCSharedLockTerminate(l)
|
||||
#define TracyCSharedLockBeforeLock(l)
|
||||
#define TracyCSharedLockAfterLock(l)
|
||||
#define TracyCSharedLockAfterUnlock(l)
|
||||
#define TracyCSharedLockAfterTryLock(l,x)
|
||||
#define TracyCSharedLockBeforeSharedLock(l)
|
||||
#define TracyCSharedLockAfterSharedLock(l)
|
||||
#define TracyCSharedLockAfterSharedUnlock(l)
|
||||
#define TracyCSharedLockAfterTrySharedLock(l,x)
|
||||
#define TracyCSharedLockMark(l)
|
||||
#define TracyCSharedLockCustomName(l,x,y)
|
||||
|
||||
#define TracyCIsConnected 0
|
||||
#define TracyCIsStarted 0
|
||||
|
||||
@@ -207,12 +222,14 @@ struct ___tracy_gpu_time_sync_data {
|
||||
};
|
||||
|
||||
struct __tracy_lockable_context_data;
|
||||
struct __tracy_shared_lockable_context_data;
|
||||
|
||||
// Some containers don't support storing const types.
|
||||
// This struct, as visible to user, is immutable, so treat it as if const was declared here.
|
||||
typedef /*const*/ struct ___tracy_c_zone_context TracyCZoneCtx;
|
||||
|
||||
typedef struct __tracy_lockable_context_data* TracyCLockCtx;
|
||||
typedef struct __tracy_shared_lockable_context_data* TracyCSharedLockCtx;
|
||||
|
||||
#ifdef TRACY_MANUAL_LIFETIME
|
||||
TRACY_API void ___tracy_startup_profiler(void);
|
||||
@@ -367,6 +384,20 @@ TRACY_API void ___tracy_after_try_lock_lockable_ctx( struct __tracy_lockable_con
|
||||
TRACY_API void ___tracy_mark_lockable_ctx( struct __tracy_lockable_context_data* lockdata, const struct ___tracy_source_location_data* srcloc );
|
||||
TRACY_API void ___tracy_custom_name_lockable_ctx( struct __tracy_lockable_context_data* lockdata, const char* name, size_t nameSz );
|
||||
|
||||
TRACY_API struct __tracy_shared_lockable_context_data* ___tracy_announce_shared_lockable_ctx( const struct ___tracy_source_location_data* srcloc );
|
||||
TRACY_API void ___tracy_terminate_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata );
|
||||
TRACY_API int32_t ___tracy_before_lock_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata );
|
||||
TRACY_API void ___tracy_after_lock_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata );
|
||||
TRACY_API void ___tracy_after_unlock_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata );
|
||||
TRACY_API void ___tracy_after_try_lock_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata, int32_t acquired );
|
||||
TRACY_API int32_t ___tracy_before_lock_shared_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata );
|
||||
TRACY_API void ___tracy_after_locked_shared_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata );
|
||||
TRACY_API void ___tracy_after_unlock_shared_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata );
|
||||
TRACY_API void ___tracy_after_try_lock_shared_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata, int32_t acquired );
|
||||
TRACY_API void ___tracy_mark_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata, const struct ___tracy_source_location_data* srcloc );
|
||||
TRACY_API void ___tracy_custom_name_shared_lockable_ctx( struct __tracy_shared_lockable_context_data* lockdata, const char* name, size_t nameSz );
|
||||
|
||||
|
||||
#define TracyCLockAnnounce( lock ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, 0 }; lock = ___tracy_announce_lockable_ctx( &TracyConcat(__tracy_source_location,TracyLine) );
|
||||
#define TracyCLockTerminate( lock ) ___tracy_terminate_lockable_ctx( lock );
|
||||
#define TracyCLockBeforeLock( lock ) ___tracy_before_lock_lockable_ctx( lock );
|
||||
@@ -376,6 +407,19 @@ TRACY_API void ___tracy_custom_name_lockable_ctx( struct __tracy_lockable_contex
|
||||
#define TracyCLockMark( lock ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, 0 }; ___tracy_mark_lockable_ctx( lock, &TracyConcat(__tracy_source_location,TracyLine) );
|
||||
#define TracyCLockCustomName( lock, name, nameSz ) ___tracy_custom_name_lockable_ctx( lock, name, nameSz );
|
||||
|
||||
#define TracyCSharedLockAnnounce( lock ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, 0 }; lock = ___tracy_announce_shared_lockable_ctx( &TracyConcat(__tracy_source_location,TracyLine) );
|
||||
#define TracyCSharedLockTerminate( lock ) ___tracy_terminate_shared_lockable_ctx( lock );
|
||||
#define TracyCSharedLockBeforeLock( lock ) ___tracy_before_lock_shared_lockable_ctx( lock );
|
||||
#define TracyCSharedLockAfterLock( lock ) ___tracy_after_lock_shared_lockable_ctx( lock );
|
||||
#define TracyCSharedLockAfterUnlock( lock ) ___tracy_after_unlock_shared_lockable_ctx( lock );
|
||||
#define TracyCSharedLockAfterTryLock( lock, acquired ) ___tracy_after_try_lock_shared_lockable_ctx( lock, acquired );
|
||||
#define TracyCSharedLockBeforeSharedLock( lock ) ___tracy_before_lock_shared_shared_lockable_ctx( lock );
|
||||
#define TracyCSharedLockAfterSharedLock( lock ) ___tracy_after_locked_shared_shared_lockable_ctx( lock );
|
||||
#define TracyCSharedLockAfterSharedUnlock( lock ) ___tracy_after_unlock_shared_shared_lockable_ctx( lock );
|
||||
#define TracyCSharedLockAfterTrySharedLock( lock, acquired ) ___tracy_after_try_lock_shared_shared_lockable_ctx( lock, acquired );
|
||||
#define TracyCSharedLockMark( lock ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, 0 }; ___tracy_mark_shared_lockable_ctx( lock, &TracyConcat(__tracy_source_location,TracyLine) );
|
||||
#define TracyCSharedLockCustomName( lock, name, nameSz ) ___tracy_custom_name_shared_lockable_ctx( lock, name, nameSz );
|
||||
|
||||
#define TracyCIsConnected ___tracy_connected()
|
||||
|
||||
TRACY_API int ___tracy_begin_sampling_profiling( void );
|
||||
|
||||
Reference in New Issue
Block a user