mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-10 02:31:48 +00:00
Merge pull request #74 from avoroshilov/manual-lifetime
Manual lifetime management for Multi-DLL
This commit is contained in:
commit
2bef3629b7
2
.github/workflows/gcc.yml
vendored
2
.github/workflows/gcc.yml
vendored
@ -40,3 +40,5 @@ jobs:
|
||||
make -j -C test
|
||||
make -j -C test clean
|
||||
make -j -C test TRACYFLAGS=-DTRACY_ON_DEMAND
|
||||
make -j -C test clean
|
||||
make -j -C test TRACYFLAGS="-DTRACY_DELAYED_INIT -DTRACY_MANUAL_LIFETIME"
|
||||
|
1
AUTHORS
1
AUTHORS
@ -11,3 +11,4 @@ Thales Sabino <thales@codeplay.com> (OpenCL support)
|
||||
Andrew Depke <andrewdepke@gmail.com> (Direct3D 12 support)
|
||||
Simonas Kazlauskas <git@kazlauskas.me> (OSX CI, external bindings)
|
||||
Jakub Žádník <kubouch@gmail.com> (csvexport utility)
|
||||
Andrey Voroshilov <andrew.voroshilov@gmail.com> (multi-DLL fixes)
|
||||
|
@ -924,6 +924,25 @@ struct ProfilerThreadData
|
||||
# endif
|
||||
};
|
||||
|
||||
# ifdef TRACY_MANUAL_LIFETIME
|
||||
ProfilerData* s_profilerData = nullptr;
|
||||
TRACY_API void StartupProfiler()
|
||||
{
|
||||
s_profilerData = new ProfilerData;
|
||||
s_profilerData->profiler.SpawnWorkerThreads();
|
||||
}
|
||||
static ProfilerData& GetProfilerData()
|
||||
{
|
||||
assert(s_profilerData);
|
||||
return *s_profilerData;
|
||||
}
|
||||
TRACY_API void ShutdownProfiler()
|
||||
{
|
||||
delete s_profilerData;
|
||||
s_profilerData = nullptr;
|
||||
rpmalloc_finalize();
|
||||
}
|
||||
# else
|
||||
static std::atomic<int> profilerDataLock { 0 };
|
||||
static std::atomic<ProfilerData*> profilerData { nullptr };
|
||||
|
||||
@ -945,6 +964,7 @@ static ProfilerData& GetProfilerData()
|
||||
}
|
||||
return *ptr;
|
||||
}
|
||||
# endif
|
||||
|
||||
static ProfilerThreadData& GetProfilerThreadData()
|
||||
{
|
||||
@ -966,10 +986,12 @@ std::atomic<ThreadNameData*>& GetThreadNameData() { return GetProfilerData().thr
|
||||
TRACY_API LuaZoneState& GetLuaZoneState() { return GetProfilerThreadData().luaZoneState; }
|
||||
# endif
|
||||
|
||||
# ifndef TRACY_MANUAL_LIFETIME
|
||||
namespace
|
||||
{
|
||||
const auto& __profiler_init = GetProfiler();
|
||||
}
|
||||
# endif
|
||||
|
||||
#else
|
||||
TRACY_API void InitRPMallocThread()
|
||||
@ -1094,6 +1116,13 @@ Profiler::Profiler()
|
||||
m_userPort = atoi( userPort );
|
||||
}
|
||||
|
||||
#if !defined(TRACY_DELAYED_INIT) || !defined(TRACY_MANUAL_LIFETIME)
|
||||
SpawnWorkerThreads();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Profiler::SpawnWorkerThreads()
|
||||
{
|
||||
s_thread = (Thread*)tracy_malloc( sizeof( Thread ) );
|
||||
new(s_thread) Thread( LaunchWorker, this );
|
||||
|
||||
@ -1185,6 +1214,8 @@ void Profiler::Worker()
|
||||
s_profilerTid = syscall( SYS_gettid );
|
||||
#endif
|
||||
|
||||
ThreadExitHandler threadExitHandler;
|
||||
|
||||
SetThreadName( "Tracy Profiler" );
|
||||
|
||||
#ifdef TRACY_DATA_PORT
|
||||
@ -1605,6 +1636,8 @@ void Profiler::Worker()
|
||||
|
||||
void Profiler::CompressWorker()
|
||||
{
|
||||
ThreadExitHandler threadExitHandler;
|
||||
|
||||
SetThreadName( "Tracy DXT1" );
|
||||
while( m_timeBegin.load( std::memory_order_relaxed ) == 0 ) std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
|
||||
rpmalloc_thread_initialize();
|
||||
|
@ -41,6 +41,10 @@
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
#if defined(TRACY_DELAYED_INIT) && defined(TRACY_MANUAL_LIFETIME)
|
||||
void StartupProfiler();
|
||||
void ShutdownProfiler();
|
||||
#endif
|
||||
|
||||
class GpuCtx;
|
||||
class Profiler;
|
||||
@ -119,6 +123,8 @@ public:
|
||||
Profiler();
|
||||
~Profiler();
|
||||
|
||||
void SpawnWorkerThreads();
|
||||
|
||||
static tracy_force_inline int64_t GetTime()
|
||||
{
|
||||
#ifdef TRACY_HW_TIMER
|
||||
|
@ -321,6 +321,7 @@ static void SetupVsync()
|
||||
|
||||
s_threadVsync = (Thread*)tracy_malloc( sizeof( Thread ) );
|
||||
new(s_threadVsync) Thread( [] (void*) {
|
||||
ThreadExitHandler threadExitHandler;
|
||||
SetThreadName( "Tracy Vsync" );
|
||||
ProcessTrace( &s_traceHandleVsync2, 1, nullptr, nullptr );
|
||||
}, nullptr );
|
||||
@ -455,6 +456,7 @@ void SysTraceStop()
|
||||
|
||||
void SysTraceWorker( void* ptr )
|
||||
{
|
||||
ThreadExitHandler threadExitHandler;
|
||||
SetThreadName( "Tracy SysTrace" );
|
||||
ProcessTrace( &s_traceHandle2, 1, 0, 0 );
|
||||
ControlTrace( 0, KERNEL_LOGGER_NAME, s_prop, EVENT_TRACE_CONTROL_STOP );
|
||||
@ -955,6 +957,7 @@ static void ProcessTraceLines( int fd )
|
||||
|
||||
void SysTraceWorker( void* ptr )
|
||||
{
|
||||
ThreadExitHandler threadExitHandler;
|
||||
SetThreadName( "Tracy SysTrace" );
|
||||
int pipefd[2];
|
||||
if( pipe( pipefd ) == 0 )
|
||||
@ -1028,6 +1031,7 @@ static void ProcessTraceLines( int fd )
|
||||
|
||||
void SysTraceWorker( void* ptr )
|
||||
{
|
||||
ThreadExitHandler threadExitHandler;
|
||||
SetThreadName( "Tracy SysTrace" );
|
||||
char tmp[256];
|
||||
memcpy( tmp, BasePath, sizeof( BasePath ) - 1 );
|
||||
|
@ -10,6 +10,17 @@
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
class ThreadExitHandler
|
||||
{
|
||||
public:
|
||||
~ThreadExitHandler()
|
||||
{
|
||||
#ifdef TRACY_MANUAL_LIFETIME
|
||||
rpmalloc_thread_finalize();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
|
||||
class Thread
|
||||
|
@ -427,6 +427,10 @@ For that you need a \emph{profiler DLL} to which your executable and the other D
|
||||
|
||||
If you are targeting Windows with Microsoft Visual Studio or MinGW, add the \texttt{TRACY\_IMPORTS} define to your application.
|
||||
|
||||
If you are experiencing crashes or freezes when manually loading/unloading a separate DLL with Tracy integration, you might want to try defining both \texttt{TRACY\_DELAYED\_INIT} and \texttt{TRACY\_MANUAL\_LIFETIME} macros.
|
||||
|
||||
\texttt{TRACY\_DELAYED\_INIT} enables a path where profiler data is gathered into one structure and initialized on the first request rather than statically at the DLL load at the expense of atomic load on each request to the profiler data. \texttt{TRACY\_MANUAL\_LIFETIME} flag augments this behavior to provide manual \texttt{StartupProfiler} and \texttt{ShutdownProfiler} functions that allow you to manually create and destroy the profiler data, removing the need to do an atomic load on each call, as well as letting you define an appropriate place to free the resources.
|
||||
|
||||
\subsubsection{Problematic platforms}
|
||||
|
||||
Some OS vendors think that \emph{they} own and control the devices \emph{you} have paid for. This results in restricting usage of APIs that might 'confuse' you, or denying you access to information about what your computer is doing.
|
||||
|
Loading…
Reference in New Issue
Block a user