From 4db092437caa4519343322e110d665fd97307462 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Tue, 22 Sep 2020 18:22:34 +0200 Subject: [PATCH] Add support for custom allocator tracking to client. --- Tracy.hpp | 30 ++++++++++++++ client/TracyProfiler.cpp | 4 ++ client/TracyProfiler.hpp | 87 +++++++++++++++++++++++++++++++++++++++- common/TracyProtocol.hpp | 2 +- common/TracyQueue.hpp | 16 ++++++++ 5 files changed, 136 insertions(+), 3 deletions(-) diff --git a/Tracy.hpp b/Tracy.hpp index e9071e8e..34e8736a 100644 --- a/Tracy.hpp +++ b/Tracy.hpp @@ -56,6 +56,11 @@ #define TracySecureAlloc(x,y) #define TracySecureFree(x) +#define TracyAllocN(x,y,z) +#define TracyFreeN(x,y) +#define TracySecureAllocN(x,y,z) +#define TracySecureFreeN(x,y) + #define ZoneNamedS(x,y,z) #define ZoneNamedNS(x,y,z,w) #define ZoneNamedCS(x,y,z,w) @@ -74,6 +79,11 @@ #define TracySecureAllocS(x,y,z) #define TracySecureFreeS(x,y) +#define TracyAllocNS(x,y,z,w) +#define TracyFreeNS(x,y,z) +#define TracySecureAllocNS(x,y,z,w) +#define TracySecureFreeNS(x,y,z) + #define TracyMessageS(x,y,z) #define TracyMessageLS(x,y) #define TracyMessageCS(x,y,z,w) @@ -152,6 +162,11 @@ # define TracyFree( ptr ) tracy::Profiler::MemFreeCallstack( ptr, TRACY_CALLSTACK, false ); # define TracySecureAlloc( ptr, size ) tracy::Profiler::MemAllocCallstack( ptr, size, TRACY_CALLSTACK, true ); # define TracySecureFree( ptr ) tracy::Profiler::MemFreeCallstack( ptr, TRACY_CALLSTACK, true ); + +# define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, false, name ); +# define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, false, name ); +# define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, true, name ); +# define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, true, name ); #else # define TracyMessage( txt, size ) tracy::Profiler::Message( txt, size, 0 ); # define TracyMessageL( txt ) tracy::Profiler::Message( txt, 0 ); @@ -162,6 +177,11 @@ # define TracyFree( ptr ) tracy::Profiler::MemFree( ptr, false ); # define TracySecureAlloc( ptr, size ) tracy::Profiler::MemAlloc( ptr, size, true ); # define TracySecureFree( ptr ) tracy::Profiler::MemFree( ptr, true ); + +# define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, false, name ); +# define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, false, name ); +# define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, true, name ); +# define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, true, name ); #endif #ifdef TRACY_HAS_CALLSTACK @@ -183,6 +203,11 @@ # define TracySecureAllocS( ptr, size, depth ) tracy::Profiler::MemAllocCallstack( ptr, size, depth, true ); # define TracySecureFreeS( ptr, depth ) tracy::Profiler::MemFreeCallstack( ptr, depth, true ); +# define TracyAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, false, name ); +# define TracyFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, false, name ); +# define TracySecureAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, true, name ); +# define TracySecureFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, true, name ); + # define TracyMessageS( txt, size, depth ) tracy::Profiler::Message( txt, size, depth ); # define TracyMessageLS( txt, depth ) tracy::Profiler::Message( txt, depth ); # define TracyMessageCS( txt, size, color, depth ) tracy::Profiler::MessageColor( txt, size, color, depth ); @@ -206,6 +231,11 @@ # define TracySecureAllocS( ptr, size, depth ) TracySecureAlloc( ptr, size ) # define TracySecureFreeS( ptr, depth ) TracySecureFree( ptr ) +# define TracyAllocNS( ptr, size, depth, name ) TracyAlloc( ptr, size, name ) +# define TracyFreeNS( ptr, depth, name ) TracyFree( ptr, name ) +# define TracySecureAllocNS( ptr, size, depth, name ) TracySecureAlloc( ptr, size, name ) +# define TracySecureFreeNS( ptr, depth, name ) TracySecureFree( ptr, name ) + # define TracyMessageS( txt, size, depth ) TracyMessage( txt, size ) # define TracyMessageLS( txt, depth ) TracyMessageL( txt ) # define TracyMessageCS( txt, size, color, depth ) TracyMessageC( txt, size, color ) diff --git a/client/TracyProfiler.cpp b/client/TracyProfiler.cpp index f5c65274..af72b270 100644 --- a/client/TracyProfiler.cpp +++ b/client/TracyProfiler.cpp @@ -2160,7 +2160,9 @@ Profiler::DequeueStatus Profiler::DequeueSerial() break; } case QueueType::MemAlloc: + case QueueType::MemAllocNamed: case QueueType::MemAllocCallstack: + case QueueType::MemAllocCallstackNamed: { int64_t t = MemRead( &item->memAlloc.time ); int64_t dt = t - refSerial; @@ -2169,7 +2171,9 @@ Profiler::DequeueStatus Profiler::DequeueSerial() break; } case QueueType::MemFree: + case QueueType::MemFreeNamed: case QueueType::MemFreeCallstack: + case QueueType::MemFreeCallstackNamed: { int64_t t = MemRead( &item->memFree.time ); int64_t dt = t - refSerial; diff --git a/client/TracyProfiler.hpp b/client/TracyProfiler.hpp index bf925ae2..d9ccd4cb 100644 --- a/client/TracyProfiler.hpp +++ b/client/TracyProfiler.hpp @@ -431,6 +431,80 @@ public: #endif } + static tracy_force_inline void MemAllocNamed( const void* ptr, size_t size, bool secure, const char* name ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + const auto thread = GetThreadHandle(); + + GetProfiler().m_serialLock.lock(); + SendMemName( name ); + SendMemAlloc( QueueType::MemAllocNamed, thread, ptr, size ); + GetProfiler().m_serialLock.unlock(); + } + + static tracy_force_inline void MemFreeNamed( const void* ptr, bool secure, const char* name ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + const auto thread = GetThreadHandle(); + + GetProfiler().m_serialLock.lock(); + SendMemName( name ); + SendMemFree( QueueType::MemFreeNamed, thread, ptr ); + GetProfiler().m_serialLock.unlock(); + } + + static tracy_force_inline void MemAllocCallstackNamed( const void* ptr, size_t size, int depth, bool secure, const char* name ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_HAS_CALLSTACK + auto& profiler = GetProfiler(); +# ifdef TRACY_ON_DEMAND + if( !profiler.IsConnected() ) return; +# endif + const auto thread = GetThreadHandle(); + + InitRPMallocThread(); + auto callstack = Callstack( depth ); + + profiler.m_serialLock.lock(); + SendMemName( name ); + SendMemAlloc( QueueType::MemAllocCallstackNamed, thread, ptr, size ); + SendCallstackMemory( callstack ); + profiler.m_serialLock.unlock(); +#else + MemAlloc( ptr, size, secure ); +#endif + } + + static tracy_force_inline void MemFreeCallstackNamed( const void* ptr, int depth, bool secure, const char* name ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_HAS_CALLSTACK + auto& profiler = GetProfiler(); +# ifdef TRACY_ON_DEMAND + if( !profiler.IsConnected() ) return; +# endif + const auto thread = GetThreadHandle(); + + InitRPMallocThread(); + auto callstack = Callstack( depth ); + + profiler.m_serialLock.lock(); + SendMemName( name ); + SendMemFree( QueueType::MemFreeCallstackNamed, thread, ptr ); + SendCallstackMemory( callstack ); + profiler.m_serialLock.unlock(); +#else + MemFree( ptr, secure ); +#endif + } + static tracy_force_inline void SendCallstack( int depth ) { #ifdef TRACY_HAS_CALLSTACK @@ -610,7 +684,7 @@ private: static tracy_force_inline void SendMemAlloc( QueueType type, const uint64_t thread, const void* ptr, size_t size ) { - assert( type == QueueType::MemAlloc || type == QueueType::MemAllocCallstack ); + assert( type == QueueType::MemAlloc || type == QueueType::MemAllocCallstack || type == QueueType::MemAllocNamed || type == QueueType::MemAllocCallstackNamed ); auto item = GetProfiler().m_serialQueue.prepare_next(); MemWrite( &item->hdr.type, type ); @@ -633,7 +707,7 @@ private: static tracy_force_inline void SendMemFree( QueueType type, const uint64_t thread, const void* ptr ) { - assert( type == QueueType::MemFree || type == QueueType::MemFreeCallstack ); + assert( type == QueueType::MemFree || type == QueueType::MemFreeCallstack || type == QueueType::MemFreeNamed || type == QueueType::MemFreeCallstackNamed ); auto item = GetProfiler().m_serialQueue.prepare_next(); MemWrite( &item->hdr.type, type ); @@ -643,6 +717,15 @@ private: GetProfiler().m_serialQueue.commit_next(); } + static tracy_force_inline void SendMemName( const char* name ) + { + assert( name ); + auto item = GetProfiler().m_serialQueue.prepare_next(); + MemWrite( &item->hdr.type, QueueType::MemNamePayload ); + MemWrite( &item->memName.name, (uint64_t)name ); + GetProfiler().m_serialQueue.commit_next(); + } + #if ( defined _WIN32 || defined __CYGWIN__ ) && defined TRACY_TIMER_QPC static int64_t GetTimeQpc(); #endif diff --git a/common/TracyProtocol.hpp b/common/TracyProtocol.hpp index 7bb19835..60a69224 100644 --- a/common/TracyProtocol.hpp +++ b/common/TracyProtocol.hpp @@ -9,7 +9,7 @@ namespace tracy constexpr unsigned Lz4CompressBound( unsigned isize ) { return isize + ( isize / 255 ) + 16; } -enum : uint32_t { ProtocolVersion = 40 }; +enum : uint32_t { ProtocolVersion = 41 }; enum : uint16_t { BroadcastVersion = 2 }; using lz4sz_t = uint32_t; diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index 3523773a..5063cf59 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -33,9 +33,13 @@ enum class QueueType : uint8_t LockSharedRelease, LockName, MemAlloc, + MemAllocNamed, MemFree, + MemFreeNamed, MemAllocCallstack, + MemAllocCallstackNamed, MemFreeCallstack, + MemFreeCallstackNamed, GpuZoneBegin, GpuZoneBeginCallstack, GpuZoneEnd, @@ -78,6 +82,7 @@ enum class QueueType : uint8_t CpuTopology, SingleStringData, SecondStringData, + MemNamePayload, StringData, ThreadName, PlotName, @@ -336,6 +341,11 @@ struct QueueGpuCalibration uint8_t context; }; +struct QueueMemNamePayload +{ + uint64_t name; +}; + struct QueueMemAlloc { int64_t time; @@ -508,6 +518,7 @@ struct QueueItem QueueGpuCalibration gpuCalibration; QueueMemAlloc memAlloc; QueueMemFree memFree; + QueueMemNamePayload memName; QueueCallstackFat callstackFat; QueueCallstackAllocFat callstackAllocFat; QueueCallstackSample callstackSample; @@ -557,9 +568,13 @@ static constexpr size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueLockRelease ), // shared sizeof( QueueHeader ) + sizeof( QueueLockName ), sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), + sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // named sizeof( QueueHeader ) + sizeof( QueueMemFree ), + sizeof( QueueHeader ) + sizeof( QueueMemFree ), // named sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // callstack + sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // callstack, named sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack + sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack, named sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // callstack sizeof( QueueHeader ) + sizeof( QueueGpuZoneEnd ), @@ -603,6 +618,7 @@ static constexpr size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueCpuTopology ), sizeof( QueueHeader ), // single string data sizeof( QueueHeader ), // second string data + sizeof( QueueHeader ) + sizeof( QueueMemNamePayload ), // keep all QueueStringTransfer below sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // string data sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // thread name