Skip to content

Commit 9d831f9

Browse files
committed
Say hello to TRACY_DEFAULT_MEMORY_PROFLER
Enables default memory profiler on supported platforms
1 parent 1ad2488 commit 9d831f9

14 files changed

Lines changed: 240 additions & 86 deletions

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ set_option(TRACY_SYMBOL_OFFLINE_RESOLVE "Instead of full runtime symbol resoluti
142142
set_option(TRACY_LIBBACKTRACE_ELF_DYNLOAD_SUPPORT "Enable libbacktrace to support dynamically loaded elfs in symbol resolution resolution after the first symbol resolve operation" OFF)
143143
set_option(TRACY_DEBUGINFOD "Enable debuginfod support" OFF)
144144
set_option(TRACY_IGNORE_MEMORY_FAULTS "Ignore instrumentation errors from memory free events that do not have a matching allocation" OFF)
145+
set_option(TRACY_DEFAULT_MEMORY_PROFLER "Enable default memory profiler on supported platforms" OFF)
145146

146147
# advanced
147148
set_option(TRACY_VERBOSE "[advanced] Verbose output from the profiler" OFF)

cmake/server.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
set(TRACY_COMMON_DIR ${CMAKE_CURRENT_LIST_DIR}/../public/common)
22

33
set(TRACY_COMMON_SOURCES
4+
../client/TracyAlloc.cpp
45
tracy_lz4.cpp
56
tracy_lz4hc.cpp
67
TracySocket.cpp

public/TracyClient.cpp

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,39 @@
1919
# pragma warning(push, 0)
2020
#endif
2121

22-
#include "common/tracy_lz4.cpp"
23-
#include "client/TracyProfiler.cpp"
24-
#include "client/TracyCallstack.cpp"
25-
#include "client/TracySysPower.cpp"
26-
#include "client/TracySysTime.cpp"
27-
#include "client/TracySysTrace.cpp"
28-
#include "common/TracySocket.cpp"
29-
#include "client/tracy_rpmalloc.cpp"
30-
#include "client/TracyDxt1.cpp"
31-
#include "client/TracyAlloc.cpp"
32-
#include "client/TracyOverride.cpp"
33-
#include "client/TracyKCore.cpp"
22+
# include "client/TracyAlloc.cpp"
23+
# include "client/TracyCallstack.cpp"
24+
# include "client/TracyDxt1.cpp"
25+
# include "client/TracyKCore.cpp"
26+
# include "client/TracyOverride.cpp"
27+
# include "client/TracyProfiler.cpp"
28+
# include "client/TracySysPower.cpp"
29+
# include "client/TracySysTime.cpp"
30+
# include "client/TracySysTrace.cpp"
31+
# include "client/tracy_rpmalloc.cpp"
32+
# include "common/TracySocket.cpp"
33+
# include "common/tracy_lz4.cpp"
3434

35-
#ifdef TRACY_ROCPROF
36-
# include "client/TracyRocprof.cpp"
37-
#endif
38-
#ifdef _MSC_VER
39-
# pragma comment(lib, "ws2_32.lib")
40-
# pragma comment(lib, "advapi32.lib")
41-
# pragma comment(lib, "user32.lib")
42-
# pragma warning(pop)
43-
#endif
35+
# ifdef TRACY_ROCPROF
36+
# include "client/TracyRocprof.cpp"
37+
# endif
38+
# ifdef _MSC_VER
39+
# pragma comment( lib, "ws2_32.lib" )
40+
# pragma comment( lib, "advapi32.lib" )
41+
# pragma comment( lib, "user32.lib" )
42+
# pragma warning( pop )
43+
# endif
4444

45+
# ifdef TRACY_ENABLE_DEFAULT_MEMORY_PROFLER
46+
class BlockMemoryProfileHooks
47+
{
48+
public:
49+
~BlockMemoryProfileHooks()
50+
{
51+
++tracy::DirectAlloc::s_direct; // at exit the application will try to free the static objects memory
52+
// which will be traced by tracy::Profiler::MemFreeCallstack which needs those static objects
53+
}
54+
};
55+
static BlockMemoryProfileHooks __blockMemoryProfileHooks;
56+
# endif
4557
#endif

public/client/TracyAlloc.cpp

Lines changed: 150 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,109 @@
11
#include "../common/TracyAlloc.hpp"
22

3+
#if defined( TRACY_DEFAULT_MEMORY_PROFLER )/* && defined( TRACY_ON_DEMAND )*/
4+
# if __has_include( <dlfcn.h>)
5+
# include "../client/TracyProfiler.hpp"
6+
# include <dlfcn.h>
7+
# define TRACY_ENABLE_DEFAULT_MEMORY_PROFLER
8+
# endif
9+
#endif
10+
11+
#ifndef TRACY_ENABLE_DEFAULT_MEMORY_PROFLER
12+
namespace
13+
{
14+
auto _malloc = &malloc;
15+
auto _free = &free;
16+
auto _calloc = &calloc;
17+
auto _realloc = &realloc;
18+
} // namespace {
19+
#else
20+
namespace
21+
{
22+
23+
inline void* _malloc( size_t size )
24+
{
25+
static auto malloc_ = reinterpret_cast<void* (*)( size_t )>( dlsym( RTLD_NEXT, "malloc" ) );
26+
return malloc_( size );
27+
}
28+
inline void _free( void* ptr )
29+
{
30+
static auto free_ = reinterpret_cast<void ( * )( void* )>( dlsym( RTLD_NEXT, "free" ) );
31+
free_( ptr );
32+
}
33+
inline void* _calloc( size_t nmemb, size_t size )
34+
{
35+
static auto calloc_ = reinterpret_cast<void* (*)( size_t, size_t )>( dlsym( RTLD_NEXT, "calloc" ) );
36+
return calloc_( nmemb, size );
37+
}
38+
39+
inline void* _realloc( void* ptr, size_t size )
40+
{
41+
static auto realloc_ = reinterpret_cast<void* (*)( void*, size_t )>( dlsym( RTLD_NEXT, "realloc" ) );
42+
return realloc_( ptr, size );
43+
}
44+
45+
} // namespace {
46+
47+
extern "C"
48+
{
49+
void* malloc( size_t size )
50+
{
51+
if( tracy::DirectAlloc::s_direct )
52+
return _malloc( size );
53+
tracy::DirectAlloc locker;
54+
auto _ptr = _malloc( size );
55+
tracy::Profiler::MemAllocCallstack( _ptr, size, 50, false );
56+
return _ptr;
57+
}
58+
59+
void free( void* ptr )
60+
{
61+
if( tracy::DirectAlloc::s_direct )
62+
return _free( ptr );
63+
tracy::DirectAlloc locker;
64+
if( ptr )
65+
tracy::Profiler::MemFreeCallstack( ptr, 50, false );
66+
_free( ptr );
67+
}
68+
69+
void* calloc( size_t nmemb, size_t size )
70+
{
71+
if( tracy::DirectAlloc::s_direct )
72+
return _calloc( nmemb, size );
73+
tracy::DirectAlloc locker;
74+
auto _ptr = _calloc( nmemb, size );
75+
tracy::Profiler::MemAllocCallstack( _ptr, nmemb * size, 50, false );
76+
return _ptr;
77+
}
78+
79+
void* realloc( void* ptr, size_t size )
80+
{
81+
if( tracy::DirectAlloc::s_direct )
82+
return _realloc( ptr, size );
83+
tracy::DirectAlloc locker;
84+
if( ptr )
85+
tracy::Profiler::MemFreeCallstack( ptr, 50, false );
86+
auto _ptr = _realloc( ptr, size );
87+
tracy::Profiler::MemAllocCallstack( _ptr, size, 50, false );
88+
return _ptr;
89+
}
90+
} // extern "C" {
91+
#endif
92+
393
#ifdef TRACY_USE_RPMALLOC
494

5-
#include <atomic>
95+
# include <atomic>
696

7-
#include "../common/TracyForceInline.hpp"
8-
#include "../common/TracyYield.hpp"
97+
# include "../common/TracyForceInline.hpp"
98+
# include "../common/TracyYield.hpp"
99+
#endif
9100

10101
namespace tracy
11102
{
12103

104+
thread_local int DirectAlloc::s_direct = 0;
105+
106+
#ifdef TRACY_USE_RPMALLOC
13107
extern thread_local bool RpThreadInitDone;
14108
extern std::atomic<int> RpInitDone;
15109
extern std::atomic<int> RpInitLock;
@@ -20,7 +114,11 @@ tracy_no_inline static void InitRpmallocPlumbing()
20114
if( !done )
21115
{
22116
int expected = 0;
23-
while( !RpInitLock.compare_exchange_weak( expected, 1, std::memory_order_release, std::memory_order_relaxed ) ) { expected = 0; YieldThread(); }
117+
while( !RpInitLock.compare_exchange_weak( expected, 1, std::memory_order_release, std::memory_order_relaxed ) )
118+
{
119+
expected = 0;
120+
YieldThread();
121+
}
24122
const auto done = RpInitDone.load( std::memory_order_acquire );
25123
if( !done )
26124
{
@@ -37,7 +135,54 @@ TRACY_API void InitRpmalloc()
37135
{
38136
if( !RpThreadInitDone ) InitRpmallocPlumbing();
39137
}
138+
#endif
40139

140+
TRACY_API void* tracy_malloc( size_t size )
141+
{
142+
# ifdef TRACY_USE_RPMALLOC
143+
InitRpmalloc();
144+
return rpmalloc( size );
145+
# else
146+
return _malloc( size );
147+
# endif
41148
}
42149

43-
#endif
150+
TRACY_API void* tracy_malloc_fast( size_t size )
151+
{
152+
# ifdef TRACY_USE_RPMALLOC
153+
return rpmalloc( size );
154+
# else
155+
return _malloc( size );
156+
# endif
157+
}
158+
159+
TRACY_API void tracy_free( void* ptr )
160+
{
161+
# ifdef TRACY_USE_RPMALLOC
162+
InitRpmalloc();
163+
rpfree( ptr );
164+
# else
165+
_free( ptr );
166+
# endif
167+
}
168+
169+
TRACY_API void tracy_free_fast( void* ptr )
170+
{
171+
# ifdef TRACY_USE_RPMALLOC
172+
rpfree( ptr );
173+
# else
174+
_free( ptr );
175+
# endif
176+
}
177+
178+
TRACY_API void* tracy_realloc( void* ptr, size_t size )
179+
{
180+
# ifdef TRACY_USE_RPMALLOC
181+
InitRpmalloc();
182+
return rprealloc( ptr, size );
183+
# else
184+
return _realloc( ptr, size );
185+
# endif
186+
}
187+
188+
} // namespace tracy

public/client/TracyCallstack.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ extern "C" const char* ___tracy_demangle( const char* mangled )
104104
if( strlen( mangled ) > ___tracy_demangle_buffer_len ) return nullptr;
105105
int status;
106106
size_t len = ___tracy_demangle_buffer_len;
107+
tracy::DirectAlloc lock;
107108
return abi::__cxa_demangle( mangled, ___tracy_demangle_buffer, &len, &status );
108109
}
109110
#endif
@@ -865,6 +866,7 @@ size_t s_kernelSymCnt;
865866

866867
static void InitKernelSymbols()
867868
{
869+
tracy::DirectAlloc lock;
868870
FILE* f = fopen( "/proc/kallsyms", "rb" );
869871
if( !f ) return;
870872
tracy::FastVector<KernelSymbol> tmpSym( 512 * 1024 );

public/client/TracyCallstack.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ static tracy_force_inline void* Callstack( int32_t depth )
149149
assert( depth >= 1 );
150150

151151
auto trace = (uintptr_t*)tracy_malloc( ( 1 + (size_t)depth ) * sizeof( uintptr_t ) );
152-
152+
tracy::DirectAlloc lock;
153153
#ifdef TRACY_LIBUNWIND_BACKTRACE
154154
size_t num = unw_backtrace( (void**)(trace+1), depth );
155155
#else

public/client/TracyProfiler.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ struct MappingInfo {
171171
// vector is sorted by ascending address too.
172172
static std::vector<MappingInfo> ParseMappings()
173173
{
174+
tracy::DirectAlloc lock;
174175
std::vector<MappingInfo> result;
175176
FILE* file = fopen( "/proc/self/maps", "r" );
176177
if( !file ) return result;
@@ -513,6 +514,7 @@ static uint32_t GetHex( char*& ptr, int skip )
513514

514515
static const char* GetHostInfo()
515516
{
517+
tracy::DirectAlloc lock;
516518
static char buf[1024];
517519
auto ptr = buf;
518520
#if defined _WIN32
@@ -3889,7 +3891,8 @@ void Profiler::CalibrateDelay()
38893891

38903892
void Profiler::ReportTopology()
38913893
{
3892-
#ifndef TRACY_DELAYED_INIT
3894+
DirectAlloc lock;
3895+
# ifndef TRACY_DELAYED_INIT
38933896
struct CpuData
38943897
{
38953898
uint32_t package;
@@ -4183,6 +4186,7 @@ void Profiler::HandleSymbolCodeQuery( uint64_t symbol, uint32_t size )
41834186

41844187
void Profiler::HandleSourceCodeQuery( char* data, char* image, uint32_t id )
41854188
{
4189+
tracy::DirectAlloc lock;
41864190
bool ok = false;
41874191
FILE* f = fopen( data, "rb" );
41884192
if( f )

public/client/TracyProfiler.hpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -852,16 +852,28 @@ class Profiler
852852
enum class DequeueStatus { DataDequeued, ConnectionLost, QueueEmpty };
853853
enum class ThreadCtxStatus { Same, Changed, ConnectionLost };
854854

855-
static void LaunchWorker( void* ptr ) { ((Profiler*)ptr)->Worker(); }
855+
static void LaunchWorker( void* ptr )
856+
{
857+
tracy::DirectAlloc lock;
858+
( (Profiler*)ptr )->Worker();
859+
}
856860
void Worker();
857861

858862
#ifndef TRACY_NO_FRAME_IMAGE
859-
static void LaunchCompressWorker( void* ptr ) { ((Profiler*)ptr)->CompressWorker(); }
863+
static void LaunchCompressWorker( void* ptr )
864+
{
865+
tracy::DirectAlloc lock;
866+
( (Profiler*)ptr )->CompressWorker();
867+
}
860868
void CompressWorker();
861869
#endif
862870

863871
#ifdef TRACY_HAS_CALLSTACK
864-
static void LaunchSymbolWorker( void* ptr ) { ((Profiler*)ptr)->SymbolWorker(); }
872+
static void LaunchSymbolWorker( void* ptr )
873+
{
874+
tracy::DirectAlloc lock;
875+
( (Profiler*)ptr )->SymbolWorker();
876+
}
865877
void SymbolWorker();
866878
void HandleSymbolQueueItem( const SymbolQueueItem& si );
867879
#endif

public/client/TracySysPower.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ void SysPower::Tick()
6868

6969
void SysPower::ScanDirectory( const char* path, int parent )
7070
{
71+
tracy::DirectAlloc lock;
7172
DIR* dir = opendir( path );
7273
if( !dir ) return;
7374
struct dirent* ent;

public/client/TracySysTime.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ void SysTime::ReadTimes()
5555

5656
void SysTime::ReadTimes()
5757
{
58+
tracy::DirectAlloc lock;
5859
uint64_t user, nice, system;
5960
FILE* f = fopen( "/proc/stat", "r" );
6061
if( f )

0 commit comments

Comments
 (0)