mirror of
https://github.com/wolfpld/tracy.git
synced 2025-03-20 07:40:02 +08:00
Check if rpmalloc has to be initialized before each operation.
The C++11 spec states in [basic.stc.thread] thread storage duration: 2. A variable with thread storage duration shall be initialized before its first odr-use (3.2) and, if constructed, shall be destroyed on thread exit. Previously Tracy relied on the TLS data being initialized: - During thread creation (MSVC). - Or during first use in a thread, but the initialization was performed for the whole TLS block. It seems that new compilers are more granular with how they perform the initialization, hence rpmalloc init has to be checked before each allocation, as it cannot be "folded" into, for example, initialization of the profiler itself.
This commit is contained in:
@@ -4,15 +4,47 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
# include <atomic>
|
||||
# include "TracyForceInline.hpp"
|
||||
# include "TracyYield.hpp"
|
||||
# include "../client/tracy_rpmalloc.hpp"
|
||||
#endif
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
extern std::atomic<int> RpInitDone;
|
||||
extern std::atomic<int> RpInitLock;
|
||||
|
||||
namespace
|
||||
{
|
||||
static inline void InitRpmallocPlumbing()
|
||||
{
|
||||
int expected = 0;
|
||||
while( !RpInitLock.compare_exchange_weak( expected, 1, std::memory_order_release, std::memory_order_relaxed ) ) { expected = 0; YieldThread(); }
|
||||
const auto done = RpInitDone.load( std::memory_order_acquire );
|
||||
if( !done )
|
||||
{
|
||||
rpmalloc_initialize();
|
||||
RpInitDone.store( 1, std::memory_order_release );
|
||||
}
|
||||
RpInitLock.store( 0, std::memory_order_release );
|
||||
}
|
||||
|
||||
static tracy_force_inline void InitRpmalloc()
|
||||
{
|
||||
const auto done = RpInitDone.load( std::memory_order_acquire );
|
||||
if( !done ) InitRpmallocPlumbing();
|
||||
rpmalloc_thread_initialize();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void* tracy_malloc( size_t size )
|
||||
{
|
||||
#ifdef TRACY_ENABLE
|
||||
InitRpmalloc();
|
||||
return rpmalloc( size );
|
||||
#else
|
||||
return malloc( size );
|
||||
@@ -22,6 +54,7 @@ static inline void* tracy_malloc( size_t size )
|
||||
static inline void tracy_free( void* ptr )
|
||||
{
|
||||
#ifdef TRACY_ENABLE
|
||||
InitRpmalloc();
|
||||
rpfree( ptr );
|
||||
#else
|
||||
free( ptr );
|
||||
@@ -31,6 +64,7 @@ static inline void tracy_free( void* ptr )
|
||||
static inline void* tracy_realloc( void* ptr, size_t size )
|
||||
{
|
||||
#ifdef TRACY_ENABLE
|
||||
InitRpmalloc();
|
||||
return rprealloc( ptr, size );
|
||||
#else
|
||||
return realloc( ptr, size );
|
||||
|
||||
@@ -96,7 +96,6 @@ struct ThreadNameData
|
||||
ThreadNameData* next;
|
||||
};
|
||||
std::atomic<ThreadNameData*>& GetThreadNameData();
|
||||
TRACY_API void InitRPMallocThread();
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -161,7 +160,6 @@ TRACY_API void SetThreadName( const char* name )
|
||||
#endif
|
||||
#ifdef TRACY_ENABLE
|
||||
{
|
||||
InitRPMallocThread();
|
||||
const auto sz = strlen( name );
|
||||
char* buf = (char*)tracy_malloc( sz+1 );
|
||||
memcpy( buf, name, sz );
|
||||
|
||||
Reference in New Issue
Block a user