Move initialization of callstack structs to a thread.

Initializing structures for callstack processing (building memory map of the
process, gathering kernel symbols, etc) takes some time, which in some cases
may be significant.

Callstack queries are now handled on a separate thread. In such setup it no
longer makes sense to block main thread execution with this lengthy init
process.

All the heavy initialization phase has been now moved to this separate
processing thread. Some initial callstack queries may now not produce
responses as promptly as before, but this is only because the main thread is
able to start working earlier.

Some parts of the initialization process may be critical to do in the main
thread, for example because the function responsible for gathering callstacks
must be loaded first. This is done still on the main thread, in a new function
InitCallstackCritical().
This commit is contained in:
Bartosz Taudul 2022-08-16 13:55:46 +02:00
parent d9d31e4d51
commit 72ad40698b
No known key found for this signature in database
GPG Key ID: B7FE2008B7575DF3
3 changed files with 17 additions and 4 deletions

View File

@ -138,9 +138,13 @@ KernelDriver* s_krnlCache = nullptr;
size_t s_krnlCacheCnt; size_t s_krnlCacheCnt;
void InitCallstack() void InitCallstackCritical()
{ {
___tracy_RtlWalkFrameChain = (___tracy_t_RtlWalkFrameChain)GetProcAddress( GetModuleHandleA( "ntdll.dll" ), "RtlWalkFrameChain" ); ___tracy_RtlWalkFrameChain = (___tracy_t_RtlWalkFrameChain)GetProcAddress( GetModuleHandleA( "ntdll.dll" ), "RtlWalkFrameChain" );
}
void InitCallstack()
{
_SymAddrIncludeInlineTrace = (t_SymAddrIncludeInlineTrace)GetProcAddress( GetModuleHandleA( "dbghelp.dll" ), "SymAddrIncludeInlineTrace" ); _SymAddrIncludeInlineTrace = (t_SymAddrIncludeInlineTrace)GetProcAddress( GetModuleHandleA( "dbghelp.dll" ), "SymAddrIncludeInlineTrace" );
_SymQueryInlineTrace = (t_SymQueryInlineTrace)GetProcAddress( GetModuleHandleA( "dbghelp.dll" ), "SymQueryInlineTrace" ); _SymQueryInlineTrace = (t_SymQueryInlineTrace)GetProcAddress( GetModuleHandleA( "dbghelp.dll" ), "SymQueryInlineTrace" );
_SymFromInlineContext = (t_SymFromInlineContext)GetProcAddress( GetModuleHandleA( "dbghelp.dll" ), "SymFromInlineContext" ); _SymFromInlineContext = (t_SymFromInlineContext)GetProcAddress( GetModuleHandleA( "dbghelp.dll" ), "SymFromInlineContext" );
@ -695,6 +699,10 @@ static void InitKernelSymbols()
} }
#endif #endif
void InitCallstackCritical()
{
}
void InitCallstack() void InitCallstack()
{ {
cb_bts = backtrace_create_state( nullptr, 0, nullptr, nullptr ); cb_bts = backtrace_create_state( nullptr, 0, nullptr, nullptr );
@ -1028,6 +1036,10 @@ CallstackEntryData DecodeCallstackPtr( uint64_t ptr )
#elif TRACY_HAS_CALLSTACK == 5 #elif TRACY_HAS_CALLSTACK == 5
void InitCallstackCritical()
{
}
void InitCallstack() void InitCallstack()
{ {
___tracy_init_demangle_buffer(); ___tracy_init_demangle_buffer();

View File

@ -55,6 +55,7 @@ CallstackSymbolData DecodeCodeAddress( uint64_t ptr );
const char* DecodeCallstackPtrFast( uint64_t ptr ); const char* DecodeCallstackPtrFast( uint64_t ptr );
CallstackEntryData DecodeCallstackPtr( uint64_t ptr ); CallstackEntryData DecodeCallstackPtr( uint64_t ptr );
void InitCallstack(); void InitCallstack();
void InitCallstackCritical();
void EndCallstack(); void EndCallstack();
const char* GetKernelModulePath( uint64_t addr ); const char* GetKernelModulePath( uint64_t addr );

View File

@ -1444,7 +1444,7 @@ void Profiler::SpawnWorkerThreads()
#endif #endif
#ifdef TRACY_HAS_CALLSTACK #ifdef TRACY_HAS_CALLSTACK
InitCallstack(); InitCallstackCritical();
#endif #endif
m_timeBegin.store( GetTime(), std::memory_order_relaxed ); m_timeBegin.store( GetTime(), std::memory_order_relaxed );
@ -3296,11 +3296,11 @@ void Profiler::SymbolWorker()
{ {
ThreadExitHandler threadExitHandler; ThreadExitHandler threadExitHandler;
SetThreadName( "Tracy Symbol Worker" ); SetThreadName( "Tracy Symbol Worker" );
while( m_timeBegin.load( std::memory_order_relaxed ) == 0 ) std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
#ifdef TRACY_USE_RPMALLOC #ifdef TRACY_USE_RPMALLOC
rpmalloc_thread_initialize(); rpmalloc_thread_initialize();
#endif #endif
InitCallstack();
while( m_timeBegin.load( std::memory_order_relaxed ) == 0 ) std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
for(;;) for(;;)
{ {