VR-Vantage 3.0 API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TracyProfiler.hpp
Go to the documentation of this file.
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 #include <time.h>
9 
10 #include "tracy_concurrentqueue.h"
11 #include "TracyCallstack.hpp"
12 #include "TracySysTime.hpp"
13 #include "TracyFastVector.hpp"
14 #include "../common/TracyQueue.hpp"
15 #include "../common/TracyAlign.hpp"
16 #include "../common/TracyAlloc.hpp"
17 #include "../common/TracyMutex.hpp"
18 #include "../common/TracyProtocol.hpp"
19 
20 #if defined _WIN32 || defined __CYGWIN__
21 # include <intrin.h>
22 #endif
23 #ifdef __APPLE__
24 # include <TargetConditionals.h>
25 # include <mach/mach_time.h>
26 #endif
27 
28 #if !defined TRACY_TIMER_FALLBACK && ( defined _WIN32 || defined __CYGWIN__ || ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) || ( defined TARGET_OS_IOS && TARGET_OS_IOS == 1 ) )
29 # define TRACY_HW_TIMER
30 #endif
31 
32 #if !defined TRACY_HW_TIMER
33 # include <chrono>
34 #endif
35 
36 #ifndef TracyConcat
37 # define TracyConcat(x,y) TracyConcatIndirect(x,y)
38 #endif
39 #ifndef TracyConcatIndirect
40 # define TracyConcatIndirect(x,y) x##y
41 #endif
42 
43 namespace tracy
44 {
45 #if defined(TRACY_DELAYED_INIT) && defined(TRACY_MANUAL_LIFETIME)
46 TRACY_API void StartupProfiler();
47 TRACY_API void ShutdownProfiler();
48 #endif
49 
50 class GpuCtx;
51 class Profiler;
52 class Socket;
53 class UdpBroadcast;
54 
56 {
57  GpuCtx* ptr;
58 };
59 
62 TRACY_API std::atomic<uint32_t>& GetLockCounter();
63 TRACY_API std::atomic<uint8_t>& GetGpuCtxCounter();
69 
71 
73 {
74  const char* name;
75  const char* function;
76  const char* file;
79 };
80 
81 #ifdef TRACY_ON_DEMAND
82 struct LuaZoneState
83 {
85  bool active;
86 };
87 #endif
88 
89 
90 #define TracyLfqPrepare( _type ) \
91  moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \
92  auto __token = GetToken(); \
93  auto& __tail = __token->get_tail_index(); \
94  auto item = __token->enqueue_begin( __magic ); \
95  MemWrite( &item->hdr.type, _type );
96 
97 #define TracyLfqCommit \
98  __tail.store( __magic + 1, std::memory_order_release );
99 
100 #define TracyLfqPrepareC( _type ) \
101  tracy::moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \
102  auto __token = tracy::GetToken(); \
103  auto& __tail = __token->get_tail_index(); \
104  auto item = __token->enqueue_begin( __magic ); \
105  tracy::MemWrite( &item->hdr.type, _type );
106 
107 #define TracyLfqCommitC \
108  __tail.store( __magic + 1, std::memory_order_release );
109 
110 
112 
113 class Profiler
114 {
116  {
117  void* image;
122  bool flip;
123  };
124 
125 public:
126  Profiler();
127  ~Profiler();
128 
129  void SpawnWorkerThreads();
130 
132  {
133 #ifdef TRACY_HW_TIMER
134 # if defined TARGET_OS_IOS && TARGET_OS_IOS == 1
135  return mach_absolute_time();
136 # elif defined _WIN32 || defined __CYGWIN__
137 # ifdef TRACY_TIMER_QPC
138  return GetTimeQpc();
139 # else
140  return int64_t( __rdtsc() );
141 # endif
142 # elif defined __i386 || defined _M_IX86
143  uint32_t eax, edx;
144  asm volatile ( "rdtsc" : "=a" (eax), "=d" (edx) );
145  return ( uint64_t( edx ) << 32 ) + uint64_t( eax );
146 # elif defined __x86_64__ || defined _M_X64
147  uint64_t rax, rdx;
148  asm volatile ( "rdtsc" : "=a" (rax), "=d" (rdx) );
149  return (int64_t)(( rdx << 32 ) + rax);
150 # else
151 # error "TRACY_HW_TIMER detection logic needs fixing"
152 # endif
153 #else
154 # if defined __linux__ && defined CLOCK_MONOTONIC_RAW
155  struct timespec ts;
156  clock_gettime( CLOCK_MONOTONIC_RAW, &ts );
157  return int64_t( ts.tv_sec ) * 1000000000ll + int64_t( ts.tv_nsec );
158 # else
159  return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
160 # endif
161 #endif
162  }
163 
165  {
166  return m_zoneId.fetch_add( 1, std::memory_order_relaxed );
167  }
168 
170  {
171  auto& p = GetProfiler();
172  p.m_serialLock.lock();
173  return p.m_serialQueue.prepare_next();
174  }
175 
177  {
178  auto& p = GetProfiler();
179  p.m_serialLock.lock();
180  p.SendCallstackSerial( ptr );
181  return p.m_serialQueue.prepare_next();
182  }
183 
185  {
186  auto& p = GetProfiler();
187  p.m_serialQueue.commit_next();
188  p.m_serialLock.unlock();
189  }
190 
191  static tracy_force_inline void SendFrameMark( const char* name )
192  {
193  if( !name ) GetProfiler().m_frameCount.fetch_add( 1, std::memory_order_relaxed );
194 #ifdef TRACY_ON_DEMAND
195  if( !GetProfiler().IsConnected() ) return;
196 #endif
197  TracyLfqPrepare( QueueType::FrameMarkMsg );
198  MemWrite( &item->frameMark.time, GetTime() );
199  MemWrite( &item->frameMark.name, uint64_t( name ) );
201  }
202 
203  static tracy_force_inline void SendFrameMark( const char* name, QueueType type )
204  {
205  assert( type == QueueType::FrameMarkMsgStart || type == QueueType::FrameMarkMsgEnd );
206 #ifdef TRACY_ON_DEMAND
207  if( !GetProfiler().IsConnected() ) return;
208 #endif
209  auto item = QueueSerial();
210  MemWrite( &item->hdr.type, type );
211  MemWrite( &item->frameMark.time, GetTime() );
212  MemWrite( &item->frameMark.name, uint64_t( name ) );
214  }
215 
216  static tracy_force_inline void SendFrameImage( const void* image, uint16_t w, uint16_t h, uint8_t offset, bool flip )
217  {
218  auto& profiler = GetProfiler();
219  assert( profiler.m_frameCount.load( std::memory_order_relaxed ) < std::numeric_limits<uint32_t>::max() );
220 #ifdef TRACY_ON_DEMAND
221  if( !profiler.IsConnected() ) return;
222 #endif
223  const auto sz = size_t( w ) * size_t( h ) * 4;
224  auto ptr = (char*)tracy_malloc( sz );
225  memcpy( ptr, image, sz );
226 
227  profiler.m_fiLock.lock();
228  auto fi = profiler.m_fiQueue.prepare_next();
229  fi->image = ptr;
230  fi->frame = uint32_t( profiler.m_frameCount.load( std::memory_order_relaxed ) - offset );
231  fi->w = w;
232  fi->h = h;
233  fi->flip = flip;
234  profiler.m_fiQueue.commit_next();
235  profiler.m_fiLock.unlock();
236  }
237 
238  static tracy_force_inline void PlotData( const char* name, int64_t val )
239  {
240 #ifdef TRACY_ON_DEMAND
241  if( !GetProfiler().IsConnected() ) return;
242 #endif
243  TracyLfqPrepare( QueueType::PlotData );
244  MemWrite( &item->plotData.name, (uint64_t)name );
245  MemWrite( &item->plotData.time, GetTime() );
246  MemWrite( &item->plotData.type, PlotDataType::Int );
247  MemWrite( &item->plotData.data.i, val );
249  }
250 
251  static tracy_force_inline void PlotData( const char* name, float val )
252  {
253 #ifdef TRACY_ON_DEMAND
254  if( !GetProfiler().IsConnected() ) return;
255 #endif
256  TracyLfqPrepare( QueueType::PlotData );
257  MemWrite( &item->plotData.name, (uint64_t)name );
258  MemWrite( &item->plotData.time, GetTime() );
259  MemWrite( &item->plotData.type, PlotDataType::Float );
260  MemWrite( &item->plotData.data.f, val );
262  }
263 
264  static tracy_force_inline void PlotData( const char* name, double val )
265  {
266 #ifdef TRACY_ON_DEMAND
267  if( !GetProfiler().IsConnected() ) return;
268 #endif
269  TracyLfqPrepare( QueueType::PlotData );
270  MemWrite( &item->plotData.name, (uint64_t)name );
271  MemWrite( &item->plotData.time, GetTime() );
272  MemWrite( &item->plotData.type, PlotDataType::Double );
273  MemWrite( &item->plotData.data.d, val );
275  }
276 
278  {
279  TracyLfqPrepare( QueueType::PlotConfig );
280  MemWrite( &item->plotConfig.name, (uint64_t)name );
281  MemWrite( &item->plotConfig.type, (uint8_t)type );
282 
283 #ifdef TRACY_ON_DEMAND
284  GetProfiler().DeferItem( *item );
285 #endif
286 
288  }
289 
290  static tracy_force_inline void Message( const char* txt, size_t size, int callstack )
291  {
292  assert( size < std::numeric_limits<uint16_t>::max() );
293 #ifdef TRACY_ON_DEMAND
294  if( !GetProfiler().IsConnected() ) return;
295 #endif
296  if( callstack != 0 )
297  {
299  tracy::GetProfiler().SendCallstack( callstack );
300  }
301 
302  TracyLfqPrepare( callstack == 0 ? QueueType::Message : QueueType::MessageCallstack );
303  auto ptr = (char*)tracy_malloc( size );
304  memcpy( ptr, txt, size );
305  MemWrite( &item->messageFat.time, GetTime() );
306  MemWrite( &item->messageFat.text, (uint64_t)ptr );
307  MemWrite( &item->messageFat.size, (uint16_t)size );
309  }
310 
311  static tracy_force_inline void Message( const char* txt, int callstack )
312  {
313 #ifdef TRACY_ON_DEMAND
314  if( !GetProfiler().IsConnected() ) return;
315 #endif
316  if( callstack != 0 )
317  {
319  tracy::GetProfiler().SendCallstack( callstack );
320  }
321 
322  TracyLfqPrepare( callstack == 0 ? QueueType::MessageLiteral : QueueType::MessageLiteralCallstack );
323  MemWrite( &item->messageLiteral.time, GetTime() );
324  MemWrite( &item->messageLiteral.text, (uint64_t)txt );
326  }
327 
328  static tracy_force_inline void MessageColor( const char* txt, size_t size, uint32_t color, int callstack )
329  {
330  assert( size < std::numeric_limits<uint16_t>::max() );
331 #ifdef TRACY_ON_DEMAND
332  if( !GetProfiler().IsConnected() ) return;
333 #endif
334  if( callstack != 0 )
335  {
337  tracy::GetProfiler().SendCallstack( callstack );
338  }
339 
340  TracyLfqPrepare( callstack == 0 ? QueueType::MessageColor : QueueType::MessageColorCallstack );
341  auto ptr = (char*)tracy_malloc( size );
342  memcpy( ptr, txt, size );
343  MemWrite( &item->messageColorFat.time, GetTime() );
344  MemWrite( &item->messageColorFat.text, (uint64_t)ptr );
345  MemWrite( &item->messageColorFat.r, uint8_t( ( color ) & 0xFF ) );
346  MemWrite( &item->messageColorFat.g, uint8_t( ( color >> 8 ) & 0xFF ) );
347  MemWrite( &item->messageColorFat.b, uint8_t( ( color >> 16 ) & 0xFF ) );
348  MemWrite( &item->messageColorFat.size, (uint16_t)size );
350  }
351 
352  static tracy_force_inline void MessageColor( const char* txt, uint32_t color, int callstack )
353  {
354 #ifdef TRACY_ON_DEMAND
355  if( !GetProfiler().IsConnected() ) return;
356 #endif
357  if( callstack != 0 )
358  {
360  tracy::GetProfiler().SendCallstack( callstack );
361  }
362 
363  TracyLfqPrepare( callstack == 0 ? QueueType::MessageLiteralColor : QueueType::MessageLiteralColorCallstack );
364  MemWrite( &item->messageColorLiteral.time, GetTime() );
365  MemWrite( &item->messageColorLiteral.text, (uint64_t)txt );
366  MemWrite( &item->messageColorLiteral.r, uint8_t( ( color ) & 0xFF ) );
367  MemWrite( &item->messageColorLiteral.g, uint8_t( ( color >> 8 ) & 0xFF ) );
368  MemWrite( &item->messageColorLiteral.b, uint8_t( ( color >> 16 ) & 0xFF ) );
370  }
371 
372  static tracy_force_inline void MessageAppInfo( const char* txt, size_t size )
373  {
374  assert( size < std::numeric_limits<uint16_t>::max() );
376  auto ptr = (char*)tracy_malloc( size );
377  memcpy( ptr, txt, size );
378  TracyLfqPrepare( QueueType::MessageAppInfo );
379  MemWrite( &item->messageFat.time, GetTime() );
380  MemWrite( &item->messageFat.text, (uint64_t)ptr );
381  MemWrite( &item->messageFat.size, (uint16_t)size );
382 
383 #ifdef TRACY_ON_DEMAND
384  GetProfiler().DeferItem( *item );
385 #endif
386 
388  }
389 
390  static tracy_force_inline void MemAlloc( const void* ptr, size_t size, bool secure )
391  {
392  if( secure && !ProfilerAvailable() ) return;
393 #ifdef TRACY_ON_DEMAND
394  if( !GetProfiler().IsConnected() ) return;
395 #endif
396  const auto thread = GetThreadHandle();
397 
398  GetProfiler().m_serialLock.lock();
399  SendMemAlloc( QueueType::MemAlloc, thread, ptr, size );
400  GetProfiler().m_serialLock.unlock();
401  }
402 
403  static tracy_force_inline void MemFree( const void* ptr, bool secure )
404  {
405  if( secure && !ProfilerAvailable() ) return;
406 #ifdef TRACY_ON_DEMAND
407  if( !GetProfiler().IsConnected() ) return;
408 #endif
409  const auto thread = GetThreadHandle();
410 
411  GetProfiler().m_serialLock.lock();
412  SendMemFree( QueueType::MemFree, thread, ptr );
413  GetProfiler().m_serialLock.unlock();
414  }
415 
416  static tracy_force_inline void MemAllocCallstack( const void* ptr, size_t size, int depth, bool secure )
417  {
418  if( secure && !ProfilerAvailable() ) return;
419 #ifdef TRACY_HAS_CALLSTACK
420  auto& profiler = GetProfiler();
421 # ifdef TRACY_ON_DEMAND
422  if( !profiler.IsConnected() ) return;
423 # endif
424  const auto thread = GetThreadHandle();
425 
427  auto callstack = Callstack( depth );
428 
429  profiler.m_serialLock.lock();
430  SendCallstackSerial( callstack );
431  SendMemAlloc( QueueType::MemAllocCallstack, thread, ptr, size );
432  profiler.m_serialLock.unlock();
433 #else
434  MemAlloc( ptr, size, secure );
435 #endif
436  }
437 
438  static tracy_force_inline void MemFreeCallstack( const void* ptr, int depth, bool secure )
439  {
440  if( secure && !ProfilerAvailable() ) return;
441 #ifdef TRACY_HAS_CALLSTACK
442  auto& profiler = GetProfiler();
443 # ifdef TRACY_ON_DEMAND
444  if( !profiler.IsConnected() ) return;
445 # endif
446  const auto thread = GetThreadHandle();
447 
449  auto callstack = Callstack( depth );
450 
451  profiler.m_serialLock.lock();
452  SendCallstackSerial( callstack );
453  SendMemFree( QueueType::MemFreeCallstack, thread, ptr );
454  profiler.m_serialLock.unlock();
455 #else
456  MemFree( ptr, secure );
457 #endif
458  }
459 
460  static tracy_force_inline void MemAllocNamed( const void* ptr, size_t size, bool secure, const char* name )
461  {
462  if( secure && !ProfilerAvailable() ) return;
463 #ifdef TRACY_ON_DEMAND
464  if( !GetProfiler().IsConnected() ) return;
465 #endif
466  const auto thread = GetThreadHandle();
467 
468  GetProfiler().m_serialLock.lock();
469  SendMemName( name );
470  SendMemAlloc( QueueType::MemAllocNamed, thread, ptr, size );
471  GetProfiler().m_serialLock.unlock();
472  }
473 
474  static tracy_force_inline void MemFreeNamed( const void* ptr, bool secure, const char* name )
475  {
476  if( secure && !ProfilerAvailable() ) return;
477 #ifdef TRACY_ON_DEMAND
478  if( !GetProfiler().IsConnected() ) return;
479 #endif
480  const auto thread = GetThreadHandle();
481 
482  GetProfiler().m_serialLock.lock();
483  SendMemName( name );
484  SendMemFree( QueueType::MemFreeNamed, thread, ptr );
485  GetProfiler().m_serialLock.unlock();
486  }
487 
488  static tracy_force_inline void MemAllocCallstackNamed( const void* ptr, size_t size, int depth, bool secure, const char* name )
489  {
490  if( secure && !ProfilerAvailable() ) return;
491 #ifdef TRACY_HAS_CALLSTACK
492  auto& profiler = GetProfiler();
493 # ifdef TRACY_ON_DEMAND
494  if( !profiler.IsConnected() ) return;
495 # endif
496  const auto thread = GetThreadHandle();
497 
499  auto callstack = Callstack( depth );
500 
501  profiler.m_serialLock.lock();
502  SendCallstackSerial( callstack );
503  SendMemName( name );
504  SendMemAlloc( QueueType::MemAllocCallstackNamed, thread, ptr, size );
505  profiler.m_serialLock.unlock();
506 #else
507  MemAlloc( ptr, size, secure );
508 #endif
509  }
510 
511  static tracy_force_inline void MemFreeCallstackNamed( const void* ptr, int depth, bool secure, const char* name )
512  {
513  if( secure && !ProfilerAvailable() ) return;
514 #ifdef TRACY_HAS_CALLSTACK
515  auto& profiler = GetProfiler();
516 # ifdef TRACY_ON_DEMAND
517  if( !profiler.IsConnected() ) return;
518 # endif
519  const auto thread = GetThreadHandle();
520 
522  auto callstack = Callstack( depth );
523 
524  profiler.m_serialLock.lock();
525  SendCallstackSerial( callstack );
526  SendMemName( name );
527  SendMemFree( QueueType::MemFreeCallstackNamed, thread, ptr );
528  profiler.m_serialLock.unlock();
529 #else
530  MemFree( ptr, secure );
531 #endif
532  }
533 
535  {
536 #ifdef TRACY_HAS_CALLSTACK
537  auto ptr = Callstack( depth );
538  TracyLfqPrepare( QueueType::Callstack );
539  MemWrite( &item->callstackFat.ptr, (uint64_t)ptr );
541 #endif
542  }
543 
545  static tracy_force_inline void ParameterSetup( uint32_t idx, const char* name, bool isBool, int32_t val )
546  {
547  TracyLfqPrepare( QueueType::ParamSetup );
548  tracy::MemWrite( &item->paramSetup.idx, idx );
549  tracy::MemWrite( &item->paramSetup.name, (uint64_t)name );
550  tracy::MemWrite( &item->paramSetup.isBool, (uint8_t)isBool );
551  tracy::MemWrite( &item->paramSetup.val, val );
552 
553 #ifdef TRACY_ON_DEMAND
554  GetProfiler().DeferItem( *item );
555 #endif
556 
558  }
559 
560  void SendCallstack( int depth, const char* skipBefore );
561  static void CutCallstack( void* callstack, const char* skipBefore );
562 
563  static bool ShouldExit();
564 
566  {
567  return m_isConnected.load( std::memory_order_acquire );
568  }
569 
571  {
572  m_isSystemTracePaused.store(value, std::memory_order_release);
573  }
574 
576  {
577  return m_isSystemTracePaused.load(std::memory_order_acquire);
578  }
579 
580 #ifdef TRACY_ON_DEMAND
581  tracy_force_inline uint64_t ConnectionId() const
582  {
583  return m_connectionId.load( std::memory_order_acquire );
584  }
585 
586  tracy_force_inline void DeferItem( const QueueItem& item )
587  {
588  m_deferredLock.lock();
589  auto dst = m_deferredQueue.push_next();
590  memcpy( dst, &item, sizeof( item ) );
591  m_deferredLock.unlock();
592  }
593 #endif
594 
595  void RequestShutdown() { m_shutdown.store( true, std::memory_order_relaxed ); m_shutdownManual.store( true, std::memory_order_relaxed ); }
596  bool HasShutdownFinished() const { return m_shutdownFinished.load( std::memory_order_relaxed ); }
597 
598  void SendString( uint64_t str, const char* ptr, QueueType type ) { SendString( str, ptr, strlen( ptr ), type ); }
599  void SendString( uint64_t str, const char* ptr, size_t len, QueueType type );
600  void SendSingleString( const char* ptr ) { SendSingleString( ptr, strlen( ptr ) ); }
601  void SendSingleString( const char* ptr, size_t len );
602  void SendSecondString( const char* ptr ) { SendSecondString( ptr, strlen( ptr ) ); }
603  void SendSecondString( const char* ptr, size_t len );
604 
605 
606  // Allocated source location data layout:
607  // 2b payload size
608  // 4b color
609  // 4b source line
610  // fsz function name
611  // 1b null terminator
612  // ssz source file name
613  // 1b null terminator
614  // nsz zone name (optional)
615 
616  static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function )
617  {
618  return AllocSourceLocation( line, source, function, nullptr, 0 );
619  }
620 
621  static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function, const char* name, size_t nameSz )
622  {
623  return AllocSourceLocation( line, source, strlen(source), function, strlen(function), name, nameSz );
624  }
625 
626  static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz )
627  {
628  return AllocSourceLocation( line, source, sourceSz, function, functionSz, nullptr, 0 );
629  }
630 
631  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 )
632  {
633  const auto sz32 = uint32_t( 2 + 4 + 4 + functionSz + 1 + sourceSz + 1 + nameSz );
634  assert( sz32 <= std::numeric_limits<uint16_t>::max() );
635  const auto sz = uint16_t( sz32 );
636  auto ptr = (char*)tracy_malloc( sz );
637  memcpy( ptr, &sz, 2 );
638  memset( ptr + 2, 0, 4 );
639  memcpy( ptr + 6, &line, 4 );
640  memcpy( ptr + 10, function, functionSz );
641  ptr[10 + functionSz] = '\0';
642  memcpy( ptr + 10 + functionSz + 1, source, sourceSz );
643  ptr[10 + functionSz + 1 + sourceSz] = '\0';
644  if( nameSz != 0 )
645  {
646  memcpy( ptr + 10 + functionSz + 1 + sourceSz + 1, name, nameSz );
647  }
648  return uint64_t( ptr );
649  }
650 
651 private:
652  enum class DequeueStatus { DataDequeued, ConnectionLost, QueueEmpty };
653 
654  static void LaunchWorker( void* ptr ) { ((Profiler*)ptr)->Worker(); }
655  void Worker();
656 
657  static void LaunchCompressWorker( void* ptr ) { ((Profiler*)ptr)->CompressWorker(); }
658  void CompressWorker();
659 
661  void ClearSerial();
665  bool CommitData();
666 
667  tracy_force_inline bool AppendData( const void* data, size_t len )
668  {
669  const auto ret = NeedDataSize( len );
670  AppendDataUnsafe( data, len );
671  return ret;
672  }
673 
675  {
676  assert( len <= TargetFrameSize );
677  bool ret = true;
678  if( m_bufferOffset - m_bufferStart + (int)len > TargetFrameSize )
679  {
680  ret = CommitData();
681  }
682  return ret;
683  }
684 
685  tracy_force_inline void AppendDataUnsafe( const void* data, size_t len )
686  {
687  memcpy( m_buffer + m_bufferOffset, data, len );
688  m_bufferOffset += int( len );
689  }
690 
691  bool SendData( const char* data, size_t len );
692  void SendLongString( uint64_t ptr, const char* str, size_t len, QueueType type );
693  void SendSourceLocation( uint64_t ptr );
695  void SendCallstackPayload( uint64_t ptr );
696  void SendCallstackPayload64( uint64_t ptr );
697  void SendCallstackAlloc( uint64_t ptr );
698  void SendCallstackFrame( uint64_t ptr );
699  void SendCodeLocation( uint64_t ptr );
700 
701  bool HandleServerQuery();
702  void HandleDisconnect();
703  void HandleParameter( uint64_t payload );
704  void HandleSymbolQuery( uint64_t symbol );
706  void HandleSourceCodeQuery();
707 
708  void AckServerQuery();
710 
711  void CalibrateTimer();
712  void CalibrateDelay();
713  void ReportTopology();
714 
715  static tracy_force_inline void SendCallstackSerial( void* ptr )
716  {
717 #ifdef TRACY_HAS_CALLSTACK
718  auto item = GetProfiler().m_serialQueue.prepare_next();
719  MemWrite( &item->hdr.type, QueueType::CallstackSerial );
720  MemWrite( &item->callstackFat.ptr, (uint64_t)ptr );
722 #endif
723  }
724 
725  static tracy_force_inline void SendMemAlloc( QueueType type, const uint64_t thread, const void* ptr, size_t size )
726  {
727  assert( type == QueueType::MemAlloc || type == QueueType::MemAllocCallstack || type == QueueType::MemAllocNamed || type == QueueType::MemAllocCallstackNamed );
728 
729  auto item = GetProfiler().m_serialQueue.prepare_next();
730  MemWrite( &item->hdr.type, type );
731  MemWrite( &item->memAlloc.time, GetTime() );
732  MemWrite( &item->memAlloc.thread, thread );
733  MemWrite( &item->memAlloc.ptr, (uint64_t)ptr );
734  if( compile_time_condition<sizeof( size ) == 4>::value )
735  {
736  memcpy( &item->memAlloc.size, &size, 4 );
737  memset( &item->memAlloc.size + 4, 0, 2 );
738  }
739  else
740  {
741  assert( sizeof( size ) == 8 );
742  memcpy( &item->memAlloc.size, &size, 4 );
743  memcpy( ((char*)&item->memAlloc.size)+4, ((char*)&size)+4, 2 );
744  }
746  }
747 
748  static tracy_force_inline void SendMemFree( QueueType type, const uint64_t thread, const void* ptr )
749  {
750  assert( type == QueueType::MemFree || type == QueueType::MemFreeCallstack || type == QueueType::MemFreeNamed || type == QueueType::MemFreeCallstackNamed );
751 
752  auto item = GetProfiler().m_serialQueue.prepare_next();
753  MemWrite( &item->hdr.type, type );
754  MemWrite( &item->memFree.time, GetTime() );
755  MemWrite( &item->memFree.thread, thread );
756  MemWrite( &item->memFree.ptr, (uint64_t)ptr );
758  }
759 
760  static tracy_force_inline void SendMemName( const char* name )
761  {
762  assert( name );
763  auto item = GetProfiler().m_serialQueue.prepare_next();
764  MemWrite( &item->hdr.type, QueueType::MemNamePayload );
765  MemWrite( &item->memName.name, (uint64_t)name );
767  }
768 
769 #if ( defined _WIN32 || defined __CYGWIN__ ) && defined TRACY_TIMER_QPC
770  static int64_t GetTimeQpc();
771 #endif
772 
773  double m_timerMul;
776  std::atomic<int64_t> m_timeBegin;
779  std::atomic<bool> m_shutdown;
780  std::atomic<bool> m_shutdownManual;
781  std::atomic<bool> m_shutdownFinished;
784  bool m_noExit;
786  std::atomic<uint32_t> m_zoneId;
788 
794 
795  void* m_stream; // LZ4_stream_t*
796  char* m_buffer;
799 
800  char* m_lz4Buf;
801 
803  TracyMutex m_serialLock;
804 
806  TracyMutex m_fiLock;
807 
808  std::atomic<uint64_t> m_frameCount;
809  std::atomic<bool> m_isConnected;
810 #ifdef TRACY_ON_DEMAND
811  std::atomic<uint64_t> m_connectionId;
812 
813  TracyMutex m_deferredLock;
814  FastVector<QueueItem> m_deferredQueue;
815 #endif
816 
817 #ifdef TRACY_HAS_SYSTIME
818  void ProcessSysTime();
819 
820  SysTime m_sysTime;
821  uint64_t m_sysTimeLast = 0;
822 #else
823  void ProcessSysTime() {}
824 #endif
825  std::atomic<bool> m_isSystemTracePaused;
826 
827 
829 
830  char* m_queryData;
832 };
833 
834 }
835 
836 #endif


Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)