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-25 22:42:09 +00:00
# include <chrono>
2017-09-10 18:08:42 +00:00
# include <stdint.h>
2017-10-14 15:20:37 +00:00
# include <string.h>
2017-09-10 15:43:56 +00:00
2017-10-03 12:19:32 +00:00
# include "concurrentqueue.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"
2017-11-11 18:44:09 +00:00
# include "../common/TracySystem.hpp"
2017-09-10 18:09:14 +00:00
2019-01-19 11:03:30 +00:00
# if defined _WIN32 || defined __CYGWIN__
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
2019-01-19 11:03:30 +00:00
# if defined _WIN32 || defined __CYGWIN__ || ( ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) && !defined __ANDROID__ ) || __ARM_ARCH >= 6
2018-04-26 14:03:31 +00:00
# define TRACY_HW_TIMER
2019-01-19 11:03:30 +00:00
# if defined _WIN32 || defined __CYGWIN__
2018-04-27 17:40:47 +00:00
// Enable optimization for MSVC __rdtscp() intrin, saving one LHS of a cpu value on the stack.
// This comes at the cost of an unaligned memory write.
# define TRACY_RDTSCP_OPT
# endif
2018-04-26 14:03:31 +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
{
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-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 ( ) ;
2017-10-03 12:19:32 +00:00
2019-06-11 21:51:12 +00:00
TRACY_API void InitRPMallocThread ( ) ;
2019-02-19 19:43:14 +00:00
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
2019-02-19 17:45:41 +00:00
using Magic = moodycamel : : ConcurrentQueueDefaultTraits : : index_t ;
2017-10-03 12:50:55 +00:00
2019-02-21 13:45:13 +00:00
# if __ARM_ARCH >= 6 && !defined TARGET_OS_IOS
2018-04-27 14:58:45 +00:00
extern int64_t ( * GetTimeImpl ) ( ) ;
# endif
2018-04-01 17:53:05 +00:00
2017-09-10 15:43:56 +00:00
class Profiler
{
public :
Profiler ( ) ;
~ Profiler ( ) ;
2018-04-26 13:30:53 +00:00
static tracy_force_inline int64_t GetTime ( uint32_t & cpu )
2017-09-25 22:42:09 +00:00
{
2018-04-26 13:30:53 +00:00
# ifdef TRACY_HW_TIMER
2019-02-21 13:45:13 +00:00
# if TARGET_OS_IOS == 1
cpu = 0xFFFFFFFF ;
return mach_absolute_time ( ) ;
# elif __ARM_ARCH >= 6
2018-04-26 15:17:37 +00:00
cpu = 0xFFFFFFFF ;
2018-04-27 14:58:45 +00:00
return GetTimeImpl ( ) ;
2019-01-19 11:03:30 +00:00
# elif defined _WIN32 || defined __CYGWIN__
2017-10-10 21:21:30 +00:00
const auto t = int64_t ( __rdtscp ( & cpu ) ) ;
2017-10-01 17:11:01 +00:00
return t ;
2018-04-26 13:30:53 +00:00
# elif defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64
2017-10-29 12:15:43 +00:00
uint32_t eax , edx ;
2017-10-10 21:21:30 +00:00
asm volatile ( " rdtscp " : " =a " ( eax ) , " =d " ( edx ) , " =c " ( cpu ) : : ) ;
2017-10-29 12:15:43 +00:00
return ( uint64_t ( edx ) < < 32 ) + uint64_t ( eax ) ;
2018-04-26 13:30:53 +00:00
# endif
# else
cpu = 0xFFFFFFFF ;
return std : : chrono : : duration_cast < std : : chrono : : nanoseconds > ( std : : chrono : : high_resolution_clock : : now ( ) . time_since_epoch ( ) ) . count ( ) ;
2017-10-03 13:35:43 +00:00
# endif
}
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
2019-02-21 13:45:13 +00:00
# if TARGET_OS_IOS == 1
return mach_absolute_time ( ) ;
# elif __ARM_ARCH >= 6
2018-04-27 14:58:45 +00:00
return GetTimeImpl ( ) ;
2019-01-19 11:03:30 +00:00
# elif defined _WIN32 || defined __CYGWIN__
2018-04-26 14:12:52 +00:00
unsigned int dontcare ;
2017-10-29 15:12:16 +00:00
const auto t = int64_t ( __rdtscp ( & dontcare ) ) ;
return t ;
2018-04-26 13:30:53 +00:00
# elif defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64
2017-10-29 15:12:16 +00:00
uint32_t eax , edx ;
2017-10-29 15:20:07 +00:00
asm volatile ( " rdtscp " : " =a " ( eax ) , " =d " ( edx ) : : " %ecx " ) ;
2017-10-29 15:12:16 +00:00
return ( uint64_t ( edx ) < < 32 ) + uint64_t ( eax ) ;
2018-04-26 13:30:53 +00:00
# endif
2017-10-29 15:12:16 +00:00
# else
return std : : chrono : : duration_cast < std : : chrono : : nanoseconds > ( std : : chrono : : high_resolution_clock : : now ( ) . time_since_epoch ( ) ) . count ( ) ;
# endif
}
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-02-28 18:21:23 +00:00
static tracy_force_inline void SendFrameMark ( const char * name )
2017-10-03 12:19:32 +00:00
{
2018-07-10 20:23:27 +00:00
# ifdef TRACY_ON_DEMAND
2019-06-09 13:23:01 +00:00
if ( ! name ) GetProfiler ( ) . m_frameCount . fetch_add ( 1 , std : : memory_order_relaxed ) ;
2019-02-19 17:38:08 +00:00
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
2018-07-10 20:23:27 +00:00
# endif
2017-10-03 12:50:55 +00:00
Magic magic ;
2019-02-19 17:27:00 +00:00
auto token = GetToken ( ) ;
2017-10-10 23:27:22 +00:00
auto & tail = token - > get_tail_index ( ) ;
2018-07-13 18:01:27 +00:00
auto item = token - > enqueue_begin < tracy : : moodycamel : : CanAlloc > ( magic ) ;
2018-03-31 12:03:55 +00:00
MemWrite ( & item - > hdr . type , QueueType : : FrameMarkMsg ) ;
MemWrite ( & item - > frameMark . time , GetTime ( ) ) ;
2019-02-28 18:21:23 +00:00
MemWrite ( & item - > frameMark . name , uint64_t ( name ) ) ;
2017-10-10 23:27:22 +00:00
tail . store ( magic + 1 , std : : memory_order_release ) ;
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-02-28 18:21:23 +00:00
GetProfiler ( ) . m_serialLock . lock ( ) ;
auto item = GetProfiler ( ) . m_serialQueue . prepare_next ( ) ;
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-02-28 18:21:23 +00:00
GetProfiler ( ) . m_serialQueue . commit_next ( ) ;
GetProfiler ( ) . m_serialLock . unlock ( ) ;
2018-08-04 13:04:18 +00:00
}
2019-06-07 18:09:29 +00:00
static tracy_force_inline void SendFrameImage ( void * image , uint16_t w , uint16_t h , uint8_t offset )
2019-06-06 19:39:54 +00:00
{
# ifdef TRACY_ON_DEMAND
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
# endif
const auto sz = size_t ( w ) * size_t ( h ) * 4 ;
Magic magic ;
auto token = GetToken ( ) ;
auto ptr = ( char * ) tracy_malloc ( sz ) ;
memcpy ( ptr , image , sz ) ;
auto & tail = token - > get_tail_index ( ) ;
auto item = token - > enqueue_begin < tracy : : moodycamel : : CanAlloc > ( magic ) ;
MemWrite ( & item - > hdr . type , QueueType : : FrameImage ) ;
MemWrite ( & item - > frameImage . image , ( uint64_t ) ptr ) ;
MemWrite ( & item - > frameImage . w , w ) ;
MemWrite ( & item - > frameImage . h , h ) ;
2019-06-07 18:09:29 +00:00
MemWrite ( & item - > frameImage . offset , offset ) ;
2019-06-06 19:39:54 +00:00
tail . store ( magic + 1 , std : : memory_order_release ) ;
}
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
2017-10-13 00:21:29 +00:00
Magic magic ;
2019-02-19 17:27:00 +00:00
auto token = GetToken ( ) ;
2017-10-13 00:21:29 +00:00
auto & tail = token - > get_tail_index ( ) ;
2018-07-13 18:01:27 +00:00
auto item = token - > enqueue_begin < tracy : : moodycamel : : CanAlloc > ( magic ) ;
2018-03-31 12:03:55 +00:00
MemWrite ( & item - > hdr . type , QueueType : : PlotData ) ;
MemWrite ( & item - > plotData . name , ( uint64_t ) name ) ;
MemWrite ( & item - > plotData . time , GetTime ( ) ) ;
MemWrite ( & item - > plotData . type , PlotDataType : : Int ) ;
MemWrite ( & item - > plotData . data . i , val ) ;
2017-10-13 00:21:29 +00:00
tail . store ( magic + 1 , std : : memory_order_release ) ;
}
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
2017-10-13 00:21:29 +00:00
Magic magic ;
2019-02-19 17:27:00 +00:00
auto token = GetToken ( ) ;
2017-10-13 00:21:29 +00:00
auto & tail = token - > get_tail_index ( ) ;
2018-07-13 18:01:27 +00:00
auto item = token - > enqueue_begin < tracy : : moodycamel : : CanAlloc > ( magic ) ;
2018-03-31 12:03:55 +00:00
MemWrite ( & item - > hdr . type , QueueType : : PlotData ) ;
MemWrite ( & item - > plotData . name , ( uint64_t ) name ) ;
MemWrite ( & item - > plotData . time , GetTime ( ) ) ;
MemWrite ( & item - > plotData . type , PlotDataType : : Float ) ;
MemWrite ( & item - > plotData . data . f , val ) ;
2017-10-13 00:21:29 +00:00
tail . store ( magic + 1 , std : : memory_order_release ) ;
}
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
2017-10-13 00:07:03 +00:00
Magic magic ;
2019-02-19 17:27:00 +00:00
auto token = GetToken ( ) ;
2017-10-13 00:07:03 +00:00
auto & tail = token - > get_tail_index ( ) ;
2018-07-13 18:01:27 +00:00
auto item = token - > enqueue_begin < tracy : : moodycamel : : CanAlloc > ( magic ) ;
2018-03-31 12:03:55 +00:00
MemWrite ( & item - > hdr . type , QueueType : : PlotData ) ;
MemWrite ( & item - > plotData . name , ( uint64_t ) name ) ;
MemWrite ( & item - > plotData . time , GetTime ( ) ) ;
MemWrite ( & item - > plotData . type , PlotDataType : : Double ) ;
MemWrite ( & item - > plotData . data . d , val ) ;
2017-10-13 00:07:03 +00:00
tail . store ( magic + 1 , std : : memory_order_release ) ;
}
2017-10-14 11:23:13 +00:00
static tracy_force_inline void Message ( const char * txt , size_t size )
{
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
2017-10-14 11:23:13 +00:00
Magic magic ;
2019-02-19 17:27:00 +00:00
auto token = GetToken ( ) ;
2017-10-14 15:15:18 +00:00
auto ptr = ( char * ) tracy_malloc ( size + 1 ) ;
2017-10-14 11:23:13 +00:00
memcpy ( ptr , txt , size ) ;
ptr [ size ] = ' \0 ' ;
auto & tail = token - > get_tail_index ( ) ;
2018-07-13 18:01:27 +00:00
auto item = token - > enqueue_begin < tracy : : moodycamel : : CanAlloc > ( magic ) ;
2018-03-31 12:03:55 +00:00
MemWrite ( & item - > hdr . type , QueueType : : Message ) ;
MemWrite ( & item - > message . time , GetTime ( ) ) ;
MemWrite ( & item - > message . thread , GetThreadHandle ( ) ) ;
MemWrite ( & item - > message . text , ( uint64_t ) ptr ) ;
2017-10-14 11:23:13 +00:00
tail . store ( magic + 1 , std : : memory_order_release ) ;
}
2017-10-15 11:06:49 +00:00
static tracy_force_inline void Message ( const char * txt )
{
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
2017-10-15 11:06:49 +00:00
Magic magic ;
2019-02-19 17:27:00 +00:00
auto token = GetToken ( ) ;
2017-10-15 11:06:49 +00:00
auto & tail = token - > get_tail_index ( ) ;
2018-07-13 18:01:27 +00:00
auto item = token - > enqueue_begin < tracy : : moodycamel : : CanAlloc > ( magic ) ;
2018-03-31 12:03:55 +00:00
MemWrite ( & item - > hdr . type , QueueType : : MessageLiteral ) ;
MemWrite ( & item - > message . time , GetTime ( ) ) ;
MemWrite ( & item - > message . thread , GetThreadHandle ( ) ) ;
MemWrite ( & item - > message . text , ( uint64_t ) txt ) ;
2017-10-15 11:06:49 +00:00
tail . store ( magic + 1 , std : : memory_order_release ) ;
}
2019-05-10 18:17:44 +00:00
static tracy_force_inline void MessageColor ( const char * txt , size_t size , uint32_t color )
{
# ifdef TRACY_ON_DEMAND
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
# endif
Magic magic ;
auto token = GetToken ( ) ;
auto ptr = ( char * ) tracy_malloc ( size + 1 ) ;
memcpy ( ptr , txt , size ) ;
ptr [ size ] = ' \0 ' ;
auto & tail = token - > get_tail_index ( ) ;
auto item = token - > enqueue_begin < tracy : : moodycamel : : CanAlloc > ( magic ) ;
MemWrite ( & item - > hdr . type , QueueType : : MessageColor ) ;
MemWrite ( & item - > messageColor . time , GetTime ( ) ) ;
MemWrite ( & item - > messageColor . thread , GetThreadHandle ( ) ) ;
MemWrite ( & item - > messageColor . text , ( uint64_t ) ptr ) ;
MemWrite ( & item - > messageColor . r , uint8_t ( ( color ) & 0xFF ) ) ;
MemWrite ( & item - > messageColor . g , uint8_t ( ( color > > 8 ) & 0xFF ) ) ;
MemWrite ( & item - > messageColor . b , uint8_t ( ( color > > 16 ) & 0xFF ) ) ;
tail . store ( magic + 1 , std : : memory_order_release ) ;
}
static tracy_force_inline void MessageColor ( const char * txt , uint32_t color )
{
# ifdef TRACY_ON_DEMAND
if ( ! GetProfiler ( ) . IsConnected ( ) ) return ;
# endif
Magic magic ;
auto token = GetToken ( ) ;
auto & tail = token - > get_tail_index ( ) ;
auto item = token - > enqueue_begin < tracy : : moodycamel : : CanAlloc > ( magic ) ;
MemWrite ( & item - > hdr . type , QueueType : : MessageLiteralColor ) ;
MemWrite ( & item - > messageColor . time , GetTime ( ) ) ;
MemWrite ( & item - > messageColor . thread , GetThreadHandle ( ) ) ;
MemWrite ( & item - > messageColor . text , ( uint64_t ) txt ) ;
MemWrite ( & item - > messageColor . r , uint8_t ( ( color ) & 0xFF ) ) ;
MemWrite ( & item - > messageColor . g , uint8_t ( ( color > > 8 ) & 0xFF ) ) ;
MemWrite ( & item - > messageColor . b , uint8_t ( ( color > > 16 ) & 0xFF ) ) ;
tail . store ( magic + 1 , std : : memory_order_release ) ;
}
2018-03-31 19:56:05 +00:00
static tracy_force_inline void MemAlloc ( const void * ptr , size_t size )
{
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
}
static tracy_force_inline void MemFree ( const void * ptr )
{
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
}
2018-06-19 16:51:21 +00:00
static tracy_force_inline void MemAllocCallstack ( const void * ptr , size_t size , int depth )
{
2019-02-19 19:43:14 +00:00
auto & profiler = GetProfiler ( ) ;
2018-06-22 21:00:03 +00:00
# ifdef TRACY_HAS_CALLSTACK
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-21 15:02:40 +00:00
rpmalloc_thread_initialize ( ) ;
2018-06-22 21:00:03 +00:00
auto callstack = Callstack ( depth ) ;
2019-02-19 19:43:14 +00:00
profiler . m_serialLock . lock ( ) ;
2018-06-20 21:29:44 +00:00
SendMemAlloc ( QueueType : : MemAllocCallstack , thread , ptr , size ) ;
2018-06-22 21:00:03 +00:00
SendCallstackMemory ( callstack ) ;
2019-02-19 19:43:14 +00:00
profiler . m_serialLock . unlock ( ) ;
2018-06-22 21:00:03 +00:00
# else
MemAlloc ( ptr , size ) ;
# endif
2018-06-19 16:51:21 +00:00
}
static tracy_force_inline void MemFreeCallstack ( const void * ptr , int depth )
{
2019-02-19 19:43:14 +00:00
auto & profiler = GetProfiler ( ) ;
2018-06-22 21:00:03 +00:00
# ifdef TRACY_HAS_CALLSTACK
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-21 15:02:40 +00:00
rpmalloc_thread_initialize ( ) ;
2018-06-22 21:00:03 +00:00
auto callstack = Callstack ( depth ) ;
2019-02-19 19:43:14 +00:00
profiler . m_serialLock . lock ( ) ;
2018-06-20 21:29:44 +00:00
SendMemFree ( QueueType : : MemFreeCallstack , thread , ptr ) ;
2018-06-22 21:00:03 +00:00
SendCallstackMemory ( callstack ) ;
2019-02-19 19:43:14 +00:00
profiler . m_serialLock . unlock ( ) ;
2018-06-22 21:00:03 +00:00
# else
MemFree ( ptr ) ;
# endif
2018-06-19 16:51:21 +00:00
}
2018-06-21 22:56:01 +00:00
static tracy_force_inline void SendCallstack ( int depth , uint64_t thread )
{
# ifdef TRACY_HAS_CALLSTACK
auto ptr = Callstack ( depth ) ;
Magic magic ;
2019-02-19 17:27:00 +00:00
auto token = GetToken ( ) ;
2018-06-21 22:56:01 +00:00
auto & tail = token - > get_tail_index ( ) ;
2018-07-13 18:01:27 +00:00
auto item = token - > enqueue_begin < tracy : : moodycamel : : CanAlloc > ( magic ) ;
2018-06-21 22:56:01 +00:00
MemWrite ( & item - > hdr . type , QueueType : : Callstack ) ;
MemWrite ( & item - > callstack . ptr , ptr ) ;
MemWrite ( & item - > callstack . thread , thread ) ;
tail . store ( magic + 1 , std : : memory_order_release ) ;
# endif
}
2018-08-20 20:20:44 +00:00
void SendCallstack ( int depth , uint64_t thread , 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 ( ) ;
2018-07-10 19:50:00 +00:00
# ifdef TRACY_ON_DEMAND
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
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 ) ; }
2017-09-10 15:43:56 +00:00
private :
2019-06-09 14:14:30 +00:00
enum class DequeueStatus { Success , ConnectionLost , QueueEmpty } ;
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 ( ) ;
2018-07-13 18:01:27 +00:00
void ClearQueues ( tracy : : moodycamel : : ConsumerToken & token ) ;
DequeueStatus Dequeue ( tracy : : moodycamel : : ConsumerToken & token ) ;
2018-04-01 18:04:35 +00:00
DequeueStatus DequeueSerial ( ) ;
2017-11-11 13:16:37 +00:00
bool AppendData ( const void * data , size_t len ) ;
bool CommitData ( ) ;
2017-11-11 14:08:03 +00:00
bool NeedDataSize ( size_t len ) ;
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 ) ;
2018-06-19 17:00:57 +00:00
void SendString ( uint64_t ptr , const char * str , QueueType type ) ;
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 ) ;
2019-02-28 19:30:07 +00:00
void SendCallstackAlloc ( uint64_t ptr ) ;
2018-06-19 23:06:31 +00:00
void SendCallstackFrame ( uint64_t ptr ) ;
2017-09-21 23:54:04 +00:00
bool HandleServerQuery ( ) ;
2017-09-14 17:07:56 +00:00
2017-09-23 19:33:05 +00:00
void CalibrateTimer ( ) ;
2017-09-24 14:02:09 +00:00
void CalibrateDelay ( ) ;
2017-09-23 19:33:05 +00:00
2018-06-22 21:00:03 +00:00
static tracy_force_inline void SendCallstackMemory ( 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 ( ) ;
2018-06-20 21:30:19 +00:00
MemWrite ( & item - > hdr . type , QueueType : : CallstackMemory ) ;
MemWrite ( & item - > callstackMemory . ptr , ( uint64_t ) ptr ) ;
2019-02-19 17:38:08 +00:00
GetProfiler ( ) . m_serialQueue . commit_next ( ) ;
2018-06-20 21:30:19 +00:00
# endif
}
2018-06-20 21:29:44 +00:00
static tracy_force_inline void SendMemAlloc ( QueueType type , const uint64_t thread , const void * ptr , size_t size )
{
assert ( type = = QueueType : : MemAlloc | | type = = QueueType : : MemAllocCallstack ) ;
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 ) ;
memcpy ( & item - > memAlloc . size , & size , 6 ) ;
}
2019-02-19 17:38:08 +00:00
GetProfiler ( ) . m_serialQueue . commit_next ( ) ;
2018-06-20 21:29:44 +00:00
}
static tracy_force_inline void SendMemFree ( QueueType type , const uint64_t thread , const void * ptr )
{
assert ( type = = QueueType : : MemFree | | type = = QueueType : : MemFreeCallstack ) ;
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
}
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 ;
2017-09-22 23:37:07 +00:00
uint64_t m_mainThread ;
2017-10-03 22:34:05 +00:00
uint64_t m_epoch ;
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 ;
2018-07-13 21:55:40 +00:00
bool m_noExit ;
2019-01-14 21:23:24 +00:00
std : : atomic < uint32_t > m_zoneId ;
2017-09-17 11:10:42 +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
QueueItem * m_itemBuf ;
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
2019-06-06 23:29:24 +00:00
char * m_etc1Buf ;
size_t m_etc1BufSize ;
2018-07-10 19:50:00 +00:00
# ifdef TRACY_ON_DEMAND
std : : atomic < bool > m_isConnected ;
2018-07-10 20:26:40 +00:00
std : : atomic < uint64_t > m_frameCount ;
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
2017-09-10 15:43:56 +00:00
} ;
} ;
# endif