From bb88366958b481c337fcde03b2106007a866d300 Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" Date: Tue, 14 Jan 2025 06:17:58 +0100 Subject: [PATCH 1/6] Provide m_isActive and methods to access it --- public/client/TracyProfiler.cpp | 1 + public/client/TracyProfiler.hpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/public/client/TracyProfiler.cpp b/public/client/TracyProfiler.cpp index 6fe7868093..d5a9bdaacf 100644 --- a/public/client/TracyProfiler.cpp +++ b/public/client/TracyProfiler.cpp @@ -1403,6 +1403,7 @@ Profiler::Profiler() , m_shutdown( false ) , m_shutdownManual( false ) , m_shutdownFinished( false ) + , m_isActive( true ) , m_sock( nullptr ) , m_broadcast( nullptr ) , m_noExit( false ) diff --git a/public/client/TracyProfiler.hpp b/public/client/TracyProfiler.hpp index 8d16905860..9ebb7ede1b 100644 --- a/public/client/TracyProfiler.hpp +++ b/public/client/TracyProfiler.hpp @@ -770,6 +770,10 @@ class Profiler void RequestShutdown() { m_shutdown.store( true, std::memory_order_relaxed ); m_shutdownManual.store( true, std::memory_order_relaxed ); } bool HasShutdownFinished() const { return m_shutdownFinished.load( std::memory_order_relaxed ); } + void Suspend() { m_isActive.store( false, std::memory_order_relaxed ); } + void Resume() { m_isActive.store( true, std::memory_order_relaxed ); } + tracy_force_inline bool IsActive() const { return m_isActive.load( std::memory_order_relaxed ); } + void SendString( uint64_t str, const char* ptr, QueueType type ) { SendString( str, ptr, strlen( ptr ), type ); } void SendString( uint64_t str, const char* ptr, size_t len, QueueType type ); void SendSingleString( const char* ptr ) { SendSingleString( ptr, strlen( ptr ) ); } @@ -998,6 +1002,7 @@ class Profiler std::atomic m_shutdown; std::atomic m_shutdownManual; std::atomic m_shutdownFinished; + std::atomic m_isActive; Socket* m_sock; UdpBroadcast* m_broadcast; bool m_noExit; From 69c541e5948167acf4d8a2b94b4acc1913902239 Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" Date: Tue, 14 Jan 2025 06:03:14 +0100 Subject: [PATCH 2/6] Commit events if IsActive --- public/client/TracyProfiler.hpp | 48 +++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/public/client/TracyProfiler.hpp b/public/client/TracyProfiler.hpp index 9ebb7ede1b..8fb2b4a354 100644 --- a/public/client/TracyProfiler.hpp +++ b/public/client/TracyProfiler.hpp @@ -114,39 +114,47 @@ struct LuaZoneState #define TracyLfqPrepare( _type ) \ - tracy::moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \ - auto __token = tracy::GetToken(); \ - auto& __tail = __token->get_tail_index(); \ - auto item = __token->enqueue_begin( __magic ); \ - tracy::MemWrite( &item->hdr.type, _type ); + if (tracy::GetProfiler().IsActive()) { \ + tracy::moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \ + auto __token = tracy::GetToken(); \ + auto& __tail = __token->get_tail_index(); \ + auto item = __token->enqueue_begin( __magic ); \ + tracy::MemWrite( &item->hdr.type, _type ); #define TracyLfqCommit \ - __tail.store( __magic + 1, std::memory_order_release ); + __tail.store( __magic + 1, std::memory_order_release ); \ + } #define TracyLfqPrepareC( _type ) \ - tracy::moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \ - auto __token = tracy::GetToken(); \ - auto& __tail = __token->get_tail_index(); \ - auto item = __token->enqueue_begin( __magic ); \ - tracy::MemWrite( &item->hdr.type, _type ); + if (tracy::GetProfiler().IsActive()) { \ + tracy::moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \ + auto __token = tracy::GetToken(); \ + auto& __tail = __token->get_tail_index(); \ + auto item = __token->enqueue_begin( __magic ); \ + tracy::MemWrite( &item->hdr.type, _type ); #define TracyLfqCommitC \ - __tail.store( __magic + 1, std::memory_order_release ); + __tail.store( __magic + 1, std::memory_order_release ); \ + } #ifdef TRACY_FIBERS # define TracyQueuePrepare( _type ) \ - auto item = tracy::Profiler::QueueSerial(); \ - tracy::MemWrite( &item->hdr.type, _type ); + if (tracy::GetProfiler().IsActive()) { \ + auto item = tracy::Profiler::QueueSerial(); \ + tracy::MemWrite( &item->hdr.type, _type ); # define TracyQueueCommit( _name ) \ - tracy::MemWrite( &item->_name.thread, tracy::GetThreadHandle() ); \ - tracy::Profiler::QueueSerialFinish(); + tracy::MemWrite( &item->_name.thread, tracy::GetThreadHandle() ); \ + tracy::Profiler::QueueSerialFinish(); \ + } # define TracyQueuePrepareC( _type ) \ - auto item = tracy::Profiler::QueueSerial(); \ - tracy::MemWrite( &item->hdr.type, _type ); + if (tracy::GetProfiler().IsActive()) { \ + auto item = tracy::Profiler::QueueSerial(); \ + tracy::MemWrite( &item->hdr.type, _type ); # define TracyQueueCommitC( _name ) \ - tracy::MemWrite( &item->_name.thread, tracy::GetThreadHandle() ); \ - tracy::Profiler::QueueSerialFinish(); + tracy::MemWrite( &item->_name.thread, tracy::GetThreadHandle() ); \ + tracy::Profiler::QueueSerialFinish(); \ + } #else # define TracyQueuePrepare( _type ) TracyLfqPrepare( _type ) # define TracyQueueCommit( _name ) TracyLfqCommit From ae9bdd6721f247d2f85486243f31aeef4a776750 Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" Date: Tue, 14 Jan 2025 06:41:33 +0100 Subject: [PATCH 3/6] Implement suspend/resume/is_active for C++/C APIs --- public/client/TracyProfiler.cpp | 10 ++++++++++ public/tracy/Tracy.hpp | 8 ++++++++ public/tracy/TracyC.h | 12 ++++++++++++ 3 files changed, 30 insertions(+) diff --git a/public/client/TracyProfiler.cpp b/public/client/TracyProfiler.cpp index d5a9bdaacf..24f72f6a57 100644 --- a/public/client/TracyProfiler.cpp +++ b/public/client/TracyProfiler.cpp @@ -4987,6 +4987,16 @@ TRACY_API int32_t ___tracy_profiler_started( void ) } # endif +TRACY_API void ___tracy_suspend( void ) { + tracy::GetProfiler().Suspend(); +} +TRACY_API void ___tracy_resume( void ) { + tracy::GetProfiler().Resume(); +} +TRACY_API int32_t ___tracy_is_active( void ) { + return static_cast( tracy::GetProfiler().IsActive() ); +} + #ifdef __cplusplus } #endif diff --git a/public/tracy/Tracy.hpp b/public/tracy/Tracy.hpp index bed511799a..94b99c5195 100644 --- a/public/tracy/Tracy.hpp +++ b/public/tracy/Tracy.hpp @@ -126,6 +126,10 @@ #define TracyFiberEnterHint(x,y) #define TracyFiberLeave +#define TracySuspend +#define TracyResume +#define TracyIsActive + #else #include @@ -249,6 +253,10 @@ # define TracyFiberLeave tracy::Profiler::LeaveFiber() #endif +#define TracySuspend tracy::GetProfiler().Suspend() +#define TracyResume tracy::GetProfiler().Resume() +#define TracyIsActive tracy::GetProfiler().IsActive() + #endif #endif diff --git a/public/tracy/TracyC.h b/public/tracy/TracyC.h index 1b1373e0d0..3a7c88119a 100644 --- a/public/tracy/TracyC.h +++ b/public/tracy/TracyC.h @@ -119,6 +119,10 @@ typedef const void* TracyCLockCtx; # define TracyCFiberLeave #endif +#define TracySuspend +#define TracyResume +#define TracyIsActive + #else #ifndef TracyConcat @@ -375,6 +379,14 @@ TRACY_API void ___tracy_fiber_leave( void ); # define TracyCFiberLeave ___tracy_fiber_leave(); #endif +TRACY_API void ___tracy_suspend( void ); +TRACY_API void ___tracy_resume( void ); +TRACY_API int32_t ___tracy_is_active( void ); + +#define TracySuspend ___tracy_suspend( void ); +#define TracyResume ___tracy_resume( void ); +#define TracyIsActive ___tracy_is_active( void ); + #endif #ifdef __cplusplus From 31b27780276ac211f5068f85b826f417c5ec1ef3 Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" Date: Tue, 14 Jan 2025 06:46:44 +0100 Subject: [PATCH 4/6] Implement suspend/resume/is_active for Fortran API --- public/TracyClient.F90 | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/public/TracyClient.F90 b/public/TracyClient.F90 index 7c24648aa7..7524650a59 100644 --- a/public/TracyClient.F90 +++ b/public/TracyClient.F90 @@ -1003,6 +1003,21 @@ subroutine tracy_fiber_leave() & end subroutine tracy_fiber_leave end interface #endif + + interface + subroutine tracy_suspend() & + bind(C, name="___tracy_suspend") + end subroutine tracy_suspend + subroutine tracy_resume() & + bind(C, name="___tracy_resume") + end subroutine tracy_resume + function impl_tracy_is_active() & + bind(C, name="___tracy_is_active") + import + integer(c_int32_t) :: impl_tracy_is_active + end function impl_tracy_is_active + end interface + ! public :: tracy_zone_context public :: tracy_source_location_data @@ -1014,6 +1029,7 @@ end subroutine tracy_fiber_leave public :: tracy_set_thread_name public :: tracy_startup_profiler, tracy_shutdown_profiler, tracy_profiler_started public :: tracy_connected + public :: tracy_suspend, tracy_resume, tracy_is_active public :: tracy_appinfo public :: tracy_alloc_srcloc public :: tracy_zone_begin, tracy_zone_end @@ -1289,4 +1305,8 @@ subroutine tracy_fiber_enter(fiber_name) call impl_tracy_fiber_enter(c_loc(fiber_name)) end subroutine tracy_fiber_enter #endif + + logical(1) function tracy_is_active() + tracy_is_active = impl_tracy_is_active() /= 0_c_int32_t + end function tracy_is_active end module tracy From 9a5f9831be2b2835df06fb57cec23b84efac6068 Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" Date: Tue, 14 Jan 2025 10:08:19 +0100 Subject: [PATCH 5/6] Avoid infinity loops at the exit --- public/client/TracyProfiler.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/public/client/TracyProfiler.cpp b/public/client/TracyProfiler.cpp index 24f72f6a57..9c8c1de7d9 100644 --- a/public/client/TracyProfiler.cpp +++ b/public/client/TracyProfiler.cpp @@ -2178,6 +2178,11 @@ void Profiler::Worker() return; } } + else + { + m_shutdownFinished.store( true, std::memory_order_relaxed ); + return; + } } } @@ -2200,7 +2205,7 @@ void Profiler::CompressWorker() bool lockHeld = true; while( !m_fiLock.try_lock() ) { - if( m_shutdownManual.load( std::memory_order_relaxed ) ) + if( m_shutdownManual.load( std::memory_order_relaxed ) || m_shutdown.load( std::memory_order_relaxed ) ) { lockHeld = false; break; From 4005f671a71e103fbadd5f426e7093c3882966c1 Mon Sep 17 00:00:00 2001 From: "Igor S. Gerasimov" Date: Tue, 14 Jan 2025 10:40:15 +0100 Subject: [PATCH 6/6] Add Resume/Suspend documentation --- manual/tracy.tex | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/manual/tracy.tex b/manual/tracy.tex index 185a21e096..a31cb4de81 100644 --- a/manual/tracy.tex +++ b/manual/tracy.tex @@ -1924,6 +1924,24 @@ \subsubsection{Debugging symbols} Also note that in the case of using offline symbol resolving, even after running the \texttt{update} tool to resolve symbols, the symbols statistics are not updated and will still report the unresolved symbols. \end{bclogo} +\subsection{Suspend/Resume profiler} +\label{suspendandresume} + +The Tracy profiler generates a lot of data, especially when used with long-running applications. +For example, a one-hour application run can produce a trace exceeding 16 Gb! +To minimize unnecessary memory consumption, you can suspend Tracy's profiling using the macro \texttt{TracySuspend} until you reach the section of code you wish to profile. +When profiling needs to resume, use the macro \texttt{TracyResume}. +To determine whether Tracy is currently active, use the macro \texttt{TracyIsActive}. + +\begin{bclogo}[ +noborder=true, +couleur=black!5, +logo=\bcbombe +]{Important} +The macros \texttt{TracySuspend} and \texttt{TracyResume} must be used within the same zones or frames (ideally outside of them). Otherwise, the trace may become incorrect. +\end{bclogo} + + \subsection{Lua support} To profile Lua code using Tracy, include the \texttt{public/tracy/TracyLua.hpp} header file in your Lua wrapper and execute \texttt{tracy::LuaRegister(lua\_State*)} function to add instrumentation support. @@ -2195,6 +2213,10 @@ \subsubsection{Call stacks} You can collect call stacks of zones and memory allocation events, as described in section~\ref{collectingcallstacks}, by using macros with \texttt{S} postfix, such as: \texttt{TracyCZoneS}, \texttt{TracyCZoneNS}, \texttt{TracyCZoneCS}, \texttt{TracyCZoneNCS}, \texttt{TracyCAllocS}, \texttt{TracyCFreeS}, and so on. +\subsubsection{Suspend/Resume profiler} + +You can suspend and resume Tracy profiler as described in section~\ref{suspendandresume}. + \subsubsection{Using the C API to implement bindings} \label{capibindings} @@ -2584,6 +2606,10 @@ \subsubsection{Call stacks} You can collect call stacks of zones and memory allocation events, as described in section~\ref{collectingcallstacks}, by using optional \texttt{depth} argument in functions/subroutines calls. +\subsubsection{Suspend/Resume profiler} + +You can suspend and resume profile, as described in section~\ref{suspendandresume}, by using \texttt{tracy\_suspend} and \texttt{tracy\_resume} subroutines and \texttt{tracy\_is\_active} function. + \subsubsection{Colors} A set of predefined colors is available with \texttt{TracyColors} variable inside of \texttt{tracy} module.