2017-09-10 15:43:56 +00:00
# ifndef __TRACYPROFILER_HPP__
# define __TRACYPROFILER_HPP__
2018-08-05 00:09:59 +00:00
# include <assert.h>
2017-09-10 15:43:56 +00:00
# include <atomic>
2017-09-10 18:08:42 +00:00
# include <stdint.h>
2017-10-14 15:20:37 +00:00
# include <string.h>
2020-08-12 14:48:36 +00:00
# include <time.h>
2017-09-10 15:43:56 +00:00
2019-07-29 19:47:50 +00:00
# include "tracy_concurrentqueue.h"
2021-11-14 17:50:59 +00:00
# include "tracy_SPSCQueue.h"
2018-06-19 16:51:21 +00:00
# include "TracyCallstack.hpp"
2019-02-21 20:59:02 +00:00
# include "TracySysTime.hpp"
2018-04-01 17:53:05 +00:00
# include "TracyFastVector.hpp"
2017-09-13 20:56:08 +00:00
# include "../common/TracyQueue.hpp"
2018-03-31 12:03:55 +00:00
# include "../common/TracyAlign.hpp"
2017-10-18 17:08:19 +00:00
# include "../common/TracyAlloc.hpp"
2018-07-13 22:39:01 +00:00
# include "../common/TracyMutex.hpp"
2020-02-23 13:44:19 +00:00
# include "../common/TracyProtocol.hpp"
2017-09-10 18:09:14 +00:00
2021-10-07 21:28:40 +00:00
# if defined _WIN32
2017-09-25 22:42:09 +00:00
# include <intrin.h>
# endif
2019-02-21 13:45:13 +00:00
# ifdef __APPLE__
# include <TargetConditionals.h>
# include <mach / mach_time.h>
# endif
2017-09-25 22:42:09 +00:00
2022-02-11 14:01:56 +00:00
# if ( defined _WIN32 || ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) || ( defined TARGET_OS_IOS && TARGET_OS_IOS == 1 ) )
2018-04-26 14:03:31 +00:00
# define TRACY_HW_TIMER
# endif
2022-02-11 14:01:56 +00:00
# if defined TRACY_TIMER_FALLBACK || !defined TRACY_HW_TIMER
2021-01-28 17:49:12 +00:00
# include <chrono>
2019-11-05 19:09:40 +00:00
# endif
2019-01-14 19:55:37 +00:00
# ifndef TracyConcat
# define TracyConcat(x,y) TracyConcatIndirect(x,y)
# endif
# ifndef TracyConcatIndirect
# define TracyConcatIndirect(x,y) x##y
# endif
2018-07-26 17:52:27 +00:00
2017-09-10 15:43:56 +00:00
namespace tracy
{
2020-07-12 17:12:50 +00:00
# if defined(TRACY_DELAYED_INIT) && defined(TRACY_MANUAL_LIFETIME)
2021-03-08 01:39:51 +00:00
TRACY_API void StartupProfiler ( ) ;
TRACY_API void ShutdownProfiler ( ) ;
2020-07-07 07:39:09 +00:00
# endif
2017-09-10 15:43:56 +00:00
2019-02-19 18:33:37 +00:00
class GpuCtx ;
2019-02-19 17:38:08 +00:00
class Profiler ;
2017-09-14 17:07:56 +00:00
class Socket ;
2019-06-17 00:25:09 +00:00
class UdpBroadcast ;
2017-09-14 17:07:56 +00:00
2019-02-19 18:33:37 +00:00
struct GpuCtxWrapper
2017-09-26 00:28:14 +00:00
{
2019-02-19 18:33:37 +00:00
GpuCtx * ptr ;
2017-09-26 00:28:14 +00:00
} ;
2019-06-07 13:56:46 +00:00
TRACY_API moodycamel : : ConcurrentQueue < QueueItem > : : ExplicitProducer * GetToken ( ) ;
TRACY_API Profiler & GetProfiler ( ) ;
TRACY_API std : : atomic < uint32_t > & GetLockCounter ( ) ;
TRACY_API std : : atomic < uint8_t > & GetGpuCtxCounter ( ) ;
TRACY_API GpuCtxWrapper & GetGpuCtx ( ) ;
2021-10-07 22:42:52 +00:00
TRACY_API uint32_t GetThreadHandle ( ) ;
2020-06-23 23:32:57 +00:00
TRACY_API bool ProfilerAvailable ( ) ;
2020-07-07 19:24:44 +00:00
TRACY_API int64_t GetFrequencyQpc ( ) ;
2019-02-19 19:43:14 +00:00
2022-02-11 14:01:56 +00:00
# if defined TRACY_TIMER_FALLBACK && defined TRACY_HW_TIMER && ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 )
2022-02-19 08:44:15 +00:00
TRACY_API bool HardwareSupportsInvariantTSC ( ) ; // check, if we need fallback scenario
2022-02-11 14:01:56 +00:00
# else
# if defined TRACY_HW_TIMER
2022-02-19 08:44:15 +00:00
tracy_force_inline bool HardwareSupportsInvariantTSC ( )
2022-02-11 14:01:56 +00:00
{
return true ; // this is checked at startup
}
# else
2022-02-19 08:44:15 +00:00
tracy_force_inline bool HardwareSupportsInvariantTSC ( )
2022-02-11 14:01:56 +00:00
{
return false ;
}
# endif
# endif
2019-02-19 18:33:37 +00:00
struct SourceLocationData
2017-11-14 22:29:48 +00:00
{
2019-02-19 18:33:37 +00:00
const char * name ;
const char * function ;
const char * file ;
uint32_t line ;
uint32_t color ;
2017-11-14 22:29:48 +00:00
} ;
2018-07-13 18:20:37 +00:00
# ifdef TRACY_ON_DEMAND
struct LuaZoneState
{
uint32_t counter ;
bool active ;
} ;
# endif
2020-01-19 14:06:11 +00:00
# define TracyLfqPrepare( _type ) \
moodycamel : : ConcurrentQueueDefaultTraits : : index_t __magic ; \
auto __token = GetToken ( ) ; \
auto & __tail = __token - > get_tail_index ( ) ; \
auto item = __token - > enqueue_begin ( __magic ) ; \
MemWrite ( & item - > hdr . type , _type ) ;
# define TracyLfqCommit \
__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 ) ;
# define TracyLfqCommitC \
__tail . store ( __magic + 1 , std : : memory_order_release ) ;
2017-10-03 12:50:55 +00:00
2018-04-01 17:53:05 +00:00
2021-10-09 12:55:32 +00:00
# ifdef TRACY_FIBERS
# define TracyQueuePrepare( _type ) \
auto item = Profiler : : QueueSerial ( ) ; \
MemWrite ( & item - > hdr . type , _type ) ;
# define TracyQueueCommit( _name ) \
MemWrite ( & item - > _name . thread , GetThreadHandle ( ) ) ; \
Profiler : : QueueSerialFinish ( ) ;
2021-10-09 13:50:30 +00:00
# define TracyQueuePrepareC( _type ) \
auto item = tracy : : Profiler : : QueueSerial ( ) ; \
tracy : : MemWrite ( & item - > hdr . type , _type ) ;
# define TracyQueueCommitC( _name ) \
tracy : : MemWrite ( & item - > _name . thread , tracy : : GetThreadHandle ( ) ) ; \
tracy : : Profiler : : QueueSerialFinish ( ) ;
2021-10-09 12:55:32 +00:00
# else
# define TracyQueuePrepare( _type ) TracyLfqPrepare( _type )
# define TracyQueueCommit( _name ) TracyLfqCommit
2021-10-09 13:50:30 +00:00
# define TracyQueuePrepareC( _type ) TracyLfqPrepareC( _type )
# define TracyQueueCommitC( _name ) TracyLfqCommitC
2021-10-09 12:55:32 +00:00
# endif
2019-11-25 22:59:48 +00:00
typedef void ( * ParameterCallback ) ( uint32_t idx , int32_t val ) ;
2017-09-10 15:43:56 +00:00
class Profiler
{
2019-06-26 20:50:56 +00:00
struct FrameImageQueueItem
{
void * image ;
2020-07-26 11:23:44 +00:00
uint32_t frame ;
2019-06-26 20:50:56 +00:00
uint16_t w ;
uint16_t h ;
bool flip ;
} ;
2021-10-22 20:22:27 +00:00
enum class SymbolQueueItemType
{
CallstackFrame ,
SymbolQuery ,
CodeLocation ,
2021-11-25 22:12:41 +00:00
ExternalName ,
KernelCode
2021-10-22 20:22:27 +00:00
} ;
struct SymbolQueueItem
{
SymbolQueueItemType type ;
uint64_t ptr ;
2021-11-25 22:12:41 +00:00
uint32_t extra ;
2021-10-22 20:22:27 +00:00
} ;
2017-09-10 15:43:56 +00:00
public :
Profiler ( ) ;
~ Profiler ( ) ;
2020-07-07 07:39:09 +00:00
void SpawnWorkerThreads ( ) ;
2018-04-26 13:30:53 +00:00
static tracy_force_inline int64_t GetTime ( )
2017-10-29 15:12:16 +00:00
{
2018-04-26 13:30:53 +00:00
# ifdef TRACY_HW_TIMER
2020-05-22 12:53:09 +00:00
# if defined TARGET_OS_IOS && TARGET_OS_IOS == 1
2022-02-19 08:44:15 +00:00
if ( HardwareSupportsInvariantTSC ( ) ) return mach_absolute_time ( ) ;
2021-10-07 21:28:40 +00:00
# elif defined _WIN32
2020-04-07 20:01:31 +00:00
# ifdef TRACY_TIMER_QPC
return GetTimeQpc ( ) ;
# else
2022-02-19 08:44:15 +00:00
if ( HardwareSupportsInvariantTSC ( ) ) return int64_t ( __rdtsc ( ) ) ;
2020-04-07 20:01:31 +00:00
# endif
2019-10-20 23:13:55 +00:00
# elif defined __i386 || defined _M_IX86
2022-02-19 08:44:15 +00:00
if ( HardwareSupportsInvariantTSC ( ) )
2022-02-11 14:01:56 +00:00
{
uint32_t eax , edx ;
asm volatile ( " rdtsc " : " =a " ( eax ) , " =d " ( edx ) ) ;
return ( uint64_t ( edx ) < < 32 ) + uint64_t ( eax ) ;
}
2019-10-20 23:13:55 +00:00
# elif defined __x86_64__ || defined _M_X64
2022-02-19 08:44:15 +00:00
if ( HardwareSupportsInvariantTSC ( ) )
2022-02-11 14:01:56 +00:00
{
uint64_t rax , rdx ;
asm volatile ( " rdtsc " : " =a " ( rax ) , " =d " ( rdx ) ) ;
return ( int64_t ) ( ( rdx < < 32 ) + rax ) ;
}
2020-08-12 14:48:36 +00:00
# else
# error "TRACY_HW_TIMER detection logic needs fixing"
2018-04-26 13:30:53 +00:00
# endif
2022-02-11 14:01:56 +00:00
# endif
# if !defined TRACY_HW_TIMER || defined TRACY_TIMER_FALLBACK
2020-08-12 14:48:36 +00:00
# if defined __linux__ && defined CLOCK_MONOTONIC_RAW
struct timespec ts ;
clock_gettime ( CLOCK_MONOTONIC_RAW , & ts ) ;
return int64_t ( ts . tv_sec ) * 1000000000ll + int64_t ( ts . tv_nsec ) ;
# else
2017-10-29 15:12:16 +00:00
return std : : chrono : : duration_cast < std : : chrono : : nanoseconds > ( std : : chrono : : high_resolution_clock : : now ( ) . time_since_epoch ( ) ) . count ( ) ;
2020-08-12 14:48:36 +00:00
# endif
2017-10-29 15:12:16 +00:00
# endif
2022-02-11 14:01:56 +00:00
return 0 ; // unreacheble branch
2017-10-29 15:12:16 +00:00
}
2019-01-14 21:23:24 +00:00
tracy_force_inline uint32_t GetNextZoneId ( )
{
return m_zoneId . fetch_add ( 1 , std : : memory_order_relaxed ) ;
}
2019-08-12 11:27:15 +00:00
static tracy_force_inline QueueItem * QueueSerial ( )
{
auto & p = GetProfiler ( ) ;
p . m_serialLock . lock ( ) ;
return p . m_serialQueue . prepare_next ( ) ;
}
2021-01-15 20:39:50 +00:00
static tracy_force_inline QueueItem * QueueSerialCallstack ( void * ptr )
{
auto & p = GetProfiler ( ) ;
p . m_serialLock . lock ( ) ;
p . SendCallstackSerial ( ptr ) ;
return p . m_serialQueue . prepare_next ( ) ;
}
2019-08-12 11:27:15 +00:00
static tracy_force_inline void QueueSerialFinish ( )
{
auto & p = GetProfiler ( ) ;
p . m_serialQueue . commit_next ( ) ;
p . m_serialLock . unlock ( ) ;
}
2019-02-28 18:21:23 +00:00
static tracy_force_inline void SendFrameMark ( const char * name )
2017-10-03 12:19:32 +00:00
{
2019-06-09 13:23:01 +00:00
if ( ! name ) GetProfiler ( ) . m_frameCount . fetch_add ( 1 , std : : memory_order_relaxed ) ;
2019-06-26 21:18:30 +00:00
# ifdef TRACY_ON_DEMAND
2019-02-19 17:38:08 +00:00
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
2018-07-10 20:23:27 +00:00
# endif
2021-11-05 00:13:24 +00:00
auto item = QueueSerial ( ) ;
MemWrite ( & item - > hdr . type , QueueType : : FrameMarkMsg ) ;
2018-03-31 12:03:55 +00:00
MemWrite ( & item - > frameMark . time , GetTime ( ) ) ;
2019-02-28 18:21:23 +00:00
MemWrite ( & item - > frameMark . name , uint64_t ( name ) ) ;
2021-11-05 00:13:24 +00:00
QueueSerialFinish ( ) ;
2017-10-03 12:19:32 +00:00
}
2017-09-10 18:09:14 +00:00
2018-08-05 00:09:59 +00:00
static tracy_force_inline void SendFrameMark ( const char * name , QueueType type )
2018-08-04 13:04:18 +00:00
{
2019-02-28 18:21:23 +00:00
assert ( type = = QueueType : : FrameMarkMsgStart | | type = = QueueType : : FrameMarkMsgEnd ) ;
2018-08-04 13:04:18 +00:00
# ifdef TRACY_ON_DEMAND
2019-02-19 17:38:08 +00:00
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
2018-08-04 13:04:18 +00:00
# endif
2019-08-12 11:27:15 +00:00
auto item = QueueSerial ( ) ;
2018-08-05 00:09:59 +00:00
MemWrite ( & item - > hdr . type , type ) ;
2018-08-04 13:04:18 +00:00
MemWrite ( & item - > frameMark . time , GetTime ( ) ) ;
MemWrite ( & item - > frameMark . name , uint64_t ( name ) ) ;
2019-08-12 11:27:15 +00:00
QueueSerialFinish ( ) ;
2018-08-04 13:04:18 +00:00
}
2019-07-13 10:33:55 +00:00
static tracy_force_inline void SendFrameImage ( const void * image , uint16_t w , uint16_t h , uint8_t offset , bool flip )
2019-06-06 19:39:54 +00:00
{
2021-04-29 18:55:16 +00:00
# ifndef TRACY_NO_FRAME_IMAGE
2019-06-26 20:50:56 +00:00
auto & profiler = GetProfiler ( ) ;
2020-07-26 11:23:44 +00:00
assert ( profiler . m_frameCount . load ( std : : memory_order_relaxed ) < std : : numeric_limits < uint32_t > : : max ( ) ) ;
2021-04-29 18:55:16 +00:00
# ifdef TRACY_ON_DEMAND
2019-06-26 20:50:56 +00:00
if ( ! profiler . IsConnected ( ) ) return ;
2021-04-29 18:55:16 +00:00
# endif
2019-06-06 19:39:54 +00:00
const auto sz = size_t ( w ) * size_t ( h ) * 4 ;
auto ptr = ( char * ) tracy_malloc ( sz ) ;
memcpy ( ptr , image , sz ) ;
2019-06-26 20:50:56 +00:00
2021-10-20 21:18:03 +00:00
profiler . m_fiLock . lock ( ) ;
auto fi = profiler . m_fiQueue . prepare_next ( ) ;
fi - > image = ptr ;
fi - > frame = uint32_t ( profiler . m_frameCount . load ( std : : memory_order_relaxed ) - offset ) ;
fi - > w = w ;
fi - > h = h ;
fi - > flip = flip ;
profiler . m_fiQueue . commit_next ( ) ;
profiler . m_fiLock . unlock ( ) ;
2021-04-29 18:55:16 +00:00
# endif
2019-06-06 19:39:54 +00:00
}
2017-10-13 00:21:29 +00:00
static tracy_force_inline void PlotData ( const char * name , int64_t val )
{
2018-07-10 21:06:27 +00:00
# ifdef TRACY_ON_DEMAND
2019-02-19 17:38:08 +00:00
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
2018-07-10 21:06:27 +00:00
# endif
2020-01-19 14:06:11 +00:00
TracyLfqPrepare ( QueueType : : PlotData ) ;
2018-03-31 12:03:55 +00:00
MemWrite ( & item - > plotData . name , ( uint64_t ) name ) ;
MemWrite ( & item - > plotData . time , GetTime ( ) ) ;
MemWrite ( & item - > plotData . type , PlotDataType : : Int ) ;
MemWrite ( & item - > plotData . data . i , val ) ;
2020-01-19 14:06:11 +00:00
TracyLfqCommit ;
2017-10-13 00:21:29 +00:00
}
static tracy_force_inline void PlotData ( const char * name , float val )
{
2018-07-10 21:06:27 +00:00
# ifdef TRACY_ON_DEMAND
2019-02-19 17:38:08 +00:00
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
2018-07-10 21:06:27 +00:00
# endif
2020-01-19 14:06:11 +00:00
TracyLfqPrepare ( QueueType : : PlotData ) ;
2018-03-31 12:03:55 +00:00
MemWrite ( & item - > plotData . name , ( uint64_t ) name ) ;
MemWrite ( & item - > plotData . time , GetTime ( ) ) ;
MemWrite ( & item - > plotData . type , PlotDataType : : Float ) ;
MemWrite ( & item - > plotData . data . f , val ) ;
2020-01-19 14:06:11 +00:00
TracyLfqCommit ;
2017-10-13 00:21:29 +00:00
}
2017-10-13 00:07:03 +00:00
static tracy_force_inline void PlotData ( const char * name , double val )
{
2018-07-10 21:06:27 +00:00
# ifdef TRACY_ON_DEMAND
2019-02-19 17:38:08 +00:00
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
2018-07-10 21:06:27 +00:00
# endif
2020-01-19 14:06:11 +00:00
TracyLfqPrepare ( QueueType : : PlotData ) ;
2018-03-31 12:03:55 +00:00
MemWrite ( & item - > plotData . name , ( uint64_t ) name ) ;
MemWrite ( & item - > plotData . time , GetTime ( ) ) ;
MemWrite ( & item - > plotData . type , PlotDataType : : Double ) ;
MemWrite ( & item - > plotData . data . d , val ) ;
2020-01-19 14:06:11 +00:00
TracyLfqCommit ;
2017-10-13 00:07:03 +00:00
}
2019-11-05 15:47:41 +00:00
static tracy_force_inline void ConfigurePlot ( const char * name , PlotFormatType type )
{
2020-01-19 14:06:11 +00:00
TracyLfqPrepare ( QueueType : : PlotConfig ) ;
2019-11-05 15:47:41 +00:00
MemWrite ( & item - > plotConfig . name , ( uint64_t ) name ) ;
MemWrite ( & item - > plotConfig . type , ( uint8_t ) type ) ;
# ifdef TRACY_ON_DEMAND
GetProfiler ( ) . DeferItem ( * item ) ;
# endif
2020-01-19 14:06:11 +00:00
TracyLfqCommit ;
2019-11-05 15:47:41 +00:00
}
2019-11-14 22:40:41 +00:00
static tracy_force_inline void Message ( const char * txt , size_t size , int callstack )
2017-10-14 11:23:13 +00:00
{
2020-07-21 18:22:59 +00:00
assert ( size < std : : numeric_limits < uint16_t > : : max ( ) ) ;
2018-07-10 21:09:59 +00:00
# ifdef TRACY_ON_DEMAND
2019-02-19 17:38:08 +00:00
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
2018-07-10 21:09:59 +00:00
# endif
2021-01-27 01:14:23 +00:00
if ( callstack ! = 0 )
{
tracy : : GetProfiler ( ) . SendCallstack ( callstack ) ;
}
2020-09-29 14:39:56 +00:00
2020-07-21 18:22:59 +00:00
auto ptr = ( char * ) tracy_malloc ( size ) ;
2017-10-14 11:23:13 +00:00
memcpy ( ptr , txt , size ) ;
2021-10-10 13:54:21 +00:00
TracyQueuePrepare ( callstack = = 0 ? QueueType : : Message : QueueType : : MessageCallstack ) ;
2020-07-21 18:22:59 +00:00
MemWrite ( & item - > messageFat . time , GetTime ( ) ) ;
MemWrite ( & item - > messageFat . text , ( uint64_t ) ptr ) ;
MemWrite ( & item - > messageFat . size , ( uint16_t ) size ) ;
2021-10-10 13:54:21 +00:00
TracyQueueCommit ( messageFatThread ) ;
2017-10-14 11:23:13 +00:00
}
2019-11-14 22:40:41 +00:00
static tracy_force_inline void Message ( const char * txt , int callstack )
2017-10-15 11:06:49 +00:00
{
2018-07-10 21:09:59 +00:00
# ifdef TRACY_ON_DEMAND
2019-02-19 17:38:08 +00:00
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
2018-07-10 21:09:59 +00:00
# endif
2021-01-27 01:14:23 +00:00
if ( callstack ! = 0 )
{
tracy : : GetProfiler ( ) . SendCallstack ( callstack ) ;
}
2020-09-29 14:39:56 +00:00
2021-10-10 13:54:21 +00:00
TracyQueuePrepare ( callstack = = 0 ? QueueType : : MessageLiteral : QueueType : : MessageLiteralCallstack ) ;
2020-07-25 23:15:11 +00:00
MemWrite ( & item - > messageLiteral . time , GetTime ( ) ) ;
MemWrite ( & item - > messageLiteral . text , ( uint64_t ) txt ) ;
2021-10-10 13:54:21 +00:00
TracyQueueCommit ( messageLiteralThread ) ;
2017-10-15 11:06:49 +00:00
}
2019-11-14 22:40:41 +00:00
static tracy_force_inline void MessageColor ( const char * txt , size_t size , uint32_t color , int callstack )
2019-05-10 18:17:44 +00:00
{
2020-07-21 18:22:59 +00:00
assert ( size < std : : numeric_limits < uint16_t > : : max ( ) ) ;
2019-05-10 18:17:44 +00:00
# ifdef TRACY_ON_DEMAND
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
# endif
2021-01-27 01:14:23 +00:00
if ( callstack ! = 0 )
{
tracy : : GetProfiler ( ) . SendCallstack ( callstack ) ;
}
2020-09-29 14:39:56 +00:00
2020-07-21 18:22:59 +00:00
auto ptr = ( char * ) tracy_malloc ( size ) ;
2019-05-10 18:17:44 +00:00
memcpy ( ptr , txt , size ) ;
2021-10-10 13:54:21 +00:00
TracyQueuePrepare ( callstack = = 0 ? QueueType : : MessageColor : QueueType : : MessageColorCallstack ) ;
2020-07-21 18:22:59 +00:00
MemWrite ( & item - > messageColorFat . time , GetTime ( ) ) ;
MemWrite ( & item - > messageColorFat . text , ( uint64_t ) ptr ) ;
MemWrite ( & item - > messageColorFat . r , uint8_t ( ( color ) & 0xFF ) ) ;
MemWrite ( & item - > messageColorFat . g , uint8_t ( ( color > > 8 ) & 0xFF ) ) ;
MemWrite ( & item - > messageColorFat . b , uint8_t ( ( color > > 16 ) & 0xFF ) ) ;
MemWrite ( & item - > messageColorFat . size , ( uint16_t ) size ) ;
2021-10-10 13:54:21 +00:00
TracyQueueCommit ( messageColorFatThread ) ;
2019-05-10 18:17:44 +00:00
}
2019-11-14 22:40:41 +00:00
static tracy_force_inline void MessageColor ( const char * txt , uint32_t color , int callstack )
2019-05-10 18:17:44 +00:00
{
# ifdef TRACY_ON_DEMAND
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
# endif
2021-01-27 01:14:23 +00:00
if ( callstack ! = 0 )
{
tracy : : GetProfiler ( ) . SendCallstack ( callstack ) ;
}
2020-09-29 14:39:56 +00:00
2021-10-10 13:54:21 +00:00
TracyQueuePrepare ( callstack = = 0 ? QueueType : : MessageLiteralColor : QueueType : : MessageLiteralColorCallstack ) ;
2020-07-25 23:15:11 +00:00
MemWrite ( & item - > messageColorLiteral . time , GetTime ( ) ) ;
MemWrite ( & item - > messageColorLiteral . text , ( uint64_t ) txt ) ;
MemWrite ( & item - > messageColorLiteral . r , uint8_t ( ( color ) & 0xFF ) ) ;
MemWrite ( & item - > messageColorLiteral . g , uint8_t ( ( color > > 8 ) & 0xFF ) ) ;
MemWrite ( & item - > messageColorLiteral . b , uint8_t ( ( color > > 16 ) & 0xFF ) ) ;
2021-10-10 13:54:21 +00:00
TracyQueueCommit ( messageColorLiteralThread ) ;
2019-05-10 18:17:44 +00:00
}
2019-07-12 16:14:42 +00:00
static tracy_force_inline void MessageAppInfo ( const char * txt , size_t size )
{
2020-07-25 23:15:11 +00:00
assert ( size < std : : numeric_limits < uint16_t > : : max ( ) ) ;
auto ptr = ( char * ) tracy_malloc ( size ) ;
2019-07-12 16:14:42 +00:00
memcpy ( ptr , txt , size ) ;
2020-01-19 14:06:11 +00:00
TracyLfqPrepare ( QueueType : : MessageAppInfo ) ;
2020-07-25 23:15:11 +00:00
MemWrite ( & item - > messageFat . time , GetTime ( ) ) ;
MemWrite ( & item - > messageFat . text , ( uint64_t ) ptr ) ;
MemWrite ( & item - > messageFat . size , ( uint16_t ) size ) ;
2019-07-12 16:14:42 +00:00
# ifdef TRACY_ON_DEMAND
GetProfiler ( ) . DeferItem ( * item ) ;
# endif
2020-01-19 14:06:11 +00:00
TracyLfqCommit ;
2019-07-12 16:14:42 +00:00
}
2020-06-23 23:33:26 +00:00
static tracy_force_inline void MemAlloc ( const void * ptr , size_t size , bool secure )
2018-03-31 19:56:05 +00:00
{
2020-06-23 23:33:26 +00:00
if ( secure & & ! ProfilerAvailable ( ) ) return ;
2018-07-11 23:36:01 +00:00
# ifdef TRACY_ON_DEMAND
2019-02-19 17:38:08 +00:00
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
2018-07-11 23:36:01 +00:00
# endif
2018-04-01 17:53:24 +00:00
const auto thread = GetThreadHandle ( ) ;
2019-02-19 17:38:08 +00:00
GetProfiler ( ) . m_serialLock . lock ( ) ;
2018-06-20 21:29:44 +00:00
SendMemAlloc ( QueueType : : MemAlloc , thread , ptr , size ) ;
2019-02-19 17:38:08 +00:00
GetProfiler ( ) . m_serialLock . unlock ( ) ;
2018-03-31 19:56:05 +00:00
}
2020-06-23 23:33:26 +00:00
static tracy_force_inline void MemFree ( const void * ptr , bool secure )
2018-03-31 19:56:05 +00:00
{
2020-06-23 23:33:26 +00:00
if ( secure & & ! ProfilerAvailable ( ) ) return ;
2018-07-11 23:36:01 +00:00
# ifdef TRACY_ON_DEMAND
2019-02-19 17:38:08 +00:00
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
2018-07-11 23:36:01 +00:00
# endif
2018-04-01 17:53:24 +00:00
const auto thread = GetThreadHandle ( ) ;
2019-02-19 17:38:08 +00:00
GetProfiler ( ) . m_serialLock . lock ( ) ;
2018-06-20 21:29:44 +00:00
SendMemFree ( QueueType : : MemFree , thread , ptr ) ;
2019-02-19 17:38:08 +00:00
GetProfiler ( ) . m_serialLock . unlock ( ) ;
2018-03-31 19:56:05 +00:00
}
2020-06-23 23:33:26 +00:00
static tracy_force_inline void MemAllocCallstack ( const void * ptr , size_t size , int depth , bool secure )
2018-06-19 16:51:21 +00:00
{
2020-06-23 23:33:26 +00:00
if ( secure & & ! ProfilerAvailable ( ) ) return ;
2018-06-22 21:00:03 +00:00
# ifdef TRACY_HAS_CALLSTACK
2019-10-05 00:11:45 +00:00
auto & profiler = GetProfiler ( ) ;
2018-07-11 23:36:01 +00:00
# ifdef TRACY_ON_DEMAND
2019-02-19 19:43:14 +00:00
if ( ! profiler . IsConnected ( ) ) return ;
2018-07-11 23:36:01 +00:00
# endif
2018-06-19 16:51:21 +00:00
const auto thread = GetThreadHandle ( ) ;
2018-06-22 21:00:03 +00:00
auto callstack = Callstack ( depth ) ;
2019-02-19 19:43:14 +00:00
profiler . m_serialLock . lock ( ) ;
2021-01-15 19:49:39 +00:00
SendCallstackSerial ( callstack ) ;
2020-09-29 14:39:56 +00:00
SendMemAlloc ( QueueType : : MemAllocCallstack , thread , ptr , size ) ;
2019-02-19 19:43:14 +00:00
profiler . m_serialLock . unlock ( ) ;
2018-06-22 21:00:03 +00:00
# else
2021-11-04 15:24:58 +00:00
static_cast < void > ( depth ) ; // unused
2020-07-02 15:17:01 +00:00
MemAlloc ( ptr , size , secure ) ;
2018-06-22 21:00:03 +00:00
# endif
2018-06-19 16:51:21 +00:00
}
2020-06-23 23:33:26 +00:00
static tracy_force_inline void MemFreeCallstack ( const void * ptr , int depth , bool secure )
2018-06-19 16:51:21 +00:00
{
2020-06-23 23:33:26 +00:00
if ( secure & & ! ProfilerAvailable ( ) ) return ;
2018-06-22 21:00:03 +00:00
# ifdef TRACY_HAS_CALLSTACK
2019-10-05 00:11:45 +00:00
auto & profiler = GetProfiler ( ) ;
2018-07-11 23:36:01 +00:00
# ifdef TRACY_ON_DEMAND
2019-02-19 19:43:14 +00:00
if ( ! profiler . IsConnected ( ) ) return ;
2018-07-11 23:36:01 +00:00
# endif
2018-06-19 16:51:21 +00:00
const auto thread = GetThreadHandle ( ) ;
2018-06-22 21:00:03 +00:00
auto callstack = Callstack ( depth ) ;
2019-02-19 19:43:14 +00:00
profiler . m_serialLock . lock ( ) ;
2021-01-15 19:49:39 +00:00
SendCallstackSerial ( callstack ) ;
2020-09-29 14:39:56 +00:00
SendMemFree ( QueueType : : MemFreeCallstack , thread , ptr ) ;
2019-02-19 19:43:14 +00:00
profiler . m_serialLock . unlock ( ) ;
2018-06-22 21:00:03 +00:00
# else
2021-11-04 15:24:58 +00:00
static_cast < void > ( depth ) ; // unused
2020-07-02 15:17:01 +00:00
MemFree ( ptr , secure ) ;
2018-06-22 21:00:03 +00:00
# endif
2018-06-19 16:51:21 +00:00
}
2020-09-22 16:22:34 +00:00
static tracy_force_inline void MemAllocNamed ( const void * ptr , size_t size , bool secure , const char * name )
{
if ( secure & & ! ProfilerAvailable ( ) ) return ;
# ifdef TRACY_ON_DEMAND
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
# endif
const auto thread = GetThreadHandle ( ) ;
GetProfiler ( ) . m_serialLock . lock ( ) ;
SendMemName ( name ) ;
SendMemAlloc ( QueueType : : MemAllocNamed , thread , ptr , size ) ;
GetProfiler ( ) . m_serialLock . unlock ( ) ;
}
static tracy_force_inline void MemFreeNamed ( const void * ptr , bool secure , const char * name )
{
if ( secure & & ! ProfilerAvailable ( ) ) return ;
# ifdef TRACY_ON_DEMAND
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
# endif
const auto thread = GetThreadHandle ( ) ;
GetProfiler ( ) . m_serialLock . lock ( ) ;
SendMemName ( name ) ;
SendMemFree ( QueueType : : MemFreeNamed , thread , ptr ) ;
GetProfiler ( ) . m_serialLock . unlock ( ) ;
}
static tracy_force_inline void MemAllocCallstackNamed ( const void * ptr , size_t size , int depth , bool secure , const char * name )
{
if ( secure & & ! ProfilerAvailable ( ) ) return ;
# ifdef TRACY_HAS_CALLSTACK
auto & profiler = GetProfiler ( ) ;
# ifdef TRACY_ON_DEMAND
if ( ! profiler . IsConnected ( ) ) return ;
# endif
const auto thread = GetThreadHandle ( ) ;
auto callstack = Callstack ( depth ) ;
profiler . m_serialLock . lock ( ) ;
2021-01-15 19:49:39 +00:00
SendCallstackSerial ( callstack ) ;
2020-09-22 16:22:34 +00:00
SendMemName ( name ) ;
SendMemAlloc ( QueueType : : MemAllocCallstackNamed , thread , ptr , size ) ;
profiler . m_serialLock . unlock ( ) ;
# else
2021-11-04 15:24:58 +00:00
static_cast < void > ( depth ) ; // unused
static_cast < void > ( name ) ; // unused
2020-09-22 16:22:34 +00:00
MemAlloc ( ptr , size , secure ) ;
# endif
}
static tracy_force_inline void MemFreeCallstackNamed ( const void * ptr , int depth , bool secure , const char * name )
{
if ( secure & & ! ProfilerAvailable ( ) ) return ;
# ifdef TRACY_HAS_CALLSTACK
auto & profiler = GetProfiler ( ) ;
# ifdef TRACY_ON_DEMAND
if ( ! profiler . IsConnected ( ) ) return ;
# endif
const auto thread = GetThreadHandle ( ) ;
auto callstack = Callstack ( depth ) ;
profiler . m_serialLock . lock ( ) ;
2021-01-15 19:49:39 +00:00
SendCallstackSerial ( callstack ) ;
2020-09-22 16:22:34 +00:00
SendMemName ( name ) ;
SendMemFree ( QueueType : : MemFreeCallstackNamed , thread , ptr ) ;
profiler . m_serialLock . unlock ( ) ;
# else
2021-11-04 15:24:58 +00:00
static_cast < void > ( depth ) ; // unused
static_cast < void > ( name ) ; // unused
2020-09-22 16:22:34 +00:00
MemFree ( ptr , secure ) ;
# endif
}
2019-07-29 22:42:31 +00:00
static tracy_force_inline void SendCallstack ( int depth )
2018-06-21 22:56:01 +00:00
{
# ifdef TRACY_HAS_CALLSTACK
auto ptr = Callstack ( depth ) ;
2021-10-10 14:14:17 +00:00
TracyQueuePrepare ( QueueType : : Callstack ) ;
2020-07-26 12:15:16 +00:00
MemWrite ( & item - > callstackFat . ptr , ( uint64_t ) ptr ) ;
2021-10-10 14:14:17 +00:00
TracyQueueCommit ( callstackFatThread ) ;
2021-11-04 15:24:58 +00:00
# else
static_cast < void > ( depth ) ; // unused
2018-06-21 22:56:01 +00:00
# endif
}
2020-01-25 15:51:17 +00:00
static tracy_force_inline void ParameterRegister ( ParameterCallback cb ) { GetProfiler ( ) . m_paramCallback = cb ; }
static tracy_force_inline void ParameterSetup ( uint32_t idx , const char * name , bool isBool , int32_t val )
{
TracyLfqPrepare ( QueueType : : ParamSetup ) ;
tracy : : MemWrite ( & item - > paramSetup . idx , idx ) ;
tracy : : MemWrite ( & item - > paramSetup . name , ( uint64_t ) name ) ;
tracy : : MemWrite ( & item - > paramSetup . isBool , ( uint8_t ) isBool ) ;
tracy : : MemWrite ( & item - > paramSetup . val , val ) ;
# ifdef TRACY_ON_DEMAND
GetProfiler ( ) . DeferItem ( * item ) ;
# endif
TracyLfqCommit ;
}
2019-11-25 22:59:48 +00:00
2021-11-01 22:56:19 +00:00
# ifdef TRACY_FIBERS
static tracy_force_inline void EnterFiber ( const char * fiber )
{
TracyQueuePrepare ( QueueType : : FiberEnter ) ;
MemWrite ( & item - > fiberEnter . time , GetTime ( ) ) ;
MemWrite ( & item - > fiberEnter . fiber , ( uint64_t ) fiber ) ;
TracyQueueCommit ( fiberEnter ) ;
}
static tracy_force_inline void LeaveFiber ( )
{
TracyQueuePrepare ( QueueType : : FiberLeave ) ;
MemWrite ( & item - > fiberLeave . time , GetTime ( ) ) ;
TracyQueueCommit ( fiberLeave ) ;
}
# endif
2019-07-29 22:42:31 +00:00
void SendCallstack ( int depth , const char * skipBefore ) ;
2019-03-05 01:15:13 +00:00
static void CutCallstack ( void * callstack , const char * skipBefore ) ;
2018-08-20 20:20:44 +00:00
2017-09-14 17:23:50 +00:00
static bool ShouldExit ( ) ;
2019-06-09 15:15:47 +00:00
tracy_force_inline bool IsConnected ( ) const
2018-07-10 19:50:00 +00:00
{
2019-06-09 14:48:00 +00:00
return m_isConnected . load ( std : : memory_order_acquire ) ;
2018-07-10 19:50:00 +00:00
}
2018-07-11 10:21:39 +00:00
2020-07-16 09:22:06 +00:00
# ifdef TRACY_ON_DEMAND
2019-06-09 15:15:47 +00:00
tracy_force_inline uint64_t ConnectionId ( ) const
{
return m_connectionId . load ( std : : memory_order_acquire ) ;
}
2018-07-11 10:21:39 +00:00
tracy_force_inline void DeferItem ( const QueueItem & item )
{
m_deferredLock . lock ( ) ;
auto dst = m_deferredQueue . push_next ( ) ;
memcpy ( dst , & item , sizeof ( item ) ) ;
m_deferredLock . unlock ( ) ;
}
2018-07-10 19:50:00 +00:00
# endif
2018-08-20 19:49:23 +00:00
void RequestShutdown ( ) { m_shutdown . store ( true , std : : memory_order_relaxed ) ; m_shutdownManual . store ( true , std : : memory_order_relaxed ) ; }
2018-08-19 23:02:27 +00:00
bool HasShutdownFinished ( ) const { return m_shutdownFinished . load ( std : : memory_order_relaxed ) ; }
2020-07-21 00:19:22 +00:00
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 ) ;
2020-07-25 21:13:01 +00:00
void SendSingleString ( const char * ptr ) { SendSingleString ( ptr , strlen ( ptr ) ) ; }
void SendSingleString ( const char * ptr , size_t len ) ;
2020-07-25 23:32:49 +00:00
void SendSecondString ( const char * ptr ) { SendSecondString ( ptr , strlen ( ptr ) ) ; }
void SendSecondString ( const char * ptr , size_t len ) ;
2019-08-16 17:22:23 +00:00
2019-12-05 23:15:46 +00:00
// Allocated source location data layout:
2020-07-05 15:11:15 +00:00
// 2b payload size
2019-12-05 23:15:46 +00:00
// 4b color
// 4b source line
// fsz function name
// 1b null terminator
// ssz source file name
// 1b null terminator
// nsz zone name (optional)
static tracy_force_inline uint64_t AllocSourceLocation ( uint32_t line , const char * source , const char * function )
{
2020-06-20 14:31:12 +00:00
return AllocSourceLocation ( line , source , function , nullptr , 0 ) ;
2019-12-05 23:15:46 +00:00
}
static tracy_force_inline uint64_t AllocSourceLocation ( uint32_t line , const char * source , const char * function , const char * name , size_t nameSz )
{
2020-06-20 14:31:12 +00:00
return AllocSourceLocation ( line , source , strlen ( source ) , function , strlen ( function ) , name , nameSz ) ;
}
static tracy_force_inline uint64_t AllocSourceLocation ( uint32_t line , const char * source , size_t sourceSz , const char * function , size_t functionSz )
{
return AllocSourceLocation ( line , source , sourceSz , function , functionSz , nullptr , 0 ) ;
}
static tracy_force_inline uint64_t AllocSourceLocation ( uint32_t line , const char * source , size_t sourceSz , const char * function , size_t functionSz , const char * name , size_t nameSz )
{
2020-07-05 15:11:15 +00:00
const auto sz32 = uint32_t ( 2 + 4 + 4 + functionSz + 1 + sourceSz + 1 + nameSz ) ;
assert ( sz32 < = std : : numeric_limits < uint16_t > : : max ( ) ) ;
const auto sz = uint16_t ( sz32 ) ;
2019-12-05 23:15:46 +00:00
auto ptr = ( char * ) tracy_malloc ( sz ) ;
2020-07-05 15:11:15 +00:00
memcpy ( ptr , & sz , 2 ) ;
memset ( ptr + 2 , 0 , 4 ) ;
memcpy ( ptr + 6 , & line , 4 ) ;
memcpy ( ptr + 10 , function , functionSz ) ;
ptr [ 10 + functionSz ] = ' \0 ' ;
memcpy ( ptr + 10 + functionSz + 1 , source , sourceSz ) ;
ptr [ 10 + functionSz + 1 + sourceSz ] = ' \0 ' ;
2020-06-20 14:31:12 +00:00
if ( nameSz ! = 0 )
{
2020-07-05 15:11:15 +00:00
memcpy ( ptr + 10 + functionSz + 1 + sourceSz + 1 , name , nameSz ) ;
2020-06-20 14:31:12 +00:00
}
2019-12-05 23:15:46 +00:00
return uint64_t ( ptr ) ;
}
2017-09-10 15:43:56 +00:00
private :
2019-11-14 17:24:29 +00:00
enum class DequeueStatus { DataDequeued , ConnectionLost , QueueEmpty } ;
2021-10-09 13:16:36 +00:00
enum class ThreadCtxStatus { Same , Changed , ConnectionLost } ;
2017-10-18 16:48:51 +00:00
2017-10-16 19:13:57 +00:00
static void LaunchWorker ( void * ptr ) { ( ( Profiler * ) ptr ) - > Worker ( ) ; }
2017-09-10 15:43:56 +00:00
void Worker ( ) ;
2021-04-29 18:55:16 +00:00
# ifndef TRACY_NO_FRAME_IMAGE
2019-06-26 20:57:24 +00:00
static void LaunchCompressWorker ( void * ptr ) { ( ( Profiler * ) ptr ) - > CompressWorker ( ) ; }
void CompressWorker ( ) ;
2021-04-29 18:55:16 +00:00
# endif
2019-06-26 20:57:24 +00:00
2021-10-22 20:25:09 +00:00
# ifdef TRACY_HAS_CALLSTACK
static void LaunchSymbolWorker ( void * ptr ) { ( ( Profiler * ) ptr ) - > SymbolWorker ( ) ; }
void SymbolWorker ( ) ;
2021-10-22 23:35:01 +00:00
void HandleSymbolQueueItem ( const SymbolQueueItem & si ) ;
2021-10-22 20:25:09 +00:00
# endif
2018-07-13 18:01:27 +00:00
void ClearQueues ( tracy : : moodycamel : : ConsumerToken & token ) ;
2019-08-14 20:39:12 +00:00
void ClearSerial ( ) ;
2018-07-13 18:01:27 +00:00
DequeueStatus Dequeue ( tracy : : moodycamel : : ConsumerToken & token ) ;
2019-08-14 21:06:13 +00:00
DequeueStatus DequeueContextSwitches ( tracy : : moodycamel : : ConsumerToken & token , int64_t & timeStop ) ;
2018-04-01 18:04:35 +00:00
DequeueStatus DequeueSerial ( ) ;
2021-10-09 13:16:36 +00:00
ThreadCtxStatus ThreadCtxCheck ( uint32_t threadId ) ;
2017-11-11 13:16:37 +00:00
bool CommitData ( ) ;
2020-02-23 13:44:19 +00:00
tracy_force_inline bool AppendData ( const void * data , size_t len )
{
const auto ret = NeedDataSize ( len ) ;
AppendDataUnsafe ( data , len ) ;
return ret ;
}
tracy_force_inline bool NeedDataSize ( size_t len )
{
assert ( len < = TargetFrameSize ) ;
bool ret = true ;
2020-11-19 15:36:01 +00:00
if ( m_bufferOffset - m_bufferStart + ( int ) len > TargetFrameSize )
2020-02-23 13:44:19 +00:00
{
ret = CommitData ( ) ;
}
return ret ;
}
2017-10-18 16:48:51 +00:00
2018-06-23 00:16:58 +00:00
tracy_force_inline void AppendDataUnsafe ( const void * data , size_t len )
{
memcpy ( m_buffer + m_bufferOffset , data , len ) ;
m_bufferOffset + = int ( len ) ;
}
2017-09-14 17:07:56 +00:00
bool SendData ( const char * data , size_t len ) ;
2019-06-06 22:22:00 +00:00
void SendLongString ( uint64_t ptr , const char * str , size_t len , QueueType type ) ;
2017-09-26 17:00:25 +00:00
void SendSourceLocation ( uint64_t ptr ) ;
2018-06-19 17:00:57 +00:00
void SendSourceLocationPayload ( uint64_t ptr ) ;
2018-06-19 17:09:43 +00:00
void SendCallstackPayload ( uint64_t ptr ) ;
2020-02-22 13:05:01 +00:00
void SendCallstackPayload64 ( uint64_t ptr ) ;
2019-02-28 19:30:07 +00:00
void SendCallstackAlloc ( uint64_t ptr ) ;
2021-10-22 20:25:09 +00:00
void QueueCallstackFrame ( uint64_t ptr ) ;
void QueueSymbolQuery ( uint64_t symbol ) ;
void QueueCodeLocation ( uint64_t ptr ) ;
void QueueExternalName ( uint64_t ptr ) ;
2021-11-25 21:27:35 +00:00
void QueueKernelCode ( uint64_t symbol , uint32_t size ) ;
2017-09-21 23:54:04 +00:00
bool HandleServerQuery ( ) ;
2019-08-01 21:14:09 +00:00
void HandleDisconnect ( ) ;
2019-11-25 22:59:48 +00:00
void HandleParameter ( uint64_t payload ) ;
2020-03-25 19:04:55 +00:00
void HandleSymbolCodeQuery ( uint64_t symbol , uint32_t size ) ;
2021-02-03 23:03:25 +00:00
void HandleSourceCodeQuery ( ) ;
2017-09-14 17:07:56 +00:00
2021-02-07 19:53:20 +00:00
void AckServerQuery ( ) ;
void AckSourceCodeNotAvailable ( ) ;
2021-11-25 21:44:56 +00:00
void AckSymbolCodeNotAvailable ( ) ;
2021-02-07 19:53:20 +00:00
2017-09-23 19:33:05 +00:00
void CalibrateTimer ( ) ;
2017-09-24 14:02:09 +00:00
void CalibrateDelay ( ) ;
2019-11-29 17:29:09 +00:00
void ReportTopology ( ) ;
2017-09-23 19:33:05 +00:00
2021-01-15 19:49:39 +00:00
static tracy_force_inline void SendCallstackSerial ( void * ptr )
2018-06-20 21:30:19 +00:00
{
# ifdef TRACY_HAS_CALLSTACK
2019-02-19 17:38:08 +00:00
auto item = GetProfiler ( ) . m_serialQueue . prepare_next ( ) ;
2021-01-15 19:49:39 +00:00
MemWrite ( & item - > hdr . type , QueueType : : CallstackSerial ) ;
2020-07-26 12:15:16 +00:00
MemWrite ( & item - > callstackFat . ptr , ( uint64_t ) ptr ) ;
2019-02-19 17:38:08 +00:00
GetProfiler ( ) . m_serialQueue . commit_next ( ) ;
2021-11-04 15:24:58 +00:00
# else
static_cast < void > ( ptr ) ; // unused
2018-06-20 21:30:19 +00:00
# endif
}
2021-10-07 22:42:52 +00:00
static tracy_force_inline void SendMemAlloc ( QueueType type , const uint32_t thread , const void * ptr , size_t size )
2018-06-20 21:29:44 +00:00
{
2020-09-22 16:22:34 +00:00
assert ( type = = QueueType : : MemAlloc | | type = = QueueType : : MemAllocCallstack | | type = = QueueType : : MemAllocNamed | | type = = QueueType : : MemAllocCallstackNamed ) ;
2018-06-20 21:29:44 +00:00
2019-02-19 17:38:08 +00:00
auto item = GetProfiler ( ) . m_serialQueue . prepare_next ( ) ;
2018-06-20 21:29:44 +00:00
MemWrite ( & item - > hdr . type , type ) ;
MemWrite ( & item - > memAlloc . time , GetTime ( ) ) ;
MemWrite ( & item - > memAlloc . thread , thread ) ;
MemWrite ( & item - > memAlloc . ptr , ( uint64_t ) ptr ) ;
2018-08-01 12:07:30 +00:00
if ( compile_time_condition < sizeof ( size ) = = 4 > : : value )
2018-06-20 21:29:44 +00:00
{
memcpy ( & item - > memAlloc . size , & size , 4 ) ;
memset ( & item - > memAlloc . size + 4 , 0 , 2 ) ;
}
else
{
assert ( sizeof ( size ) = = 8 ) ;
2020-04-13 11:45:21 +00:00
memcpy ( & item - > memAlloc . size , & size , 4 ) ;
memcpy ( ( ( char * ) & item - > memAlloc . size ) + 4 , ( ( char * ) & size ) + 4 , 2 ) ;
2018-06-20 21:29:44 +00:00
}
2019-02-19 17:38:08 +00:00
GetProfiler ( ) . m_serialQueue . commit_next ( ) ;
2018-06-20 21:29:44 +00:00
}
2021-10-07 22:42:52 +00:00
static tracy_force_inline void SendMemFree ( QueueType type , const uint32_t thread , const void * ptr )
2018-06-20 21:29:44 +00:00
{
2020-09-22 16:22:34 +00:00
assert ( type = = QueueType : : MemFree | | type = = QueueType : : MemFreeCallstack | | type = = QueueType : : MemFreeNamed | | type = = QueueType : : MemFreeCallstackNamed ) ;
2018-06-20 21:29:44 +00:00
2019-02-19 17:38:08 +00:00
auto item = GetProfiler ( ) . m_serialQueue . prepare_next ( ) ;
2018-06-20 21:29:44 +00:00
MemWrite ( & item - > hdr . type , type ) ;
MemWrite ( & item - > memFree . time , GetTime ( ) ) ;
MemWrite ( & item - > memFree . thread , thread ) ;
MemWrite ( & item - > memFree . ptr , ( uint64_t ) ptr ) ;
2019-02-19 17:38:08 +00:00
GetProfiler ( ) . m_serialQueue . commit_next ( ) ;
2018-06-20 21:29:44 +00:00
}
2020-09-22 16:22:34 +00:00
static tracy_force_inline void SendMemName ( const char * name )
{
assert ( name ) ;
auto item = GetProfiler ( ) . m_serialQueue . prepare_next ( ) ;
MemWrite ( & item - > hdr . type , QueueType : : MemNamePayload ) ;
MemWrite ( & item - > memName . name , ( uint64_t ) name ) ;
GetProfiler ( ) . m_serialQueue . commit_next ( ) ;
}
2021-10-07 21:28:40 +00:00
# if defined _WIN32 && defined TRACY_TIMER_QPC
2020-04-07 20:01:31 +00:00
static int64_t GetTimeQpc ( ) ;
# endif
2017-09-23 19:33:05 +00:00
double m_timerMul ;
2017-09-29 16:29:39 +00:00
uint64_t m_resolution ;
2017-09-24 14:02:09 +00:00
uint64_t m_delay ;
2017-10-16 23:07:54 +00:00
std : : atomic < int64_t > m_timeBegin ;
2021-10-07 22:42:52 +00:00
uint32_t m_mainThread ;
2021-01-31 16:42:44 +00:00
uint64_t m_epoch , m_exectime ;
2017-09-10 15:43:56 +00:00
std : : atomic < bool > m_shutdown ;
2018-08-20 19:49:23 +00:00
std : : atomic < bool > m_shutdownManual ;
2018-08-19 23:02:27 +00:00
std : : atomic < bool > m_shutdownFinished ;
2017-10-18 17:49:17 +00:00
Socket * m_sock ;
2019-06-17 00:25:09 +00:00
UdpBroadcast * m_broadcast ;
2018-07-13 21:55:40 +00:00
bool m_noExit ;
2020-03-08 15:14:36 +00:00
uint32_t m_userPort ;
2019-01-14 21:23:24 +00:00
std : : atomic < uint32_t > m_zoneId ;
2020-02-25 22:08:52 +00:00
int64_t m_samplingPeriod ;
2017-09-17 11:10:42 +00:00
2021-10-07 22:42:52 +00:00
uint32_t m_threadCtx ;
2019-10-23 22:04:31 +00:00
int64_t m_refTimeThread ;
int64_t m_refTimeSerial ;
2019-10-25 17:13:11 +00:00
int64_t m_refTimeCtx ;
2019-10-25 17:52:01 +00:00
int64_t m_refTimeGpu ;
2019-08-02 18:18:08 +00:00
2019-05-01 10:57:42 +00:00
void * m_stream ; // LZ4_stream_t*
2017-09-17 11:10:42 +00:00
char * m_buffer ;
int m_bufferOffset ;
2017-11-11 13:16:37 +00:00
int m_bufferStart ;
2017-11-02 11:56:13 +00:00
2017-11-02 16:37:10 +00:00
char * m_lz4Buf ;
2018-04-01 17:53:05 +00:00
2018-04-14 13:46:11 +00:00
FastVector < QueueItem > m_serialQueue , m_serialDequeue ;
2018-07-13 22:39:01 +00:00
TracyMutex m_serialLock ;
2018-07-10 19:50:00 +00:00
2021-04-29 18:55:16 +00:00
# ifndef TRACY_NO_FRAME_IMAGE
2021-10-20 21:18:03 +00:00
FastVector < FrameImageQueueItem > m_fiQueue , m_fiDequeue ;
TracyMutex m_fiLock ;
2021-04-29 18:55:16 +00:00
# endif
2019-06-26 20:50:56 +00:00
2021-11-14 17:50:59 +00:00
SPSCQueue < SymbolQueueItem > m_symbolQueue ;
2021-10-22 20:22:27 +00:00
2019-06-26 21:18:30 +00:00
std : : atomic < uint64_t > m_frameCount ;
2018-07-10 19:50:00 +00:00
std : : atomic < bool > m_isConnected ;
2020-07-16 09:22:06 +00:00
# ifdef TRACY_ON_DEMAND
2019-06-09 15:15:47 +00:00
std : : atomic < uint64_t > m_connectionId ;
2018-07-11 10:14:28 +00:00
2018-07-13 22:39:01 +00:00
TracyMutex m_deferredLock ;
2018-07-11 10:14:28 +00:00
FastVector < QueueItem > m_deferredQueue ;
2018-07-10 19:50:00 +00:00
# endif
2019-02-21 20:59:02 +00:00
# ifdef TRACY_HAS_SYSTIME
void ProcessSysTime ( ) ;
SysTime m_sysTime ;
uint64_t m_sysTimeLast = 0 ;
# else
void ProcessSysTime ( ) { }
# endif
2019-11-25 22:59:48 +00:00
ParameterCallback m_paramCallback ;
2021-02-03 23:03:25 +00:00
char * m_queryData ;
char * m_queryDataPtr ;
2021-07-25 09:40:22 +00:00
2021-10-07 21:28:40 +00:00
# if defined _WIN32
2021-07-25 09:48:27 +00:00
void * m_exceptionHandler ;
# endif
2021-07-25 09:40:22 +00:00
# ifdef __linux__
struct {
struct sigaction pwr , ill , fpe , segv , pipe , bus , abrt ;
} m_prevSignal ;
# endif
2021-07-25 09:46:20 +00:00
bool m_crashHandlerInstalled ;
2017-09-10 15:43:56 +00:00
} ;
2020-05-10 13:32:39 +00:00
}
2017-09-10 15:43:56 +00:00
# endif