mudgangster

Tiny, scriptable MUD client
Log | Files | Refs | README

TracyProfiler.hpp (20328B)


      1 #ifndef __TRACYPROFILER_HPP__
      2 #define __TRACYPROFILER_HPP__
      3 
      4 #include <assert.h>
      5 #include <atomic>
      6 #include <stdint.h>
      7 #include <string.h>
      8 
      9 #include "tracy_concurrentqueue.h"
     10 #include "TracyCallstack.hpp"
     11 #include "TracySysTime.hpp"
     12 #include "TracyFastVector.hpp"
     13 #include "../common/TracyQueue.hpp"
     14 #include "../common/TracyAlign.hpp"
     15 #include "../common/TracyAlloc.hpp"
     16 #include "../common/TracyMutex.hpp"
     17 
     18 #if defined _WIN32 || defined __CYGWIN__
     19 #  include <intrin.h>
     20 #endif
     21 #ifdef __APPLE__
     22 #  include <TargetConditionals.h>
     23 #  include <mach/mach_time.h>
     24 #endif
     25 
     26 #if defined _WIN32 || defined __CYGWIN__ || ( ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) && !defined __ANDROID__ ) || __ARM_ARCH >= 6
     27 #  define TRACY_HW_TIMER
     28 #endif
     29 
     30 #if !defined TRACY_HW_TIMER || ( __ARM_ARCH >= 6 && !defined CLOCK_MONOTONIC_RAW )
     31   #include <chrono>
     32 #endif
     33 
     34 #ifndef TracyConcat
     35 #  define TracyConcat(x,y) TracyConcatIndirect(x,y)
     36 #endif
     37 #ifndef TracyConcatIndirect
     38 #  define TracyConcatIndirect(x,y) x##y
     39 #endif
     40 
     41 namespace tracy
     42 {
     43 
     44 class GpuCtx;
     45 class Profiler;
     46 class Socket;
     47 class UdpBroadcast;
     48 
     49 struct GpuCtxWrapper
     50 {
     51     GpuCtx* ptr;
     52 };
     53 
     54 TRACY_API moodycamel::ConcurrentQueue<QueueItem>::ExplicitProducer* GetToken();
     55 TRACY_API Profiler& GetProfiler();
     56 TRACY_API std::atomic<uint32_t>& GetLockCounter();
     57 TRACY_API std::atomic<uint8_t>& GetGpuCtxCounter();
     58 TRACY_API GpuCtxWrapper& GetGpuCtx();
     59 TRACY_API uint64_t GetThreadHandle();
     60 
     61 TRACY_API void InitRPMallocThread();
     62 
     63 struct SourceLocationData
     64 {
     65     const char* name;
     66     const char* function;
     67     const char* file;
     68     uint32_t line;
     69     uint32_t color;
     70 };
     71 
     72 #ifdef TRACY_ON_DEMAND
     73 struct LuaZoneState
     74 {
     75     uint32_t counter;
     76     bool active;
     77 };
     78 #endif
     79 
     80 using Magic = moodycamel::ConcurrentQueueDefaultTraits::index_t;
     81 
     82 
     83 typedef void(*ParameterCallback)( uint32_t idx, int32_t val );
     84 
     85 class Profiler
     86 {
     87     struct FrameImageQueueItem
     88     {
     89         void* image;
     90         uint64_t frame;
     91         uint16_t w;
     92         uint16_t h;
     93         uint8_t offset;
     94         bool flip;
     95     };
     96 
     97 public:
     98     Profiler();
     99     ~Profiler();
    100 
    101     static tracy_force_inline int64_t GetTime()
    102     {
    103 #ifdef TRACY_HW_TIMER
    104 #  if TARGET_OS_IOS == 1
    105         return mach_absolute_time();
    106 #  elif __ARM_ARCH >= 6
    107 #    ifdef CLOCK_MONOTONIC_RAW
    108         struct timespec ts;
    109         clock_gettime( CLOCK_MONOTONIC_RAW, &ts );
    110         return int64_t( ts.tv_sec ) * 1000000000ll + int64_t( ts.tv_nsec );
    111 #    else
    112         return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
    113 #    endif
    114 #  elif defined _WIN32 || defined __CYGWIN__
    115         return int64_t( __rdtsc() );
    116 #  elif defined __i386 || defined _M_IX86
    117         uint32_t eax, edx;
    118         asm volatile ( "rdtsc" : "=a" (eax), "=d" (edx) );
    119         return ( uint64_t( edx ) << 32 ) + uint64_t( eax );
    120 #  elif defined __x86_64__ || defined _M_X64
    121         uint64_t rax, rdx;
    122         asm volatile ( "rdtsc" : "=a" (rax), "=d" (rdx) );
    123         return ( rdx << 32 ) + rax;
    124 #  endif
    125 #else
    126         return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
    127 #endif
    128     }
    129 
    130     tracy_force_inline uint32_t GetNextZoneId()
    131     {
    132         return m_zoneId.fetch_add( 1, std::memory_order_relaxed );
    133     }
    134 
    135     static tracy_force_inline QueueItem* QueueSerial()
    136     {
    137         auto& p = GetProfiler();
    138         p.m_serialLock.lock();
    139         return p.m_serialQueue.prepare_next();
    140     }
    141 
    142     static tracy_force_inline void QueueSerialFinish()
    143     {
    144         auto& p = GetProfiler();
    145         p.m_serialQueue.commit_next();
    146         p.m_serialLock.unlock();
    147     }
    148 
    149     static tracy_force_inline void SendFrameMark( const char* name )
    150     {
    151         if( !name ) GetProfiler().m_frameCount.fetch_add( 1, std::memory_order_relaxed );
    152 #ifdef TRACY_ON_DEMAND
    153         if( !GetProfiler().IsConnected() ) return;
    154 #endif
    155         Magic magic;
    156         auto token = GetToken();
    157         auto& tail = token->get_tail_index();
    158         auto item = token->enqueue_begin( magic );
    159         MemWrite( &item->hdr.type, QueueType::FrameMarkMsg );
    160         MemWrite( &item->frameMark.time, GetTime() );
    161         MemWrite( &item->frameMark.name, uint64_t( name ) );
    162         tail.store( magic + 1, std::memory_order_release );
    163     }
    164 
    165     static tracy_force_inline void SendFrameMark( const char* name, QueueType type )
    166     {
    167         assert( type == QueueType::FrameMarkMsgStart || type == QueueType::FrameMarkMsgEnd );
    168 #ifdef TRACY_ON_DEMAND
    169         if( !GetProfiler().IsConnected() ) return;
    170 #endif
    171         auto item = QueueSerial();
    172         MemWrite( &item->hdr.type, type );
    173         MemWrite( &item->frameMark.time, GetTime() );
    174         MemWrite( &item->frameMark.name, uint64_t( name ) );
    175         QueueSerialFinish();
    176     }
    177 
    178     static tracy_force_inline void SendFrameImage( const void* image, uint16_t w, uint16_t h, uint8_t offset, bool flip )
    179     {
    180         auto& profiler = GetProfiler();
    181 #ifdef TRACY_ON_DEMAND
    182         if( !profiler.IsConnected() ) return;
    183 #endif
    184         const auto sz = size_t( w ) * size_t( h ) * 4;
    185         auto ptr = (char*)tracy_malloc( sz );
    186         memcpy( ptr, image, sz );
    187 
    188         profiler.m_fiLock.lock();
    189         auto fi = profiler.m_fiQueue.prepare_next();
    190         fi->image = ptr;
    191         fi->frame = profiler.m_frameCount.load( std::memory_order_relaxed ) - offset;
    192         fi->w = w;
    193         fi->h = h;
    194         fi->flip = flip;
    195         profiler.m_fiQueue.commit_next();
    196         profiler.m_fiLock.unlock();
    197     }
    198 
    199     static tracy_force_inline void PlotData( const char* name, int64_t val )
    200     {
    201 #ifdef TRACY_ON_DEMAND
    202         if( !GetProfiler().IsConnected() ) return;
    203 #endif
    204         Magic magic;
    205         auto token = GetToken();
    206         auto& tail = token->get_tail_index();
    207         auto item = token->enqueue_begin( magic );
    208         MemWrite( &item->hdr.type, QueueType::PlotData );
    209         MemWrite( &item->plotData.name, (uint64_t)name );
    210         MemWrite( &item->plotData.time, GetTime() );
    211         MemWrite( &item->plotData.type, PlotDataType::Int );
    212         MemWrite( &item->plotData.data.i, val );
    213         tail.store( magic + 1, std::memory_order_release );
    214     }
    215 
    216     static tracy_force_inline void PlotData( const char* name, float val )
    217     {
    218 #ifdef TRACY_ON_DEMAND
    219         if( !GetProfiler().IsConnected() ) return;
    220 #endif
    221         Magic magic;
    222         auto token = GetToken();
    223         auto& tail = token->get_tail_index();
    224         auto item = token->enqueue_begin( magic );
    225         MemWrite( &item->hdr.type, QueueType::PlotData );
    226         MemWrite( &item->plotData.name, (uint64_t)name );
    227         MemWrite( &item->plotData.time, GetTime() );
    228         MemWrite( &item->plotData.type, PlotDataType::Float );
    229         MemWrite( &item->plotData.data.f, val );
    230         tail.store( magic + 1, std::memory_order_release );
    231     }
    232 
    233     static tracy_force_inline void PlotData( const char* name, double val )
    234     {
    235 #ifdef TRACY_ON_DEMAND
    236         if( !GetProfiler().IsConnected() ) return;
    237 #endif
    238         Magic magic;
    239         auto token = GetToken();
    240         auto& tail = token->get_tail_index();
    241         auto item = token->enqueue_begin( magic );
    242         MemWrite( &item->hdr.type, QueueType::PlotData );
    243         MemWrite( &item->plotData.name, (uint64_t)name );
    244         MemWrite( &item->plotData.time, GetTime() );
    245         MemWrite( &item->plotData.type, PlotDataType::Double );
    246         MemWrite( &item->plotData.data.d, val );
    247         tail.store( magic + 1, std::memory_order_release );
    248     }
    249 
    250     static tracy_force_inline void ConfigurePlot( const char* name, PlotFormatType type )
    251     {
    252         Magic magic;
    253         auto token = GetToken();
    254         auto& tail = token->get_tail_index();
    255         auto item = token->enqueue_begin( magic );
    256         MemWrite( &item->hdr.type, QueueType::PlotConfig );
    257         MemWrite( &item->plotConfig.name, (uint64_t)name );
    258         MemWrite( &item->plotConfig.type, (uint8_t)type );
    259 
    260 #ifdef TRACY_ON_DEMAND
    261         GetProfiler().DeferItem( *item );
    262 #endif
    263 
    264         tail.store( magic + 1, std::memory_order_release );
    265     }
    266 
    267     static tracy_force_inline void Message( const char* txt, size_t size, int callstack )
    268     {
    269 #ifdef TRACY_ON_DEMAND
    270         if( !GetProfiler().IsConnected() ) return;
    271 #endif
    272         Magic magic;
    273         auto token = GetToken();
    274         auto ptr = (char*)tracy_malloc( size+1 );
    275         memcpy( ptr, txt, size );
    276         ptr[size] = '\0';
    277         auto& tail = token->get_tail_index();
    278         auto item = token->enqueue_begin( magic );
    279         MemWrite( &item->hdr.type, callstack == 0 ? QueueType::Message : QueueType::MessageCallstack );
    280         MemWrite( &item->message.time, GetTime() );
    281         MemWrite( &item->message.text, (uint64_t)ptr );
    282         tail.store( magic + 1, std::memory_order_release );
    283 
    284         if( callstack != 0 ) tracy::GetProfiler().SendCallstack( callstack );
    285     }
    286 
    287     static tracy_force_inline void Message( const char* txt, int callstack )
    288     {
    289 #ifdef TRACY_ON_DEMAND
    290         if( !GetProfiler().IsConnected() ) return;
    291 #endif
    292         Magic magic;
    293         auto token = GetToken();
    294         auto& tail = token->get_tail_index();
    295         auto item = token->enqueue_begin( magic );
    296         MemWrite( &item->hdr.type, callstack == 0 ? QueueType::MessageLiteral : QueueType::MessageLiteralCallstack );
    297         MemWrite( &item->message.time, GetTime() );
    298         MemWrite( &item->message.text, (uint64_t)txt );
    299         tail.store( magic + 1, std::memory_order_release );
    300 
    301         if( callstack != 0 ) tracy::GetProfiler().SendCallstack( callstack );
    302     }
    303 
    304     static tracy_force_inline void MessageColor( const char* txt, size_t size, uint32_t color, int callstack )
    305     {
    306 #ifdef TRACY_ON_DEMAND
    307         if( !GetProfiler().IsConnected() ) return;
    308 #endif
    309         Magic magic;
    310         auto token = GetToken();
    311         auto ptr = (char*)tracy_malloc( size+1 );
    312         memcpy( ptr, txt, size );
    313         ptr[size] = '\0';
    314         auto& tail = token->get_tail_index();
    315         auto item = token->enqueue_begin( magic );
    316         MemWrite( &item->hdr.type, callstack == 0 ? QueueType::MessageColor : QueueType::MessageColorCallstack );
    317         MemWrite( &item->messageColor.time, GetTime() );
    318         MemWrite( &item->messageColor.text, (uint64_t)ptr );
    319         MemWrite( &item->messageColor.r, uint8_t( ( color       ) & 0xFF ) );
    320         MemWrite( &item->messageColor.g, uint8_t( ( color >> 8  ) & 0xFF ) );
    321         MemWrite( &item->messageColor.b, uint8_t( ( color >> 16 ) & 0xFF ) );
    322         tail.store( magic + 1, std::memory_order_release );
    323 
    324         if( callstack != 0 ) tracy::GetProfiler().SendCallstack( callstack );
    325     }
    326 
    327     static tracy_force_inline void MessageColor( const char* txt, uint32_t color, int callstack )
    328     {
    329 #ifdef TRACY_ON_DEMAND
    330         if( !GetProfiler().IsConnected() ) return;
    331 #endif
    332         Magic magic;
    333         auto token = GetToken();
    334         auto& tail = token->get_tail_index();
    335         auto item = token->enqueue_begin( magic );
    336         MemWrite( &item->hdr.type, callstack == 0 ? QueueType::MessageLiteralColor : QueueType::MessageLiteralColorCallstack );
    337         MemWrite( &item->messageColor.time, GetTime() );
    338         MemWrite( &item->messageColor.text, (uint64_t)txt );
    339         MemWrite( &item->messageColor.r, uint8_t( ( color       ) & 0xFF ) );
    340         MemWrite( &item->messageColor.g, uint8_t( ( color >> 8  ) & 0xFF ) );
    341         MemWrite( &item->messageColor.b, uint8_t( ( color >> 16 ) & 0xFF ) );
    342         tail.store( magic + 1, std::memory_order_release );
    343 
    344         if( callstack != 0 ) tracy::GetProfiler().SendCallstack( callstack );
    345     }
    346 
    347     static tracy_force_inline void MessageAppInfo( const char* txt, size_t size )
    348     {
    349         Magic magic;
    350         auto token = GetToken();
    351         auto ptr = (char*)tracy_malloc( size+1 );
    352         memcpy( ptr, txt, size );
    353         ptr[size] = '\0';
    354         auto& tail = token->get_tail_index();
    355         auto item = token->enqueue_begin( magic );
    356         MemWrite( &item->hdr.type, QueueType::MessageAppInfo );
    357         MemWrite( &item->message.time, GetTime() );
    358         MemWrite( &item->message.text, (uint64_t)ptr );
    359 
    360 #ifdef TRACY_ON_DEMAND
    361         GetProfiler().DeferItem( *item );
    362 #endif
    363 
    364         tail.store( magic + 1, std::memory_order_release );
    365     }
    366 
    367     static tracy_force_inline void MemAlloc( const void* ptr, size_t size )
    368     {
    369 #ifdef TRACY_ON_DEMAND
    370         if( !GetProfiler().IsConnected() ) return;
    371 #endif
    372         const auto thread = GetThreadHandle();
    373 
    374         GetProfiler().m_serialLock.lock();
    375         SendMemAlloc( QueueType::MemAlloc, thread, ptr, size );
    376         GetProfiler().m_serialLock.unlock();
    377     }
    378 
    379     static tracy_force_inline void MemFree( const void* ptr )
    380     {
    381 #ifdef TRACY_ON_DEMAND
    382         if( !GetProfiler().IsConnected() ) return;
    383 #endif
    384         const auto thread = GetThreadHandle();
    385 
    386         GetProfiler().m_serialLock.lock();
    387         SendMemFree( QueueType::MemFree, thread, ptr );
    388         GetProfiler().m_serialLock.unlock();
    389     }
    390 
    391     static tracy_force_inline void MemAllocCallstack( const void* ptr, size_t size, int depth )
    392     {
    393 #ifdef TRACY_HAS_CALLSTACK
    394         auto& profiler = GetProfiler();
    395 #  ifdef TRACY_ON_DEMAND
    396         if( !profiler.IsConnected() ) return;
    397 #  endif
    398         const auto thread = GetThreadHandle();
    399 
    400         rpmalloc_thread_initialize();
    401         auto callstack = Callstack( depth );
    402 
    403         profiler.m_serialLock.lock();
    404         SendMemAlloc( QueueType::MemAllocCallstack, thread, ptr, size );
    405         SendCallstackMemory( callstack );
    406         profiler.m_serialLock.unlock();
    407 #else
    408         MemAlloc( ptr, size );
    409 #endif
    410     }
    411 
    412     static tracy_force_inline void MemFreeCallstack( const void* ptr, int depth )
    413     {
    414 #ifdef TRACY_HAS_CALLSTACK
    415         auto& profiler = GetProfiler();
    416 #  ifdef TRACY_ON_DEMAND
    417         if( !profiler.IsConnected() ) return;
    418 #  endif
    419         const auto thread = GetThreadHandle();
    420 
    421         rpmalloc_thread_initialize();
    422         auto callstack = Callstack( depth );
    423 
    424         profiler.m_serialLock.lock();
    425         SendMemFree( QueueType::MemFreeCallstack, thread, ptr );
    426         SendCallstackMemory( callstack );
    427         profiler.m_serialLock.unlock();
    428 #else
    429         MemFree( ptr );
    430 #endif
    431     }
    432 
    433     static tracy_force_inline void SendCallstack( int depth )
    434     {
    435 #ifdef TRACY_HAS_CALLSTACK
    436         auto ptr = Callstack( depth );
    437         Magic magic;
    438         auto token = GetToken();
    439         auto& tail = token->get_tail_index();
    440         auto item = token->enqueue_begin( magic );
    441         MemWrite( &item->hdr.type, QueueType::Callstack );
    442         MemWrite( &item->callstack.ptr, ptr );
    443         tail.store( magic + 1, std::memory_order_release );
    444 #endif
    445     }
    446 
    447     static void ParameterRegister( ParameterCallback cb ) { GetProfiler().m_paramCallback = cb; }
    448     static void ParameterSetup( uint32_t idx, const char* name, bool isBool, int32_t val );
    449 
    450     void SendCallstack( int depth, const char* skipBefore );
    451     static void CutCallstack( void* callstack, const char* skipBefore );
    452 
    453     static bool ShouldExit();
    454 
    455 #ifdef TRACY_ON_DEMAND
    456     tracy_force_inline bool IsConnected() const
    457     {
    458         return m_isConnected.load( std::memory_order_acquire );
    459     }
    460 
    461     tracy_force_inline uint64_t ConnectionId() const
    462     {
    463         return m_connectionId.load( std::memory_order_acquire );
    464     }
    465 
    466     tracy_force_inline void DeferItem( const QueueItem& item )
    467     {
    468         m_deferredLock.lock();
    469         auto dst = m_deferredQueue.push_next();
    470         memcpy( dst, &item, sizeof( item ) );
    471         m_deferredLock.unlock();
    472     }
    473 #endif
    474 
    475     void RequestShutdown() { m_shutdown.store( true, std::memory_order_relaxed ); m_shutdownManual.store( true, std::memory_order_relaxed ); }
    476     bool HasShutdownFinished() const { return m_shutdownFinished.load( std::memory_order_relaxed ); }
    477 
    478     void SendString( uint64_t ptr, const char* str, QueueType type );
    479 
    480 private:
    481     enum class DequeueStatus { DataDequeued, ConnectionLost, QueueEmpty };
    482 
    483     static void LaunchWorker( void* ptr ) { ((Profiler*)ptr)->Worker(); }
    484     void Worker();
    485 
    486     static void LaunchCompressWorker( void* ptr ) { ((Profiler*)ptr)->CompressWorker(); }
    487     void CompressWorker();
    488 
    489     void ClearQueues( tracy::moodycamel::ConsumerToken& token );
    490     void ClearSerial();
    491     DequeueStatus Dequeue( tracy::moodycamel::ConsumerToken& token );
    492     DequeueStatus DequeueContextSwitches( tracy::moodycamel::ConsumerToken& token, int64_t& timeStop );
    493     DequeueStatus DequeueSerial();
    494     bool AppendData( const void* data, size_t len );
    495     bool CommitData();
    496     bool NeedDataSize( size_t len );
    497 
    498     tracy_force_inline void AppendDataUnsafe( const void* data, size_t len )
    499     {
    500         memcpy( m_buffer + m_bufferOffset, data, len );
    501         m_bufferOffset += int( len );
    502     }
    503 
    504     bool SendData( const char* data, size_t len );
    505     void SendLongString( uint64_t ptr, const char* str, size_t len, QueueType type );
    506     void SendSourceLocation( uint64_t ptr );
    507     void SendSourceLocationPayload( uint64_t ptr );
    508     void SendCallstackPayload( uint64_t ptr );
    509     void SendCallstackAlloc( uint64_t ptr );
    510     void SendCallstackFrame( uint64_t ptr );
    511 
    512     bool HandleServerQuery();
    513     void HandleDisconnect();
    514     void HandleParameter( uint64_t payload );
    515 
    516     void CalibrateTimer();
    517     void CalibrateDelay();
    518 
    519     static tracy_force_inline void SendCallstackMemory( void* ptr )
    520     {
    521 #ifdef TRACY_HAS_CALLSTACK
    522         auto item = GetProfiler().m_serialQueue.prepare_next();
    523         MemWrite( &item->hdr.type, QueueType::CallstackMemory );
    524         MemWrite( &item->callstackMemory.ptr, (uint64_t)ptr );
    525         GetProfiler().m_serialQueue.commit_next();
    526 #endif
    527     }
    528 
    529     static tracy_force_inline void SendMemAlloc( QueueType type, const uint64_t thread, const void* ptr, size_t size )
    530     {
    531         assert( type == QueueType::MemAlloc || type == QueueType::MemAllocCallstack );
    532 
    533         auto item = GetProfiler().m_serialQueue.prepare_next();
    534         MemWrite( &item->hdr.type, type );
    535         MemWrite( &item->memAlloc.time, GetTime() );
    536         MemWrite( &item->memAlloc.thread, thread );
    537         MemWrite( &item->memAlloc.ptr, (uint64_t)ptr );
    538         if( compile_time_condition<sizeof( size ) == 4>::value )
    539         {
    540             memcpy( &item->memAlloc.size, &size, 4 );
    541             memset( &item->memAlloc.size + 4, 0, 2 );
    542         }
    543         else
    544         {
    545             assert( sizeof( size ) == 8 );
    546             memcpy( &item->memAlloc.size, &size, 6 );
    547         }
    548         GetProfiler().m_serialQueue.commit_next();
    549     }
    550 
    551     static tracy_force_inline void SendMemFree( QueueType type, const uint64_t thread, const void* ptr )
    552     {
    553         assert( type == QueueType::MemFree || type == QueueType::MemFreeCallstack );
    554 
    555         auto item = GetProfiler().m_serialQueue.prepare_next();
    556         MemWrite( &item->hdr.type, type );
    557         MemWrite( &item->memFree.time, GetTime() );
    558         MemWrite( &item->memFree.thread, thread );
    559         MemWrite( &item->memFree.ptr, (uint64_t)ptr );
    560         GetProfiler().m_serialQueue.commit_next();
    561     }
    562 
    563     double m_timerMul;
    564     uint64_t m_resolution;
    565     uint64_t m_delay;
    566     std::atomic<int64_t> m_timeBegin;
    567     uint64_t m_mainThread;
    568     uint64_t m_epoch;
    569     std::atomic<bool> m_shutdown;
    570     std::atomic<bool> m_shutdownManual;
    571     std::atomic<bool> m_shutdownFinished;
    572     Socket* m_sock;
    573     UdpBroadcast* m_broadcast;
    574     bool m_noExit;
    575     std::atomic<uint32_t> m_zoneId;
    576 
    577     uint64_t m_threadCtx;
    578     int64_t m_refTimeThread;
    579     int64_t m_refTimeSerial;
    580     int64_t m_refTimeCtx;
    581     int64_t m_refTimeGpu;
    582 
    583     void* m_stream;     // LZ4_stream_t*
    584     char* m_buffer;
    585     int m_bufferOffset;
    586     int m_bufferStart;
    587 
    588     QueueItem* m_itemBuf;
    589     char* m_lz4Buf;
    590 
    591     FastVector<QueueItem> m_serialQueue, m_serialDequeue;
    592     TracyMutex m_serialLock;
    593 
    594     FastVector<FrameImageQueueItem> m_fiQueue, m_fiDequeue;
    595     TracyMutex m_fiLock;
    596 
    597     std::atomic<uint64_t> m_frameCount;
    598 #ifdef TRACY_ON_DEMAND
    599     std::atomic<bool> m_isConnected;
    600     std::atomic<uint64_t> m_connectionId;
    601 
    602     TracyMutex m_deferredLock;
    603     FastVector<QueueItem> m_deferredQueue;
    604 #endif
    605 
    606 #ifdef TRACY_HAS_SYSTIME
    607     void ProcessSysTime();
    608 
    609     SysTime m_sysTime;
    610     uint64_t m_sysTimeLast = 0;
    611 #else
    612     void ProcessSysTime() {}
    613 #endif
    614 
    615     ParameterCallback m_paramCallback;
    616 };
    617 
    618 };
    619 
    620 #endif