diff --git a/manual/tracy.tex b/manual/tracy.tex index 29633c79..93ff6ecf 100644 --- a/manual/tracy.tex +++ b/manual/tracy.tex @@ -1927,6 +1927,24 @@ Beware that \texttt{update} will use any matching symbol file to the path it res 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. @@ -2206,6 +2224,10 @@ To query the connection status (section~\ref{connectionstatus}) using the C API 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} @@ -2615,6 +2637,10 @@ To query the connection status (section~\ref{connectionstatus}) using the Fortra 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. diff --git a/public/TracyClient.F90 b/public/TracyClient.F90 index 7c24648a..7524650a 100644 --- a/public/TracyClient.F90 +++ b/public/TracyClient.F90 @@ -1003,6 +1003,21 @@ module tracy 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 @@ module tracy 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 @@ contains 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 diff --git a/public/client/TracyProfiler.cpp b/public/client/TracyProfiler.cpp index 6fe78680..9c8c1de7 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 ) @@ -2177,6 +2178,11 @@ void Profiler::Worker() return; } } + else + { + m_shutdownFinished.store( true, std::memory_order_relaxed ); + return; + } } } @@ -2199,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; @@ -4986,6 +4992,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/client/TracyProfiler.hpp b/public/client/TracyProfiler.hpp index 8d169058..8fb2b4a3 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 @@ -770,6 +778,10 @@ public: 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 +1010,7 @@ private: 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; diff --git a/public/tracy/Tracy.hpp b/public/tracy/Tracy.hpp index bed51179..94b99c51 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 1b1373e0..3a7c8811 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