Merge branch 'GoaLitiuM-tracy_v09'

This commit is contained in:
Wojtek Figat
2023-05-08 11:56:31 +02:00
47 changed files with 7540 additions and 3598 deletions

View File

@@ -4,7 +4,7 @@
#include "Engine/Core/Log.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Collections/Sorting.h"
#include <ThirdParty/tracy/Tracy.h>
#include <ThirdParty/tracy/tracy/Tracy.hpp>
static bool CompareEngineServices(EngineService* const& a, EngineService* const& b)
{

View File

@@ -7,7 +7,7 @@
#include "Engine/Scripting/ManagedCLR/MCore.h"
#if TRACY_ENABLE
#include "Engine/Core/Math/Math.h"
#include <ThirdParty/tracy/Tracy.h>
#include <ThirdParty/tracy/tracy/Tracy.hpp>
#endif
Delegate<Thread*> ThreadBase::ThreadStarting;

View File

@@ -8,7 +8,7 @@
#include "Engine/Core/Math/Math.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Scripting/ScriptingType.h"
#include <ThirdParty/tracy/Tracy.h>
#include <ThirdParty/tracy/tracy/Tracy.hpp>
#if COMPILE_WITH_PROFILER

View File

@@ -127,7 +127,7 @@ void PluginManagerService::InvokeDeinitialize(Plugin* plugin)
return;
StringAnsiView typeName = plugin->GetType().GetName();
PROFILE_CPU();
ZoneName(typeName.Get(), typeName.Length())
ZoneName(typeName.Get(), typeName.Length());
LOG(Info, "Unloading plugin {}", plugin->ToString());

View File

@@ -26,6 +26,8 @@
#include "client/TracySysTrace.cpp"
#include "common/TracySocket.cpp"
#include "client/tracy_rpmalloc.cpp"
#include "client/TracyAlloc.cpp"
#if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6
# include "libbacktrace/alloc.cpp"
@@ -40,6 +42,7 @@
# else
# include "libbacktrace/elf.cpp"
# endif
# include "common/TracyStackFrames.cpp"
#endif
#ifdef _MSC_VER

View File

@@ -0,0 +1,42 @@
#include "../common/TracyAlloc.hpp"
#ifdef TRACY_USE_RPMALLOC
#include <atomic>
#include "../common/TracyYield.hpp"
namespace tracy
{
extern thread_local bool RpThreadInitDone;
extern std::atomic<int> RpInitDone;
extern std::atomic<int> RpInitLock;
tracy_no_inline static void InitRpmallocPlumbing()
{
const auto done = RpInitDone.load( std::memory_order_acquire );
if( !done )
{
int expected = 0;
while( !RpInitLock.compare_exchange_weak( expected, 1, std::memory_order_release, std::memory_order_relaxed ) ) { expected = 0; YieldThread(); }
const auto done = RpInitDone.load( std::memory_order_acquire );
if( !done )
{
rpmalloc_initialize();
RpInitDone.store( 1, std::memory_order_release );
}
RpInitLock.store( 0, std::memory_order_release );
}
rpmalloc_thread_initialize();
RpThreadInitDone = true;
}
TRACY_API void InitRpmalloc()
{
if( !RpThreadInitDone ) InitRpmallocPlumbing();
}
}
#endif

View File

@@ -38,7 +38,7 @@ static const char* DecodeArmPart( uint32_t impl, uint32_t part )
static char buf[16];
switch( impl )
{
case 0x41:
case 0x41: // ARM
switch( part )
{
case 0x810: return "810";
@@ -61,8 +61,8 @@ static const char* DecodeArmPart( uint32_t impl, uint32_t part )
case 0xc09: return " Cortex-A9";
case 0xc0c: return " Cortex-A12";
case 0xc0d: return " Rockchip RK3288";
case 0xc0f: return " Cortex-A15";
case 0xc0e: return " Cortex-A17";
case 0xc0f: return " Cortex-A15";
case 0xc14: return " Cortex-R4";
case 0xc15: return " Cortex-R5";
case 0xc17: return " Cortex-R7";
@@ -92,14 +92,21 @@ static const char* DecodeArmPart( uint32_t impl, uint32_t part )
case 0xd13: return " Cortex-R52";
case 0xd20: return " Cortex-M23";
case 0xd21: return " Cortex-M33";
case 0xd40: return " Zeus";
case 0xd22: return " Cortex-M55";
case 0xd40: return " Neoverse V1";
case 0xd41: return " Cortex-A78";
case 0xd42: return " Cortex-A78AE";
case 0xd43: return " Cortex-A65AE";
case 0xd44: return " Cortex-X1";
case 0xd47: return " Cortex-A710";
case 0xd48: return " Cortex-X2";
case 0xd49: return " Neoverse N2";
case 0xd4a: return " Neoverse E1";
case 0xd4b: return " Cortex-A78C";
case 0xd4c: return " Cortex-X1C";
default: break;
}
case 0x42:
case 0x42: // Broadcom
switch( part )
{
case 0xf: return " Brahma B15";
@@ -107,7 +114,7 @@ static const char* DecodeArmPart( uint32_t impl, uint32_t part )
case 0x516: return " ThunderX2";
default: break;
}
case 0x43:
case 0x43: // Cavium
switch( part )
{
case 0xa0: return " ThunderX";
@@ -121,30 +128,31 @@ static const char* DecodeArmPart( uint32_t impl, uint32_t part )
case 0xb3: return " OcteonTX2 F95";
case 0xb4: return " OcteonTX2 F95N";
case 0xb5: return " OcteonTX2 F95MM";
case 0xb6: return " OcteonTX2 F95O";
case 0xb8: return " ThunderX3 T110";
default: break;
}
case 0x44:
case 0x44: // DEC
switch( part )
{
case 0xa10: return " SA110";
case 0xa11: return " SA1100";
default: break;
}
case 0x46:
case 0x46: // Fujitsu
switch( part )
{
case 0x1: return " A64FX";
default: break;
}
case 0x48:
case 0x48: // HiSilicon
switch( part )
{
case 0xd01: return " TSV100";
case 0xd40: return " Kirin 980";
default: break;
}
case 0x4e:
case 0x4e: // Nvidia
switch( part )
{
case 0x0: return " Denver";
@@ -152,13 +160,13 @@ static const char* DecodeArmPart( uint32_t impl, uint32_t part )
case 0x4: return " Carmel";
default: break;
}
case 0x50:
case 0x50: // Applied Micro
switch( part )
{
case 0x0: return " X-Gene";
default: break;
}
case 0x51:
case 0x51: // Qualcomm
switch( part )
{
case 0xf: return " Scorpion";
@@ -174,18 +182,27 @@ static const char* DecodeArmPart( uint32_t impl, uint32_t part )
case 0x802: return " Kryo 385 Gold";
case 0x803: return " Kryo 385 Silver";
case 0x804: return " Kryo 485 Gold";
case 0x805: return " Kryo 4xx/5xx Silver";
case 0xc00: return " Falkor";
case 0xc01: return " Saphira";
default: break;
}
case 0x53:
case 0x53: // Samsung
switch( part )
{
case 0x1: return " Exynos M1/M2";
case 0x2: return " Exynos M3";
case 0x3: return " Exynos M4";
case 0x4: return " Exynos M5";
default: break;
}
case 0x56:
case 0x54: // Texas Instruments
switch( part )
{
case 0x925: return " TI925";
default: break;
}
case 0x56: // Marvell
switch( part )
{
case 0x131: return " Feroceon 88FR131";
@@ -193,7 +210,7 @@ static const char* DecodeArmPart( uint32_t impl, uint32_t part )
case 0x584: return " PJ4B-MP / PJ4C";
default: break;
}
case 0x61:
case 0x61: // Apple
switch( part )
{
case 0x1: return " Cyclone";
@@ -203,21 +220,33 @@ static const char* DecodeArmPart( uint32_t impl, uint32_t part )
case 0x5: return " Twister/Elba/Malta";
case 0x6: return " Hurricane";
case 0x7: return " Hurricane/Myst";
case 0x22: return " M1 Icestorm";
case 0x23: return " M1 Firestorm";
case 0x24: return " M1 Icestorm Pro";
case 0x25: return " M1 Firestorm Pro";
case 0x28: return " M1 Icestorm Max";
case 0x29: return " M1 Firestorm Max";
default: break;
}
case 0x66:
case 0x66: // Faraday
switch( part )
{
case 0x526: return " FA526";
case 0x626: return " FA626";
default: break;
}
case 0x68:
case 0x68: // HXT
switch( part )
{
case 0x0: return " Phecda";
default: break;
}
case 0xc0: // Ampere Computing
switch( part )
{
case 0xac3: return " Ampere1";
default: break;
}
default: break;
}
sprintf( buf, " 0x%x", part );
@@ -267,6 +296,15 @@ static const char* DecodeIosDevice( const char* id )
"iPhone12,3", "iPhone 11 Pro",
"iPhone12,5", "iPhone 11 Pro Max",
"iPhone12,8", "iPhone SE 2nd Gen",
"iPhone13,1", "iPhone 12 Mini",
"iPhone13,2", "iPhone 12",
"iPhone13,3", "iPhone 12 Pro",
"iPhone13,4", "iPhone 12 Pro Max",
"iPhone14,2", "iPhone 13 Pro",
"iPhone14,3", "iPhone 13 Pro Max",
"iPhone14,4", "iPhone 13 Mini",
"iPhone14,5", "iPhone 13",
"iPhone14,6", "iPhone SE 3rd Gen",
"iPad1,1", "iPad (A1219/A1337)",
"iPad2,1", "iPad 2 (A1395)",
"iPad2,2", "iPad 2 (A1396)",
@@ -325,6 +363,20 @@ static const char* DecodeIosDevice( const char* id )
"iPad11,2", "iPad Mini 5th gen (A2124/A2125/A2126)",
"iPad11,3", "iPad Air 3rd gen (A2152)",
"iPad11,4", "iPad Air 3rd gen (A2123/A2153/A2154)",
"iPad11,6", "iPad 8th gen (WiFi)",
"iPad11,7", "iPad 8th gen (WiFi+Cellular)",
"iPad13,1", "iPad Air 4th gen (WiFi)",
"iPad13,2", "iPad Air 4th gen (WiFi+Cellular)",
"iPad13,4", "iPad Pro 11\" 3rd gen",
"iPad13,5", "iPad Pro 11\" 3rd gen",
"iPad13,6", "iPad Pro 11\" 3rd gen",
"iPad13,7", "iPad Pro 11\" 3rd gen",
"iPad13,8", "iPad Pro 12.9\" 5th gen",
"iPad13,9", "iPad Pro 12.9\" 5th gen",
"iPad13,10", "iPad Pro 12.9\" 5th gen",
"iPad13,11", "iPad Pro 12.9\" 5th gen",
"iPad13,16", "iPad Air 5th Gen (WiFi)",
"iPad13,17", "iPad Air 5th Gen (WiFi+Cellular)",
"iPod1,1", "iPod Touch",
"iPod2,1", "iPod Touch 2nd gen",
"iPod3,1", "iPod Touch 3rd gen",

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +1,35 @@
#ifndef __TRACYCALLSTACK_H__
#define __TRACYCALLSTACK_H__
#if !defined _WIN32 && !defined __CYGWIN__
# include <sys/param.h>
#endif
#ifndef TRACY_NO_CALLSTACK
#if defined _WIN32 || defined __CYGWIN__
# define TRACY_HAS_CALLSTACK 1
#elif defined __ANDROID__
# if !defined __arm__ || __ANDROID_API__ >= 21
# define TRACY_HAS_CALLSTACK 2
# else
# define TRACY_HAS_CALLSTACK 5
# if !defined _WIN32
# include <sys/param.h>
# endif
#elif defined __linux
# if defined _GNU_SOURCE && defined __GLIBC__
# define TRACY_HAS_CALLSTACK 3
# else
# define TRACY_HAS_CALLSTACK 2
# if defined _WIN32
# include "../common/TracyUwp.hpp"
# ifndef TRACY_UWP
# define TRACY_HAS_CALLSTACK 1
# endif
# elif defined __ANDROID__
# if !defined __arm__ || __ANDROID_API__ >= 21
# define TRACY_HAS_CALLSTACK 2
# else
# define TRACY_HAS_CALLSTACK 5
# endif
# elif defined __linux
# if defined _GNU_SOURCE && defined __GLIBC__
# define TRACY_HAS_CALLSTACK 3
# else
# define TRACY_HAS_CALLSTACK 2
# endif
# elif defined __APPLE__
# define TRACY_HAS_CALLSTACK 4
# elif defined BSD
# define TRACY_HAS_CALLSTACK 6
# endif
#elif defined __APPLE__
# define TRACY_HAS_CALLSTACK 4
#elif defined BSD
# define TRACY_HAS_CALLSTACK 6
#endif
#endif

View File

@@ -12,6 +12,10 @@
#ifdef TRACY_HAS_CALLSTACK
#ifdef TRACY_DEBUGINFOD
# include <elfutils/debuginfod.h>
#endif
#include <assert.h>
#include <stdint.h>
@@ -25,6 +29,7 @@ struct CallstackSymbolData
const char* file;
uint32_t line;
bool needFree;
uint64_t symAddr;
};
struct CallstackEntry
@@ -44,19 +49,33 @@ struct CallstackEntryData
};
CallstackSymbolData DecodeSymbolAddress( uint64_t ptr );
CallstackSymbolData DecodeCodeAddress( uint64_t ptr );
const char* DecodeCallstackPtrFast( uint64_t ptr );
CallstackEntryData DecodeCallstackPtr( uint64_t ptr );
void InitCallstack();
void InitCallstackCritical();
void EndCallstack();
const char* GetKernelModulePath( uint64_t addr );
#ifdef TRACY_DEBUGINFOD
const uint8_t* GetBuildIdForImage( const char* image, size_t& size );
debuginfod_client* GetDebuginfodClient();
#endif
#if TRACY_HAS_CALLSTACK == 1
TRACY_API uintptr_t* CallTrace( int depth );
extern "C"
{
typedef unsigned long (__stdcall *___tracy_t_RtlWalkFrameChain)( void**, unsigned long, unsigned long );
TRACY_API extern ___tracy_t_RtlWalkFrameChain ___tracy_RtlWalkFrameChain;
}
static tracy_force_inline void* Callstack( int depth )
{
assert( depth >= 1 && depth < 63 );
return CallTrace( depth );
auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) );
const auto num = ___tracy_RtlWalkFrameChain( (void**)( trace + 1 ), depth, 0 );
*trace = num;
return trace;
}
#elif TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5

View File

@@ -0,0 +1,12 @@
#ifndef __TRACYCPUID_HPP__
#define __TRACYCPUID_HPP__
// Prior to GCC 11 the cpuid.h header did not have any include guards and thus
// including it more than once would cause a compiler error due to symbol
// redefinitions. In order to support older GCC versions, we have to wrap this
// include between custom include guards to prevent this issue.
// See also https://github.com/wolfpld/tracy/issues/452
#include <cpuid.h>
#endif

View File

@@ -0,0 +1,11 @@
#ifndef __TRACYPRINT_HPP__
#define __TRACYPRINT_HPP__
#ifdef TRACY_VERBOSE
# include <stdio.h>
# define TracyDebug(...) fprintf( stderr, __VA_ARGS__ );
#else
# define TracyDebug(...)
#endif
#endif

View File

@@ -101,7 +101,7 @@ private:
const auto size = size_t( m_write - m_ptr );
T* ptr = (T*)tracy_malloc( sizeof( T ) * cap );
memcpy( ptr, m_ptr, size * sizeof( T ) );
tracy_free( m_ptr );
tracy_free_fast( m_ptr );
m_ptr = ptr;
m_write = m_ptr + size;
m_end = m_ptr + cap;

View File

@@ -98,7 +98,6 @@ public:
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockRelease );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
Profiler::QueueSerialFinish();
@@ -313,7 +312,6 @@ public:
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockRelease );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
Profiler::QueueSerialFinish();
@@ -395,9 +393,9 @@ public:
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockSharedRelease );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
MemWrite( &item->lockReleaseShared.thread, GetThreadHandle() );
MemWrite( &item->lockReleaseShared.id, m_id );
MemWrite( &item->lockReleaseShared.time, Profiler::GetTime() );
Profiler::QueueSerialFinish();
}

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@
#include <time.h>
#include "tracy_concurrentqueue.h"
#include "tracy_SPSCQueue.h"
#include "TracyCallstack.hpp"
#include "TracySysTime.hpp"
#include "TracyFastVector.hpp"
@@ -17,7 +18,7 @@
#include "../common/TracyMutex.hpp"
#include "../common/TracyProtocol.hpp"
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
# include <intrin.h>
#endif
#ifdef __APPLE__
@@ -25,11 +26,15 @@
# include <mach/mach_time.h>
#endif
#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 ) )
#if ( defined _WIN32 || ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) || ( defined TARGET_OS_IOS && TARGET_OS_IOS == 1 ) )
# define TRACY_HW_TIMER
#endif
#if !defined TRACY_HW_TIMER
#ifdef __linux__
# include <signal.h>
#endif
#if defined TRACY_TIMER_FALLBACK || !defined TRACY_HW_TIMER
# include <chrono>
#endif
@@ -55,11 +60,27 @@ TRACY_API Profiler& GetProfiler();
TRACY_API std::atomic<uint32_t>& GetLockCounter();
TRACY_API std::atomic<uint8_t>& GetGpuCtxCounter();
TRACY_API GpuCtxWrapper& GetGpuCtx();
TRACY_API uint64_t GetThreadHandle();
TRACY_API void InitRPMallocThread();
TRACY_API uint32_t GetThreadHandle();
TRACY_API bool ProfilerAvailable();
TRACY_API bool ProfilerAllocatorAvailable();
TRACY_API int64_t GetFrequencyQpc();
#if defined TRACY_TIMER_FALLBACK && defined TRACY_HW_TIMER && ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 )
TRACY_API bool HardwareSupportsInvariantTSC(); // check, if we need fallback scenario
#else
# if defined TRACY_HW_TIMER
tracy_force_inline bool HardwareSupportsInvariantTSC()
{
return true; // this is checked at startup
}
# else
tracy_force_inline bool HardwareSupportsInvariantTSC()
{
return false;
}
# endif
#endif
#ifdef TRACY_ON_DEMAND
struct LuaZoneState
{
@@ -90,6 +111,29 @@ struct LuaZoneState
__tail.store( __magic + 1, std::memory_order_release );
#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();
# 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();
#else
# define TracyQueuePrepare( _type ) TracyLfqPrepare( _type )
# define TracyQueueCommit( _name ) TracyLfqCommit
# define TracyQueuePrepareC( _type ) TracyLfqPrepareC( _type )
# define TracyQueueCommitC( _name ) TracyLfqCommitC
#endif
typedef char*(*SourceContentsCallback)( void* data, const char* filename, size_t& size );
class TRACY_API Profiler
{
struct FrameImageQueueItem
@@ -98,10 +142,26 @@ class TRACY_API Profiler
uint32_t frame;
uint16_t w;
uint16_t h;
uint8_t offset;
bool flip;
};
enum class SymbolQueueItemType
{
CallstackFrame,
SymbolQuery,
ExternalName,
KernelCode,
SourceCode
};
struct SymbolQueueItem
{
SymbolQueueItemType type;
uint64_t ptr;
uint64_t extra;
uint32_t id;
};
public:
Profiler();
~Profiler();
@@ -112,25 +172,33 @@ public:
{
#ifdef TRACY_HW_TIMER
# if defined TARGET_OS_IOS && TARGET_OS_IOS == 1
return mach_absolute_time();
# elif defined _WIN32 || defined __CYGWIN__
if( HardwareSupportsInvariantTSC() ) return mach_absolute_time();
# elif defined _WIN32
# ifdef TRACY_TIMER_QPC
return GetTimeQpc();
# else
return int64_t( __rdtsc() );
if( HardwareSupportsInvariantTSC() ) return int64_t( __rdtsc() );
# endif
# elif defined __i386 || defined _M_IX86
uint32_t eax, edx;
asm volatile ( "rdtsc" : "=a" (eax), "=d" (edx) );
return ( uint64_t( edx ) << 32 ) + uint64_t( eax );
if( HardwareSupportsInvariantTSC() )
{
uint32_t eax, edx;
asm volatile ( "rdtsc" : "=a" (eax), "=d" (edx) );
return ( uint64_t( edx ) << 32 ) + uint64_t( eax );
}
# elif defined __x86_64__ || defined _M_X64
uint64_t rax, rdx;
asm volatile ( "rdtsc" : "=a" (rax), "=d" (rdx) );
return (int64_t)(( rdx << 32 ) + rax);
if( HardwareSupportsInvariantTSC() )
{
uint64_t rax, rdx;
asm volatile ( "rdtsc" : "=a" (rax), "=d" (rdx) );
return (int64_t)(( rdx << 32 ) + rax);
}
# else
# error "TRACY_HW_TIMER detection logic needs fixing"
# endif
#else
#endif
#if !defined TRACY_HW_TIMER || defined TRACY_TIMER_FALLBACK
# if defined __linux__ && defined CLOCK_MONOTONIC_RAW
struct timespec ts;
clock_gettime( CLOCK_MONOTONIC_RAW, &ts );
@@ -138,6 +206,10 @@ public:
# else
return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
# endif
#endif
#if !defined TRACY_TIMER_FALLBACK
return 0; // unreachable branch
#endif
}
@@ -168,12 +240,37 @@ public:
p.m_serialLock.unlock();
}
static tracy_force_inline void SourceCallbackRegister( SourceContentsCallback cb, void* data )
{
auto& profiler = GetProfiler();
profiler.m_sourceCallback = cb;
profiler.m_sourceCallbackData = data;
}
#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
static void SendFrameMark( const char* name );
static void SendFrameMark( const char* name, QueueType type );
static void SendFrameImage( const void* image, uint16_t w, uint16_t h, uint8_t offset, bool flip );
static void PlotData( const char* name, int64_t val );
static void PlotData( const char* name, float val );
static void PlotData( const char* name, double val );
static void ConfigurePlot( const char* name, PlotFormatType type );
static void ConfigurePlot( const char* name, PlotFormatType type, bool step, bool fill, uint32_t color );
static void Message( const char* txt, size_t size, int callstack );
static void Message( const char* txt, int callstack );
static void MessageColor( const char* txt, size_t size, uint32_t color, int callstack );
@@ -189,6 +286,7 @@ public:
static void MemFreeCallstackNamed( const void* ptr, int depth, bool secure, const char* name );
static void SendCallstack( int depth );
static void ParameterRegister( ParameterCallback cb );
static void ParameterRegister( ParameterCallback cb, void* data );
static void ParameterSetup( uint32_t idx, const char* name, bool isBool, int32_t val );
void SendCallstack( int depth, const char* skipBefore );
@@ -296,15 +394,28 @@ public:
private:
enum class DequeueStatus { DataDequeued, ConnectionLost, QueueEmpty };
enum class ThreadCtxStatus { Same, Changed, ConnectionLost };
static void LaunchWorker( void* ptr ) { ((Profiler*)ptr)->Worker(); }
void Worker();
#ifndef TRACY_NO_FRAME_IMAGE
static void LaunchCompressWorker( void* ptr ) { ((Profiler*)ptr)->CompressWorker(); }
void CompressWorker();
#endif
#ifdef TRACY_HAS_CALLSTACK
static void LaunchSymbolWorker( void* ptr ) { ((Profiler*)ptr)->SymbolWorker(); }
void SymbolWorker();
void HandleSymbolQueueItem( const SymbolQueueItem& si );
#endif
void ClearQueues( tracy::moodycamel::ConsumerToken& token );
void ClearSerial();
DequeueStatus Dequeue( tracy::moodycamel::ConsumerToken& token );
DequeueStatus DequeueContextSwitches( tracy::moodycamel::ConsumerToken& token, int64_t& timeStop );
DequeueStatus DequeueSerial();
ThreadCtxStatus ThreadCtxCheck( uint32_t threadId );
bool CommitData();
tracy_force_inline bool AppendData( const void* data, size_t len )
@@ -338,18 +449,21 @@ private:
void SendCallstackPayload( uint64_t ptr );
void SendCallstackPayload64( uint64_t ptr );
void SendCallstackAlloc( uint64_t ptr );
void SendCallstackFrame( uint64_t ptr );
void SendCodeLocation( uint64_t ptr );
void QueueCallstackFrame( uint64_t ptr );
void QueueSymbolQuery( uint64_t symbol );
void QueueExternalName( uint64_t ptr );
void QueueKernelCode( uint64_t symbol, uint32_t size );
void QueueSourceCodeQuery( uint32_t id );
bool HandleServerQuery();
void HandleDisconnect();
void HandleParameter( uint64_t payload );
void HandleSymbolQuery( uint64_t symbol );
void HandleSymbolCodeQuery( uint64_t symbol, uint32_t size );
void HandleSourceCodeQuery();
void HandleSourceCodeQuery( char* data, char* image, uint32_t id );
void AckServerQuery();
void AckSourceCodeNotAvailable();
void AckSymbolCodeNotAvailable();
void CalibrateTimer();
void CalibrateDelay();
@@ -362,10 +476,12 @@ private:
MemWrite( &item->hdr.type, QueueType::CallstackSerial );
MemWrite( &item->callstackFat.ptr, (uint64_t)ptr );
GetProfiler().m_serialQueue.commit_next();
#else
static_cast<void>(ptr); // unused
#endif
}
static tracy_force_inline void SendMemAlloc( QueueType type, const uint64_t thread, const void* ptr, size_t size )
static tracy_force_inline void SendMemAlloc( QueueType type, const uint32_t thread, const void* ptr, size_t size )
{
assert( type == QueueType::MemAlloc || type == QueueType::MemAllocCallstack || type == QueueType::MemAllocNamed || type == QueueType::MemAllocCallstackNamed );
@@ -388,7 +504,7 @@ private:
GetProfiler().m_serialQueue.commit_next();
}
static tracy_force_inline void SendMemFree( QueueType type, const uint64_t thread, const void* ptr )
static tracy_force_inline void SendMemFree( QueueType type, const uint32_t thread, const void* ptr )
{
assert( type == QueueType::MemFree || type == QueueType::MemFreeCallstack || type == QueueType::MemFreeNamed || type == QueueType::MemFreeCallstackNamed );
@@ -409,7 +525,7 @@ private:
GetProfiler().m_serialQueue.commit_next();
}
#if ( defined _WIN32 || defined __CYGWIN__ ) && defined TRACY_TIMER_QPC
#if defined _WIN32 && defined TRACY_TIMER_QPC
static int64_t GetTimeQpc();
#endif
@@ -417,7 +533,7 @@ private:
uint64_t m_resolution;
uint64_t m_delay;
std::atomic<int64_t> m_timeBegin;
uint64_t m_mainThread;
uint32_t m_mainThread;
uint64_t m_epoch, m_exectime;
std::atomic<bool> m_shutdown;
std::atomic<bool> m_shutdownManual;
@@ -429,7 +545,7 @@ private:
std::atomic<uint32_t> m_zoneId;
int64_t m_samplingPeriod;
uint64_t m_threadCtx;
uint32_t m_threadCtx;
int64_t m_refTimeThread;
int64_t m_refTimeSerial;
int64_t m_refTimeCtx;
@@ -445,6 +561,13 @@ private:
FastVector<QueueItem> m_serialQueue, m_serialDequeue;
TracyMutex m_serialLock;
#ifndef TRACY_NO_FRAME_IMAGE
FastVector<FrameImageQueueItem> m_fiQueue, m_fiDequeue;
TracyMutex m_fiLock;
#endif
SPSCQueue<SymbolQueueItem> m_symbolQueue;
std::atomic<uint64_t> m_frameCount;
std::atomic<bool> m_isConnected;
#ifdef TRACY_ON_DEMAND
@@ -464,9 +587,23 @@ private:
#endif
ParameterCallback m_paramCallback;
void* m_paramCallbackData;
SourceContentsCallback m_sourceCallback;
void* m_sourceCallbackData;
char* m_queryImage;
char* m_queryData;
char* m_queryDataPtr;
#if defined _WIN32
void* m_exceptionHandler;
#endif
#ifdef __linux__
struct {
struct sigaction pwr, ill, fpe, segv, pipe, bus, abrt;
} m_prevSignal;
#endif
bool m_crashHandlerInstalled;
};
}

View File

@@ -1,27 +1,44 @@
#include <atomic>
#include <assert.h>
#include <errno.h>
#include <linux/perf_event.h>
#include <stdint.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include "TracyDebug.hpp"
namespace tracy
{
template<size_t Size>
class RingBuffer
{
public:
RingBuffer( int fd )
: m_fd( fd )
RingBuffer( unsigned int size, int fd, int id, int cpu = -1 )
: m_size( size )
, m_id( id )
, m_cpu( cpu )
, m_fd( fd )
{
const auto pageSize = uint32_t( getpagesize() );
assert( Size >= pageSize );
assert( __builtin_popcount( Size ) == 1 );
m_mapSize = Size + pageSize;
assert( size >= pageSize );
assert( __builtin_popcount( size ) == 1 );
m_mapSize = size + pageSize;
auto mapAddr = mmap( nullptr, m_mapSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
if( !mapAddr )
if( mapAddr == MAP_FAILED )
{
TracyDebug( "mmap failed: errno %i (%s)\n", errno, strerror( errno ) );
m_fd = 0;
m_metadata = nullptr;
close( fd );
return;
}
m_metadata = (perf_event_mmap_page*)mapAddr;
assert( m_metadata->data_offset == pageSize );
m_buffer = ((char*)mapAddr) + pageSize;
m_tail = m_metadata->data_tail;
}
~RingBuffer()
@@ -49,36 +66,35 @@ public:
}
bool IsValid() const { return m_metadata != nullptr; }
int GetId() const { return m_id; }
int GetCpu() const { return m_cpu; }
void Enable()
{
ioctl( m_fd, PERF_EVENT_IOC_ENABLE, 0 );
}
bool HasData() const
{
const auto head = LoadHead();
return head > m_metadata->data_tail;
}
void Read( void* dst, uint64_t offset, uint64_t cnt )
{
auto src = ( m_metadata->data_tail + offset ) % Size;
if( src + cnt <= Size )
const auto size = m_size;
auto src = ( m_tail + offset ) % size;
if( src + cnt <= size )
{
memcpy( dst, m_buffer + src, cnt );
}
else
{
const auto s0 = Size - src;
memcpy( dst, m_buffer + src, s0 );
memcpy( (char*)dst + s0, m_buffer, cnt - s0 );
const auto s0 = size - src;
const auto buf = m_buffer;
memcpy( dst, buf + src, s0 );
memcpy( (char*)dst + s0, buf, cnt - s0 );
}
}
void Advance( uint64_t cnt )
{
StoreTail( m_metadata->data_tail + cnt );
m_tail += cnt;
StoreTail();
}
bool CheckTscCaps() const
@@ -88,26 +104,35 @@ public:
int64_t ConvertTimeToTsc( int64_t timestamp ) const
{
assert( m_metadata->cap_user_time_zero );
if( !m_metadata->cap_user_time_zero ) return 0;
const auto time = timestamp - m_metadata->time_zero;
const auto quot = time / m_metadata->time_mult;
const auto rem = time % m_metadata->time_mult;
return ( quot << m_metadata->time_shift ) + ( rem << m_metadata->time_shift ) / m_metadata->time_mult;
}
private:
uint64_t LoadHead() const
{
return std::atomic_load_explicit( (const volatile std::atomic<uint64_t>*)&m_metadata->data_head, std::memory_order_acquire );
}
void StoreTail( uint64_t tail )
uint64_t GetTail() const
{
std::atomic_store_explicit( (volatile std::atomic<uint64_t>*)&m_metadata->data_tail, tail, std::memory_order_release );
return m_tail;
}
perf_event_mmap_page* m_metadata;
private:
void StoreTail()
{
std::atomic_store_explicit( (volatile std::atomic<uint64_t>*)&m_metadata->data_tail, m_tail, std::memory_order_release );
}
unsigned int m_size;
uint64_t m_tail;
char* m_buffer;
int m_id;
int m_cpu;
perf_event_mmap_page* m_metadata;
size_t m_mapSize;
int m_fd;

View File

@@ -8,7 +8,7 @@
#include "../common/TracySystem.hpp"
#include "../common/TracyAlign.hpp"
#include "../common/TracyAlloc.hpp"
#include "TracyProfiler.hpp"
#include "../client/TracyLock.hpp"
namespace tracy
{
@@ -56,10 +56,10 @@ ScopedZone::ScopedZone( const SourceLocationData* srcloc, bool is_active )
#ifdef TRACY_ON_DEMAND
m_connectionId = GetProfiler().ConnectionId();
#endif
TracyLfqPrepare( QueueType::ZoneBegin );
TracyQueuePrepare( QueueType::ZoneBegin );
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc );
TracyLfqCommit;
TracyQueueCommit( zoneBeginThread );
}
ScopedZone::ScopedZone( const SourceLocationData* srcloc, int depth, bool is_active )
@@ -75,10 +75,10 @@ ScopedZone::ScopedZone( const SourceLocationData* srcloc, int depth, bool is_act
#endif
GetProfiler().SendCallstack( depth );
TracyLfqPrepare( QueueType::ZoneBeginCallstack );
TracyQueuePrepare( QueueType::ZoneBeginCallstack );
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc );
TracyLfqCommit;
TracyQueueCommit( zoneBeginThread );
}
ScopedZone::ScopedZone( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool is_active )
@@ -92,11 +92,11 @@ ScopedZone::ScopedZone( uint32_t line, const char* source, size_t sourceSz, cons
#ifdef TRACY_ON_DEMAND
m_connectionId = GetProfiler().ConnectionId();
#endif
TracyLfqPrepare( QueueType::ZoneBeginAllocSrcLoc );
TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLoc );
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
MemWrite( &item->zoneBegin.srcloc, srcloc );
TracyLfqCommit;
TracyQueueCommit( zoneBeginThread );
}
ScopedZone::ScopedZone( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool is_active )
@@ -112,11 +112,11 @@ ScopedZone::ScopedZone( uint32_t line, const char* source, size_t sourceSz, cons
#endif
GetProfiler().SendCallstack( depth );
TracyLfqPrepare( QueueType::ZoneBeginAllocSrcLocCallstack );
TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLocCallstack );
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
MemWrite( &item->zoneBegin.srcloc, srcloc );
TracyLfqCommit;
TracyQueueCommit( zoneBeginThread );
}
ScopedZone::~ScopedZone()
@@ -125,9 +125,9 @@ ScopedZone::~ScopedZone()
#ifdef TRACY_ON_DEMAND
if( GetProfiler().ConnectionId() != m_connectionId ) return;
#endif
TracyLfqPrepare( QueueType::ZoneEnd );
TracyQueuePrepare( QueueType::ZoneEnd );
MemWrite( &item->zoneEnd.time, Profiler::GetTime() );
TracyLfqCommit;
TracyQueueCommit( zoneEndThread );
}
void ScopedZone::Text( const char* txt, size_t size )
@@ -139,13 +139,13 @@ void ScopedZone::Text( const char* txt, size_t size )
#endif
auto ptr = (char*)tracy_malloc( size );
memcpy( ptr, txt, size );
TracyLfqPrepare( QueueType::ZoneText );
TracyQueuePrepare( QueueType::ZoneText );
MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
MemWrite( &item->zoneTextFat.size, (uint16_t)size );
TracyLfqCommit;
TracyQueueCommit( zoneTextFatThread );
}
void ScopedZone::Text(const Char* txt, size_t size)
void ScopedZone::Text( const Char* txt, size_t size )
{
assert( size < std::numeric_limits<uint16_t>::max() );
if( !m_active ) return;
@@ -155,10 +155,10 @@ void ScopedZone::Text(const Char* txt, size_t size)
auto ptr = (char*)tracy_malloc( size );
for( int i = 0; i < size; i++)
ptr[i] = (char)txt[i];
TracyLfqPrepare( QueueType::ZoneText );
TracyQueuePrepare( QueueType::ZoneText );
MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
MemWrite( &item->zoneTextFat.size, (uint16_t)size );
TracyLfqCommit;
TracyQueueCommit( zoneTextFatThread );
}
void ScopedZone::Name( const char* txt, size_t size )
@@ -170,10 +170,10 @@ void ScopedZone::Name( const char* txt, size_t size )
#endif
auto ptr = (char*)tracy_malloc( size );
memcpy( ptr, txt, size );
TracyLfqPrepare( QueueType::ZoneName );
TracyQueuePrepare( QueueType::ZoneName );
MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
MemWrite( &item->zoneTextFat.size, (uint16_t)size );
TracyLfqCommit;
TracyQueueCommit( zoneTextFatThread );
}
void ScopedZone::Name( const Char* txt, size_t size )
@@ -186,10 +186,10 @@ void ScopedZone::Name( const Char* txt, size_t size )
auto ptr = (char*)tracy_malloc( size );
for( int i = 0; i < size; i++)
ptr[i] = (char)txt[i];
TracyLfqPrepare( QueueType::ZoneName );
TracyQueuePrepare( QueueType::ZoneName );
MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
MemWrite( &item->zoneTextFat.size, (uint16_t)size );
TracyLfqCommit;
TracyQueueCommit( zoneTextFatThread );
}
void ScopedZone::Color( uint32_t color )
@@ -198,11 +198,11 @@ void ScopedZone::Color( uint32_t color )
#ifdef TRACY_ON_DEMAND
if( GetProfiler().ConnectionId() != m_connectionId ) return;
#endif
TracyLfqPrepare( QueueType::ZoneColor );
TracyQueuePrepare( QueueType::ZoneColor );
MemWrite( &item->zoneColor.r, uint8_t( ( color ) & 0xFF ) );
MemWrite( &item->zoneColor.g, uint8_t( ( color >> 8 ) & 0xFF ) );
MemWrite( &item->zoneColor.b, uint8_t( ( color >> 16 ) & 0xFF ) );
TracyLfqCommit;
TracyQueueCommit( zoneColorThread );
}
void ScopedZone::Value( uint64_t value )
@@ -211,13 +211,10 @@ void ScopedZone::Value( uint64_t value )
#ifdef TRACY_ON_DEMAND
if( GetProfiler().ConnectionId() != m_connectionId ) return;
#endif
TracyLfqPrepare( QueueType::ZoneValue );
TracyQueuePrepare( QueueType::ZoneValue );
MemWrite( &item->zoneValue.value, value );
TracyLfqCommit;
TracyQueueCommit( zoneValueThread );
}
bool ScopedZone::IsActive() const { return m_active; }
}
#endif

View File

@@ -0,0 +1,40 @@
#ifndef __TRACYSTRINGHELPERS_HPP__
#define __TRACYSTRINGHELPERS_HPP__
#include <assert.h>
#include <string.h>
#include "../common/TracyAlloc.hpp"
namespace tracy
{
static tracy_force_inline char* CopyString( const char* src, size_t sz )
{
auto dst = (char*)tracy_malloc( sz + 1 );
memcpy( dst, src, sz );
dst[sz] = '\0';
return dst;
}
static tracy_force_inline char* CopyString( const char* src )
{
return CopyString( src, strlen( src ) );
}
static tracy_force_inline char* CopyStringFast( const char* src, size_t sz )
{
auto dst = (char*)tracy_malloc_fast( sz + 1 );
memcpy( dst, src, sz );
dst[sz] = '\0';
return dst;
}
static tracy_force_inline char* CopyStringFast( const char* src )
{
return CopyStringFast( src, strlen( src ) );
}
}
#endif

View File

@@ -2,7 +2,7 @@
#ifdef TRACY_HAS_SYSTIME
# if defined _WIN32 || defined __CYGWIN__
# if defined _WIN32
# include <windows.h>
# elif defined __linux__
# include <stdio.h>
@@ -18,7 +18,7 @@
namespace tracy
{
# if defined _WIN32 || defined __CYGWIN__
# if defined _WIN32
static inline uint64_t ConvertTime( const FILETIME& t )
{
@@ -62,7 +62,7 @@ void SysTime::ReadTimes()
{
host_cpu_load_info_data_t info;
mach_msg_type_number_t cnt = HOST_CPU_LOAD_INFO_COUNT;
host_statistics( mach_host_self(), HOST_CPU_LOAD_INFO, reinterpret_cast<host_info_t>( &info ), &cnt );
host_statistics( mach_host_self(), HOST_CPU_LOAD_INFO, reinterpret_cast<host_info_t>( &info ), &cnt );
used = info.cpu_ticks[CPU_STATE_USER] + info.cpu_ticks[CPU_STATE_NICE] + info.cpu_ticks[CPU_STATE_SYSTEM];
idle = info.cpu_ticks[CPU_STATE_IDLE];
}
@@ -95,7 +95,7 @@ float SysTime::Get()
const auto diffIdle = idle - oldIdle;
const auto diffUsed = used - oldUsed;
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
return diffUsed == 0 ? -1 : ( diffUsed - diffIdle ) * 100.f / diffUsed;
#elif defined __linux__ || defined __APPLE__ || defined BSD
const auto total = diffUsed + diffIdle;

View File

@@ -1,7 +1,7 @@
#ifndef __TRACYSYSTIME_HPP__
#define __TRACYSYSTIME_HPP__
#if defined _WIN32 || defined __CYGWIN__ || defined __linux__ || defined __APPLE__
#if defined _WIN32 || defined __linux__ || defined __APPLE__
# define TRACY_HAS_SYSTIME
#else
# include <sys/param.h>

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,11 @@
#ifndef __TRACYSYSTRACE_HPP__
#define __TRACYSYSTRACE_HPP__
#if !defined TRACY_NO_SYSTEM_TRACING && ( defined _WIN32 || defined __CYGWIN__ || defined __linux__ )
# define TRACY_HAS_SYSTEM_TRACING
#if !defined TRACY_NO_SYSTEM_TRACING && ( defined _WIN32 || defined __linux__ )
# include "../common/TracyUwp.hpp"
# ifndef TRACY_UWP
# define TRACY_HAS_SYSTEM_TRACING
# endif
#endif
#ifdef TRACY_HAS_SYSTEM_TRACING
@@ -16,7 +19,7 @@ bool SysTraceStart( int64_t& samplingPeriod );
void SysTraceStop();
void SysTraceWorker( void* ptr );
void SysTraceSendExternalName( uint64_t thread );
void SysTraceGetExternalName( uint64_t thread, const char*& threadName, const char*& name );
}

View File

@@ -1,78 +0,0 @@
// File: 'extra/systrace/tracy_systrace.armv7' (1149 bytes)
// File: 'extra/systrace/tracy_systrace.aarch64' (1650 bytes)
// Exported using binary_to_compressed_c.cpp
namespace tracy
{
static const unsigned int tracy_systrace_armv7_size = 1149;
static const unsigned int tracy_systrace_armv7_data[1152/4] =
{
0x464c457f, 0x00010101, 0x00000000, 0x00000000, 0x00280003, 0x00000001, 0x000001f0, 0x00000034, 0x00000000, 0x05000200, 0x00200034, 0x00280007,
0x00000000, 0x00000006, 0x00000034, 0x00000034, 0x00000034, 0x000000e0, 0x000000e0, 0x00000004, 0x00000004, 0x00000003, 0x00000114, 0x00000114,
0x00000114, 0x00000013, 0x00000013, 0x00000004, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x000003fd, 0x000003fd, 0x00000005,
0x00001000, 0x00000001, 0x000003fd, 0x000013fd, 0x000013fd, 0x00000080, 0x000000b3, 0x00000006, 0x00001000, 0x00000002, 0x00000400, 0x00001400,
0x00001400, 0x0000007d, 0x000000b0, 0x00000006, 0x00000004, 0x6474e551, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006,
0x00000004, 0x70000001, 0x000003a4, 0x000003a4, 0x000003a4, 0x00000008, 0x00000008, 0x00000004, 0x00000004, 0x7379732f, 0x2f6d6574, 0x2f6e6962,
0x6b6e696c, 0x00007265, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000012, 0x00000016, 0x00000000,
0x00000000, 0x00000012, 0x6f6c6400, 0x006e6570, 0x4342494c, 0x62696c00, 0x732e6c64, 0x6c64006f, 0x006d7973, 0x00000001, 0x00000003, 0x00000001,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010001, 0x0000000d, 0x00000010, 0x00000000, 0x00050d63, 0x00020000, 0x00000008,
0x00000000, 0x000014bc, 0x00000116, 0x000014c0, 0x00000216, 0xe52de004, 0xe59fe004, 0xe08fe00e, 0xe5bef008, 0x000012dc, 0xe28fc600, 0xe28cca01,
0xe5bcf2dc, 0xe28fc600, 0xe28cca01, 0xe5bcf2d4, 0xe92d4ff0, 0xe28db01c, 0xe24dd024, 0xe24dd801, 0xe59f017c, 0xe3a01001, 0xe3a08001, 0xe08f0000,
0xebfffff0, 0xe59f116c, 0xe1a04000, 0xe08f1001, 0xebffffef, 0xe59f1160, 0xe1a06000, 0xe1a00004, 0xe08f1001, 0xebffffea, 0xe59f1150, 0xe1a07000,
0xe1a00004, 0xe08f1001, 0xebffffe5, 0xe59f1140, 0xe1a05000, 0xe1a00004, 0xe08f1001, 0xebffffe0, 0xe58d0004, 0xe1a00004, 0xe59f1128, 0xe08f1001,
0xebffffdb, 0xe59f1120, 0xe1a0a000, 0xe1a00004, 0xe08f1001, 0xebffffd6, 0xe1a04000, 0xe59f010c, 0xe3a01000, 0xe3a09000, 0xe08f0000, 0xe12fff36,
0xe1a06000, 0xe3700001, 0xca000001, 0xe3a00000, 0xe12fff37, 0xe3a00009, 0xe3a01001, 0xe1cd01bc, 0xe3a00008, 0xe1cd01b4, 0xe3090680, 0xe3400098,
0xe3a02000, 0xe58d000c, 0xe28d0010, 0xe58d7000, 0xe58d6018, 0xe58d8010, 0xe58d9008, 0xe12fff35, 0xe3500000, 0xca00001d, 0xe28d7018, 0xe28d8010,
0xe28d9020, 0xe1a00007, 0xe3a01001, 0xe3a02000, 0xe12fff35, 0xe3500000, 0xda00000a, 0xe1a00006, 0xe1a01009, 0xe3a02801, 0xe12fff3a, 0xe3500001,
0xba00000e, 0xe1a02000, 0xe3a00001, 0xe1a01009, 0xe12fff34, 0xea000003, 0xe59d2004, 0xe28d0008, 0xe3a01000, 0xe12fff32, 0xe1a00008, 0xe3a01001,
0xe3a02000, 0xe12fff35, 0xe3500001, 0xbaffffe4, 0xe59d1000, 0xe3a00000, 0xe12fff31, 0xe24bd01c, 0xe8bd8ff0, 0x00000198, 0x00000190, 0x00000181,
0x00000172, 0x00000163, 0x00000159, 0x0000014a, 0x00000138, 0x7ffffe4c, 0x00000001, 0x6362696c, 0x006f732e, 0x6e65706f, 0x69786500, 0x6f700074,
0x6e006c6c, 0x736f6e61, 0x7065656c, 0x61657200, 0x72770064, 0x00657469, 0x7379732f, 0x72656b2f, 0x2f6c656e, 0x75626564, 0x72742f67, 0x6e696361,
0x72742f67, 0x5f656361, 0x65706970, 0x00000000, 0x00000003, 0x000014b0, 0x00000002, 0x00000010, 0x00000017, 0x000001b4, 0x00000014, 0x00000011,
0x00000015, 0x00000000, 0x00000006, 0x00000128, 0x0000000b, 0x00000010, 0x00000005, 0x00000158, 0x0000000a, 0x0000001c, 0x6ffffef5, 0x00000174,
0x00000001, 0x0000000d, 0x0000001e, 0x00000008, 0x6ffffffb, 0x00000001, 0x6ffffff0, 0x0000018c, 0x6ffffffe, 0x00000194, 0x6fffffff, 0x00000001,
};
static const unsigned int tracy_systrace_aarch64_size = 1650;
static const unsigned int tracy_systrace_aarch64_data[1652/4] =
{
0x464c457f, 0x00010102, 0x00000000, 0x00000000, 0x00b70003, 0x00000001, 0x000002e0, 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00380040, 0x00400006, 0x00000000, 0x00000006, 0x00000005, 0x00000040, 0x00000000, 0x00000040, 0x00000000, 0x00000040, 0x00000000,
0x00000150, 0x00000000, 0x00000150, 0x00000000, 0x00000008, 0x00000000, 0x00000003, 0x00000004, 0x00000190, 0x00000000, 0x00000190, 0x00000000,
0x00000190, 0x00000000, 0x00000015, 0x00000000, 0x00000015, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000005, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000004e1, 0x00000000, 0x000004e1, 0x00000000, 0x00001000, 0x00000000, 0x00000001, 0x00000006,
0x000004e8, 0x00000000, 0x000014e8, 0x00000000, 0x000014e8, 0x00000000, 0x0000018a, 0x00000000, 0x00000190, 0x00000000, 0x00001000, 0x00000000,
0x00000002, 0x00000006, 0x000004e8, 0x00000000, 0x000014e8, 0x00000000, 0x000014e8, 0x00000000, 0x00000160, 0x00000000, 0x00000160, 0x00000000,
0x00000008, 0x00000000, 0x6474e551, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000008, 0x00000000, 0x7379732f, 0x2f6d6574, 0x2f6e6962, 0x6b6e696c, 0x34367265, 0x00000000, 0x00000001, 0x00000001,
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00090003, 0x000002e0, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000012, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x0000000a, 0x00000012, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x62696c00, 0x732e6c64, 0x6c64006f, 0x006d7973, 0x706f6c64, 0x4c006e65,
0x00434249, 0x00000000, 0x00000000, 0x00000000, 0x00010001, 0x00000001, 0x00000010, 0x00000000, 0x00050d63, 0x00020000, 0x00000017, 0x00000000,
0x00001668, 0x00000000, 0x00000402, 0x00000002, 0x00000000, 0x00000000, 0x00001670, 0x00000000, 0x00000402, 0x00000003, 0x00000000, 0x00000000,
0xa9bf7bf0, 0xb0000010, 0xf9433211, 0x91198210, 0xd61f0220, 0xd503201f, 0xd503201f, 0xd503201f, 0xb0000010, 0xf9433611, 0x9119a210, 0xd61f0220,
0xb0000010, 0xf9433a11, 0x9119c210, 0xd61f0220, 0xa9bb67fc, 0xa9015ff8, 0xa90257f6, 0xa9034ff4, 0xa9047bfd, 0x910103fd, 0xd14043ff, 0xd10083ff,
0x90000000, 0x91124000, 0x52800021, 0x52800039, 0x97ffffec, 0x90000001, 0x91126021, 0xaa0003f7, 0x97ffffec, 0x90000001, 0xaa0003f8, 0x91127421,
0xaa1703e0, 0x97ffffe7, 0x90000001, 0xaa0003f3, 0x91128821, 0xaa1703e0, 0x97ffffe2, 0x90000001, 0xaa0003f4, 0x91129c21, 0xaa1703e0, 0x97ffffdd,
0x90000001, 0xaa0003f5, 0x9112c421, 0xaa1703e0, 0x97ffffd8, 0x90000001, 0xaa0003f6, 0x9112d821, 0xaa1703e0, 0x97ffffd3, 0xaa0003f7, 0x90000000,
0x9112f000, 0x2a1f03e1, 0xd63f0300, 0x2a0003f8, 0x36f80060, 0x2a1f03e0, 0xd63f0260, 0x90000009, 0x3dc12120, 0x52800128, 0x79003be8, 0x52800108,
0x910043e0, 0x52800021, 0x2a1f03e2, 0xb9001bf8, 0xb90013f9, 0x79002be8, 0x3d8003e0, 0xd63f0280, 0x7100001f, 0x5400036c, 0x910063e0, 0x52800021,
0x2a1f03e2, 0xd63f0280, 0x7100001f, 0x5400018d, 0x910083e1, 0x52a00022, 0x2a1803e0, 0xd63f02c0, 0xf100041f, 0x540001eb, 0xaa0003e2, 0x910083e1,
0x52800020, 0xd63f02e0, 0x14000004, 0x910003e0, 0xaa1f03e1, 0xd63f02a0, 0x910043e0, 0x52800021, 0x2a1f03e2, 0xd63f0280, 0x7100041f, 0x54fffceb,
0x2a1f03e0, 0xd63f0260, 0x914043ff, 0x910083ff, 0xa9447bfd, 0xa9434ff4, 0xa94257f6, 0xa9415ff8, 0xa8c567fc, 0xd65f03c0, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00989680, 0x00000000, 0x6362696c, 0x006f732e, 0x6e65706f, 0x69786500, 0x6f700074, 0x6e006c6c, 0x736f6e61, 0x7065656c,
0x61657200, 0x72770064, 0x00657469, 0x7379732f, 0x72656b2f, 0x2f6c656e, 0x75626564, 0x72742f67, 0x6e696361, 0x72742f67, 0x5f656361, 0x65706970,
0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x6ffffef5, 0x00000000, 0x000001a8, 0x00000000, 0x00000005, 0x00000000,
0x00000228, 0x00000000, 0x00000006, 0x00000000, 0x000001c8, 0x00000000, 0x0000000a, 0x00000000, 0x0000001c, 0x00000000, 0x0000000b, 0x00000000,
0x00000018, 0x00000000, 0x00000015, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00001650, 0x00000000, 0x00000002, 0x00000000,
0x00000030, 0x00000000, 0x00000014, 0x00000000, 0x00000007, 0x00000000, 0x00000017, 0x00000000, 0x00000270, 0x00000000, 0x0000001e, 0x00000000,
0x00000008, 0x00000000, 0x6ffffffb, 0x00000000, 0x00000001, 0x00000000, 0x6ffffffe, 0x00000000, 0x00000250, 0x00000000, 0x6fffffff, 0x00000000,
0x00000001, 0x00000000, 0x6ffffff0, 0x00000000, 0x00000244, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x000002a0, 0x00000000, 0x000002a0,
};
}

View File

@@ -1,7 +1,7 @@
#ifndef __TRACYTHREAD_HPP__
#define __TRACYTHREAD_HPP__
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
# include <windows.h>
#else
# include <pthread.h>
@@ -14,18 +14,23 @@
namespace tracy
{
#ifdef TRACY_MANUAL_LIFETIME
extern thread_local bool RpThreadInitDone;
#endif
class ThreadExitHandler
{
public:
~ThreadExitHandler()
{
#ifdef TRACY_MANUAL_LIFETIME
rpmalloc_thread_finalize();
rpmalloc_thread_finalize( 1 );
RpThreadInitDone = false;
#endif
}
};
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
class Thread
{

View File

@@ -0,0 +1,148 @@
/*
Copyright (c) 2020 Erik Rigtorp <erik@rigtorp.se>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#include <atomic>
#include <cassert>
#include <cstddef>
#include <stdexcept>
#include <type_traits> // std::enable_if, std::is_*_constructible
#include "../common/TracyAlloc.hpp"
#if defined (_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4324)
#endif
namespace tracy {
template <typename T> class SPSCQueue {
public:
explicit SPSCQueue(const size_t capacity)
: capacity_(capacity) {
capacity_++; // Needs one slack element
slots_ = (T*)tracy_malloc(sizeof(T) * (capacity_ + 2 * kPadding));
static_assert(alignof(SPSCQueue<T>) == kCacheLineSize, "");
static_assert(sizeof(SPSCQueue<T>) >= 3 * kCacheLineSize, "");
assert(reinterpret_cast<char *>(&readIdx_) -
reinterpret_cast<char *>(&writeIdx_) >=
static_cast<std::ptrdiff_t>(kCacheLineSize));
}
~SPSCQueue() {
while (front()) {
pop();
}
tracy_free(slots_);
}
// non-copyable and non-movable
SPSCQueue(const SPSCQueue &) = delete;
SPSCQueue &operator=(const SPSCQueue &) = delete;
template <typename... Args>
void emplace(Args &&...args) noexcept(
std::is_nothrow_constructible<T, Args &&...>::value) {
static_assert(std::is_constructible<T, Args &&...>::value,
"T must be constructible with Args&&...");
auto const writeIdx = writeIdx_.load(std::memory_order_relaxed);
auto nextWriteIdx = writeIdx + 1;
if (nextWriteIdx == capacity_) {
nextWriteIdx = 0;
}
while (nextWriteIdx == readIdxCache_) {
readIdxCache_ = readIdx_.load(std::memory_order_acquire);
}
new (&slots_[writeIdx + kPadding]) T(std::forward<Args>(args)...);
writeIdx_.store(nextWriteIdx, std::memory_order_release);
}
T *front() noexcept {
auto const readIdx = readIdx_.load(std::memory_order_relaxed);
if (readIdx == writeIdxCache_) {
writeIdxCache_ = writeIdx_.load(std::memory_order_acquire);
if (writeIdxCache_ == readIdx) {
return nullptr;
}
}
return &slots_[readIdx + kPadding];
}
void pop() noexcept {
static_assert(std::is_nothrow_destructible<T>::value,
"T must be nothrow destructible");
auto const readIdx = readIdx_.load(std::memory_order_relaxed);
assert(writeIdx_.load(std::memory_order_acquire) != readIdx);
slots_[readIdx + kPadding].~T();
auto nextReadIdx = readIdx + 1;
if (nextReadIdx == capacity_) {
nextReadIdx = 0;
}
readIdx_.store(nextReadIdx, std::memory_order_release);
}
size_t size() const noexcept {
std::ptrdiff_t diff = writeIdx_.load(std::memory_order_acquire) -
readIdx_.load(std::memory_order_acquire);
if (diff < 0) {
diff += capacity_;
}
return static_cast<size_t>(diff);
}
bool empty() const noexcept {
return writeIdx_.load(std::memory_order_acquire) ==
readIdx_.load(std::memory_order_acquire);
}
size_t capacity() const noexcept { return capacity_ - 1; }
private:
static constexpr size_t kCacheLineSize = 64;
// Padding to avoid false sharing between slots_ and adjacent allocations
static constexpr size_t kPadding = (kCacheLineSize - 1) / sizeof(T) + 1;
private:
size_t capacity_;
T *slots_;
// Align to cache line size in order to avoid false sharing
// readIdxCache_ and writeIdxCache_ is used to reduce the amount of cache
// coherency traffic
alignas(kCacheLineSize) std::atomic<size_t> writeIdx_ = {0};
alignas(kCacheLineSize) size_t readIdxCache_ = 0;
alignas(kCacheLineSize) std::atomic<size_t> readIdx_ = {0};
alignas(kCacheLineSize) size_t writeIdxCache_ = 0;
// Padding to avoid adjacent allocations to share cache line with
// writeIdxCache_
char padding_[kCacheLineSize - sizeof(SPSCQueue<T>::writeIdxCache_)];
};
} // namespace rigtorp
#if defined (_MSC_VER)
#pragma warning(pop)
#endif

View File

@@ -201,7 +201,7 @@ namespace details
ConcurrentQueueProducerTypelessBase* next;
std::atomic<bool> inactive;
ProducerToken* token;
uint64_t threadId;
uint32_t threadId;
ConcurrentQueueProducerTypelessBase()
: next(nullptr), inactive(false), token(nullptr), threadId(0)
@@ -209,19 +209,19 @@ namespace details
}
};
template<typename T>
static inline bool circular_less_than(T a, T b)
{
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4554)
#endif
template<typename T>
static inline bool circular_less_than(T a, T b)
{
static_assert(std::is_integral<T>::value && !std::numeric_limits<T>::is_signed, "circular_less_than is intended to be used only with unsigned integer types");
return static_cast<T>(a - b) > static_cast<T>(static_cast<T>(1) << static_cast<T>(sizeof(T) * CHAR_BIT - 1));
return static_cast<T>(a - b) > (static_cast<T>(static_cast<T>(1) << static_cast<T>(sizeof(T) * CHAR_BIT - 1)));
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
}
template<typename U>
static inline char* align_for(char* ptr)

File diff suppressed because it is too large Load Diff

View File

@@ -20,11 +20,12 @@ namespace tracy
#if defined(__clang__) || defined(__GNUC__)
# define RPMALLOC_EXPORT __attribute__((visibility("default")))
# define RPMALLOC_ALLOCATOR
# define RPMALLOC_ATTRIB_MALLOC __attribute__((__malloc__))
# if defined(__clang_major__) && (__clang_major__ < 4)
# if (defined(__clang_major__) && (__clang_major__ < 4)) || (defined(__GNUC__) && defined(ENABLE_PRELOAD) && ENABLE_PRELOAD)
# define RPMALLOC_ATTRIB_MALLOC
# define RPMALLOC_ATTRIB_ALLOC_SIZE(size)
# define RPMALLOC_ATTRIB_ALLOC_SIZE2(count, size)
# else
# define RPMALLOC_ATTRIB_MALLOC __attribute__((__malloc__))
# define RPMALLOC_ATTRIB_ALLOC_SIZE(size) __attribute__((alloc_size(size)))
# define RPMALLOC_ATTRIB_ALLOC_SIZE2(count, size) __attribute__((alloc_size(count, size)))
# endif
@@ -45,13 +46,24 @@ namespace tracy
# define RPMALLOC_CDECL
#endif
//! Define RPMALLOC_CONFIGURABLE to enable configuring sizes
//! Define RPMALLOC_CONFIGURABLE to enable configuring sizes. Will introduce
// a very small overhead due to some size calculations not being compile time constants
#ifndef RPMALLOC_CONFIGURABLE
#define RPMALLOC_CONFIGURABLE 0
#endif
//! Define RPMALLOC_FIRST_CLASS_HEAPS to enable heap based API (rpmalloc_heap_* functions).
// Will introduce a very small overhead to track fully allocated spans in heaps
#ifndef RPMALLOC_FIRST_CLASS_HEAPS
#define RPMALLOC_FIRST_CLASS_HEAPS 0
#endif
//! Flag to rpaligned_realloc to not preserve content in reallocation
#define RPMALLOC_NO_PRESERVE 1
//! Flag to rpaligned_realloc to fail and return null pointer if grow cannot be done in-place,
// in which case the original pointer is still valid (just like a call to realloc which failes to allocate
// a new block).
#define RPMALLOC_GROW_OR_FAIL 2
typedef struct rpmalloc_global_statistics_t {
//! Current amount of virtual memory mapped, all of which might not have been committed (only if ENABLE_STATISTICS=1)
@@ -99,7 +111,7 @@ typedef struct rpmalloc_thread_statistics_t {
size_t from_reserved;
//! Number of raw memory map calls (not hitting the reserve spans but resulting in actual OS mmap calls)
size_t map_calls;
} span_use[32];
} span_use[64];
//! Per size class statistics (only if ENABLE_STATISTICS=1)
struct {
//! Current number of allocations
@@ -131,7 +143,8 @@ typedef struct rpmalloc_config_t {
// larger than 65535 (storable in an uint16_t), if it is you must use natural
// alignment to shift it into 16 bits. If you set a memory_map function, you
// must also set a memory_unmap function or else the default implementation will
// be used for both.
// be used for both. This function must be thread safe, it can be called by
// multiple threads simultaneously.
void* (*memory_map)(size_t size, size_t* offset);
//! Unmap the memory pages starting at address and spanning the given number of bytes.
// If release is set to non-zero, the unmap is for an entire span range as returned by
@@ -139,8 +152,18 @@ typedef struct rpmalloc_config_t {
// release argument holds the size of the entire span range. If release is set to 0,
// the unmap is a partial decommit of a subset of the mapped memory range.
// If you set a memory_unmap function, you must also set a memory_map function or
// else the default implementation will be used for both.
// else the default implementation will be used for both. This function must be thread
// safe, it can be called by multiple threads simultaneously.
void (*memory_unmap)(void* address, size_t size, size_t offset, size_t release);
//! Called when an assert fails, if asserts are enabled. Will use the standard assert()
// if this is not set.
void (*error_callback)(const char* message);
//! Called when a call to map memory pages fails (out of memory). If this callback is
// not set or returns zero the library will return a null pointer in the allocation
// call. If this callback returns non-zero the map call will be retried. The argument
// passed is the number of bytes that was requested in the map call. Only used if
// the default system memory map function is used (memory_map callback is not set).
int (*map_fail_callback)(size_t size);
//! Size of memory pages. The page size MUST be a power of two. All memory mapping
// requests to memory_map will be made with size set to a multiple of the page size.
// Used if RPMALLOC_CONFIGURABLE is defined to 1, otherwise system page size is used.
@@ -163,6 +186,10 @@ typedef struct rpmalloc_config_t {
// For Windows, see https://docs.microsoft.com/en-us/windows/desktop/memory/large-page-support
// For Linux, see https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
int enable_huge_pages;
//! Respectively allocated pages and huge allocated pages names for systems
// supporting it to be able to distinguish among anonymous regions.
const char *page_name;
const char *huge_page_name;
} rpmalloc_config_t;
//! Initialize allocator with default configuration
@@ -187,7 +214,7 @@ rpmalloc_thread_initialize(void);
//! Finalize allocator for calling thread
TRACY_API void
rpmalloc_thread_finalize(void);
rpmalloc_thread_finalize(int release_caches);
//! Perform deferred deallocations pending for the calling thread heap
RPMALLOC_EXPORT void
@@ -240,6 +267,13 @@ rpaligned_realloc(void* ptr, size_t alignment, size_t size, size_t oldsize, unsi
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
rpaligned_alloc(size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
//! Allocate a memory block of at least the given size and alignment, and zero initialize it.
// Alignment must be a power of two and a multiple of sizeof(void*),
// and should ideally be less than memory page size. A caveat of rpmalloc
// internals is that this must also be strictly less than the span size (default 64KiB)
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
rpaligned_calloc(size_t alignment, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
//! Allocate a memory block of at least the given size and alignment.
// Alignment must be a power of two and a multiple of sizeof(void*),
// and should ideally be less than memory page size. A caveat of rpmalloc
@@ -252,10 +286,78 @@ rpmemalign(size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB
// and should ideally be less than memory page size. A caveat of rpmalloc
// internals is that this must also be strictly less than the span size (default 64KiB)
RPMALLOC_EXPORT int
rpposix_memalign(void **memptr, size_t alignment, size_t size);
rpposix_memalign(void** memptr, size_t alignment, size_t size);
//! Query the usable size of the given memory block (from given pointer to the end of block)
RPMALLOC_EXPORT size_t
rpmalloc_usable_size(void* ptr);
#if RPMALLOC_FIRST_CLASS_HEAPS
//! Heap type
typedef struct heap_t rpmalloc_heap_t;
//! Acquire a new heap. Will reuse existing released heaps or allocate memory for a new heap
// if none available. Heap API is implemented with the strict assumption that only one single
// thread will call heap functions for a given heap at any given time, no functions are thread safe.
RPMALLOC_EXPORT rpmalloc_heap_t*
rpmalloc_heap_acquire(void);
//! Release a heap (does NOT free the memory allocated by the heap, use rpmalloc_heap_free_all before destroying the heap).
// Releasing a heap will enable it to be reused by other threads. Safe to pass a null pointer.
RPMALLOC_EXPORT void
rpmalloc_heap_release(rpmalloc_heap_t* heap);
//! Allocate a memory block of at least the given size using the given heap.
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
rpmalloc_heap_alloc(rpmalloc_heap_t* heap, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
//! Allocate a memory block of at least the given size using the given heap. The returned
// block will have the requested alignment. Alignment must be a power of two and a multiple of sizeof(void*),
// and should ideally be less than memory page size. A caveat of rpmalloc
// internals is that this must also be strictly less than the span size (default 64KiB).
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
rpmalloc_heap_aligned_alloc(rpmalloc_heap_t* heap, size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3);
//! Allocate a memory block of at least the given size using the given heap and zero initialize it.
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
rpmalloc_heap_calloc(rpmalloc_heap_t* heap, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
//! Allocate a memory block of at least the given size using the given heap and zero initialize it. The returned
// block will have the requested alignment. Alignment must either be zero, or a power of two and a multiple of sizeof(void*),
// and should ideally be less than memory page size. A caveat of rpmalloc
// internals is that this must also be strictly less than the span size (default 64KiB).
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
rpmalloc_heap_aligned_calloc(rpmalloc_heap_t* heap, size_t alignment, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
//! Reallocate the given block to at least the given size. The memory block MUST be allocated
// by the same heap given to this function.
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
rpmalloc_heap_realloc(rpmalloc_heap_t* heap, void* ptr, size_t size, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3);
//! Reallocate the given block to at least the given size. The memory block MUST be allocated
// by the same heap given to this function. The returned block will have the requested alignment.
// Alignment must be either zero, or a power of two and a multiple of sizeof(void*), and should ideally be
// less than memory page size. A caveat of rpmalloc internals is that this must also be strictly less than
// the span size (default 64KiB).
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
rpmalloc_heap_aligned_realloc(rpmalloc_heap_t* heap, void* ptr, size_t alignment, size_t size, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(4);
//! Free the given memory block from the given heap. The memory block MUST be allocated
// by the same heap given to this function.
RPMALLOC_EXPORT void
rpmalloc_heap_free(rpmalloc_heap_t* heap, void* ptr);
//! Free all memory allocated by the heap
RPMALLOC_EXPORT void
rpmalloc_heap_free_all(rpmalloc_heap_t* heap);
//! Set the given heap as the current heap for the calling thread. A heap MUST only be current heap
// for a single thread, a heap can never be shared between multiple threads. The previous
// current heap for the calling thread is released to be reused by other threads.
RPMALLOC_EXPORT void
rpmalloc_heap_thread_set_current(rpmalloc_heap_t* heap);
#endif
}

View File

@@ -3,16 +3,33 @@
#include <stdlib.h>
#ifdef TRACY_ENABLE
#if defined TRACY_ENABLE && !defined __EMSCRIPTEN__
# include "../client/tracy_rpmalloc.hpp"
# define TRACY_USE_RPMALLOC
#endif
namespace tracy
{
#ifdef TRACY_USE_RPMALLOC
TRACY_API void InitRpmalloc();
#else
static inline void InitRpmalloc() {}
#endif
static inline void* tracy_malloc( size_t size )
{
#ifdef TRACY_ENABLE
#ifdef TRACY_USE_RPMALLOC
InitRpmalloc();
return rpmalloc( size );
#else
return malloc( size );
#endif
}
static inline void* tracy_malloc_fast( size_t size )
{
#ifdef TRACY_USE_RPMALLOC
return rpmalloc( size );
#else
return malloc( size );
@@ -21,7 +38,17 @@ static inline void* tracy_malloc( size_t size )
static inline void tracy_free( void* ptr )
{
#ifdef TRACY_ENABLE
#ifdef TRACY_USE_RPMALLOC
InitRpmalloc();
rpfree( ptr );
#else
free( ptr );
#endif
}
static inline void tracy_free_fast( void* ptr )
{
#ifdef TRACY_USE_RPMALLOC
rpfree( ptr );
#else
free( ptr );
@@ -30,7 +57,8 @@ static inline void tracy_free( void* ptr )
static inline void* tracy_realloc( void* ptr, size_t size )
{
#ifdef TRACY_ENABLE
#ifdef TRACY_USE_RPMALLOC
InitRpmalloc();
return rprealloc( ptr, size );
#else
return realloc( ptr, size );

View File

@@ -9,8 +9,8 @@ namespace tracy
constexpr unsigned Lz4CompressBound( unsigned isize ) { return isize + ( isize / 255 ) + 16; }
enum : uint32_t { ProtocolVersion = 46 };
enum : uint16_t { BroadcastVersion = 2 };
enum : uint32_t { ProtocolVersion = 63 };
enum : uint16_t { BroadcastVersion = 3 };
using lz4sz_t = uint32_t;
@@ -34,7 +34,7 @@ enum HandshakeStatus : uint8_t
enum { WelcomeMessageProgramNameSize = 64 };
enum { WelcomeMessageHostInfoSize = 1024 };
#pragma pack( 1 )
#pragma pack( push, 1 )
// Must increase left query space after handling!
enum ServerQuery : uint8_t
@@ -44,14 +44,15 @@ enum ServerQuery : uint8_t
ServerQueryThreadString,
ServerQuerySourceLocation,
ServerQueryPlotName,
ServerQueryCallstackFrame,
ServerQueryFrameName,
ServerQueryDisconnect,
ServerQueryExternalName,
ServerQueryParameter,
ServerQueryFiberName,
// Items above are high priority. Split order must be preserved. See IsQueryPrio().
ServerQueryDisconnect,
ServerQueryCallstackFrame,
ServerQueryExternalName,
ServerQuerySymbol,
ServerQuerySymbolCode,
ServerQueryCodeLocation,
ServerQuerySourceCode,
ServerQueryDataTransfer,
ServerQueryDataTransferPart
@@ -77,6 +78,18 @@ enum CpuArchitecture : uint8_t
};
struct WelcomeFlag
{
enum _t : uint8_t
{
OnDemand = 1 << 0,
IsApple = 1 << 1,
CodeTransfer = 1 << 2,
CombineSamples = 1 << 3,
IdentifySamples = 1 << 4,
};
};
struct WelcomeMessage
{
double timerMul;
@@ -88,10 +101,8 @@ struct WelcomeMessage
uint64_t exectime;
uint64_t pid;
int64_t samplingPeriod;
uint8_t onDemand;
uint8_t isApple;
uint8_t flags;
uint8_t cpuArch;
uint8_t codeTransfer;
char cpuManufacturer[12];
uint32_t cpuId;
char programName[WelcomeMessageProgramNameSize];
@@ -115,13 +126,43 @@ struct BroadcastMessage
uint16_t broadcastVersion;
uint16_t listenPort;
uint32_t protocolVersion;
uint64_t pid;
int32_t activeTime; // in seconds
char programName[WelcomeMessageProgramNameSize];
};
enum { BroadcastMessageSize = sizeof( BroadcastMessage ) };
struct BroadcastMessage_v2
{
uint16_t broadcastVersion;
uint16_t listenPort;
uint32_t protocolVersion;
int32_t activeTime;
char programName[WelcomeMessageProgramNameSize];
};
#pragma pack()
struct BroadcastMessage_v1
{
uint32_t broadcastVersion;
uint32_t protocolVersion;
uint32_t listenPort;
uint32_t activeTime;
char programName[WelcomeMessageProgramNameSize];
};
struct BroadcastMessage_v0
{
uint32_t broadcastVersion;
uint32_t protocolVersion;
uint32_t activeTime;
char programName[WelcomeMessageProgramNameSize];
};
enum { BroadcastMessageSize = sizeof( BroadcastMessage ) };
enum { BroadcastMessageSize_v2 = sizeof( BroadcastMessage_v2 ) };
enum { BroadcastMessageSize_v1 = sizeof( BroadcastMessage_v1 ) };
enum { BroadcastMessageSize_v0 = sizeof( BroadcastMessage_v0 ) };
#pragma pack( pop )
}

View File

@@ -21,6 +21,7 @@ enum class QueueType : uint8_t
Callstack,
CallstackAlloc,
CallstackSample,
CallstackSampleContextSwitch,
FrameImage,
ZoneBegin,
ZoneBeginCallstack,
@@ -50,11 +51,20 @@ enum class QueueType : uint8_t
GpuZoneBeginAllocSrcLocSerial,
GpuZoneBeginAllocSrcLocCallstackSerial,
GpuZoneEndSerial,
PlotData,
PlotDataInt,
PlotDataFloat,
PlotDataDouble,
ContextSwitch,
ThreadWakeup,
GpuTime,
GpuContextName,
CallstackFrameSize,
SymbolInformation,
ExternalNameMetadata,
SymbolCodeMetadata,
SourceCodeMetadata,
FiberEnter,
FiberLeave,
Terminate,
KeepAlive,
ThreadContext,
@@ -67,6 +77,7 @@ enum class QueueType : uint8_t
FrameMarkMsg,
FrameMarkMsgStart,
FrameMarkMsgEnd,
FrameVsync,
SourceLocation,
LockAnnounce,
LockTerminate,
@@ -76,16 +87,20 @@ enum class QueueType : uint8_t
MessageLiteralCallstack,
MessageLiteralColorCallstack,
GpuNewContext,
CallstackFrameSize,
CallstackFrame,
SymbolInformation,
CodeInformation,
SysTimeReport,
TidToPid,
HwSampleCpuCycle,
HwSampleInstructionRetired,
HwSampleCacheReference,
HwSampleCacheMiss,
HwSampleBranchRetired,
HwSampleBranchMiss,
PlotConfig,
ParamSetup,
AckServerQueryNoop,
AckSourceCodeNotAvailable,
AckSymbolCodeNotAvailable,
CpuTopology,
SingleStringData,
SecondStringData,
@@ -102,14 +117,15 @@ enum class QueueType : uint8_t
ExternalThreadName,
SymbolCode,
SourceCode,
FiberName,
NUM_TYPES
};
#pragma pack( 1 )
#pragma pack( push, 1 )
struct QueueThreadContext
{
uint64_t thread;
uint32_t thread;
};
struct QueueZoneBeginLean
@@ -122,16 +138,31 @@ struct QueueZoneBegin : public QueueZoneBeginLean
uint64_t srcloc; // ptr
};
struct QueueZoneBeginThread : public QueueZoneBegin
{
uint32_t thread;
};
struct QueueZoneEnd
{
int64_t time;
};
struct QueueZoneEndThread : public QueueZoneEnd
{
uint32_t thread;
};
struct QueueZoneValidation
{
uint32_t id;
};
struct QueueZoneValidationThread : public QueueZoneValidation
{
uint32_t thread;
};
struct QueueZoneColor
{
uint8_t r;
@@ -139,11 +170,21 @@ struct QueueZoneColor
uint8_t b;
};
struct QueueZoneColorThread : public QueueZoneColor
{
uint32_t thread;
};
struct QueueZoneValue
{
uint64_t value;
};
struct QueueZoneValueThread : public QueueZoneValue
{
uint32_t thread;
};
struct QueueStringTransfer
{
uint64_t ptr;
@@ -155,6 +196,12 @@ struct QueueFrameMark
uint64_t name; // ptr
};
struct QueueFrameVsync
{
int64_t time;
uint32_t id;
};
struct QueueFrameImage
{
uint32_t frame;
@@ -185,6 +232,11 @@ struct QueueZoneTextFat
uint16_t size;
};
struct QueueZoneTextFatThread : public QueueZoneTextFat
{
uint32_t thread;
};
enum class LockType : uint8_t
{
Lockable,
@@ -199,6 +251,19 @@ struct QueueLockAnnounce
LockType type;
};
struct QueueFiberEnter
{
int64_t time;
uint64_t fiber; // ptr
uint32_t thread;
};
struct QueueFiberLeave
{
int64_t time;
uint32_t thread;
};
struct QueueLockTerminate
{
uint32_t id;
@@ -207,28 +272,32 @@ struct QueueLockTerminate
struct QueueLockWait
{
uint64_t thread;
uint32_t thread;
uint32_t id;
int64_t time;
};
struct QueueLockObtain
{
uint64_t thread;
uint32_t thread;
uint32_t id;
int64_t time;
};
struct QueueLockRelease
{
uint64_t thread;
uint32_t id;
int64_t time;
};
struct QueueLockReleaseShared : public QueueLockRelease
{
uint32_t thread;
};
struct QueueLockMark
{
uint64_t thread;
uint32_t thread;
uint32_t id;
uint64_t srcloc; // ptr
};
@@ -244,24 +313,25 @@ struct QueueLockNameFat : public QueueLockName
uint16_t size;
};
enum class PlotDataType : uint8_t
{
Float,
Double,
Int
};
struct QueuePlotData
struct QueuePlotDataBase
{
uint64_t name; // ptr
int64_t time;
PlotDataType type;
union
{
double d;
float f;
int64_t i;
} data;
};
struct QueuePlotDataInt : public QueuePlotDataBase
{
int64_t val;
};
struct QueuePlotDataFloat : public QueuePlotDataBase
{
float val;
};
struct QueuePlotDataDouble : public QueuePlotDataBase
{
double val;
};
struct QueueMessage
@@ -281,23 +351,43 @@ struct QueueMessageLiteral : public QueueMessage
uint64_t text; // ptr
};
struct QueueMessageLiteralThread : public QueueMessageLiteral
{
uint32_t thread;
};
struct QueueMessageColorLiteral : public QueueMessageColor
{
uint64_t text; // ptr
};
struct QueueMessageColorLiteralThread : public QueueMessageColorLiteral
{
uint32_t thread;
};
struct QueueMessageFat : public QueueMessage
{
uint64_t text; // ptr
uint16_t size;
};
struct QueueMessageFatThread : public QueueMessageFat
{
uint32_t thread;
};
struct QueueMessageColorFat : public QueueMessageColor
{
uint64_t text; // ptr
uint16_t size;
};
struct QueueMessageColorFatThread : public QueueMessageColorFat
{
uint32_t thread;
};
// Don't change order, only add new entries at the end, this is also used on trace dumps!
enum class GpuContextType : uint8_t
{
@@ -305,7 +395,8 @@ enum class GpuContextType : uint8_t
OpenGl,
Vulkan,
OpenCL,
Direct3D12
Direct3D12,
Direct3D11
};
enum GpuContextFlags : uint8_t
@@ -317,7 +408,7 @@ struct QueueGpuNewContext
{
int64_t cpuTime;
int64_t gpuTime;
uint64_t thread;
uint32_t thread;
float period;
uint8_t context;
GpuContextFlags flags;
@@ -327,7 +418,7 @@ struct QueueGpuNewContext
struct QueueGpuZoneBeginLean
{
int64_t cpuTime;
uint64_t thread;
uint32_t thread;
uint16_t queryId;
uint8_t context;
};
@@ -340,7 +431,7 @@ struct QueueGpuZoneBegin : public QueueGpuZoneBeginLean
struct QueueGpuZoneEnd
{
int64_t cpuTime;
uint64_t thread;
uint32_t thread;
uint16_t queryId;
uint8_t context;
};
@@ -379,7 +470,7 @@ struct QueueMemNamePayload
struct QueueMemAlloc
{
int64_t time;
uint64_t thread;
uint32_t thread;
uint64_t ptr;
char size[6];
};
@@ -387,7 +478,7 @@ struct QueueMemAlloc
struct QueueMemFree
{
int64_t time;
uint64_t thread;
uint32_t thread;
uint64_t ptr;
};
@@ -396,16 +487,26 @@ struct QueueCallstackFat
uint64_t ptr;
};
struct QueueCallstackFatThread : public QueueCallstackFat
{
uint32_t thread;
};
struct QueueCallstackAllocFat
{
uint64_t ptr;
uint64_t nativePtr;
};
struct QueueCallstackAllocFatThread : public QueueCallstackAllocFat
{
uint32_t thread;
};
struct QueueCallstackSample
{
int64_t time;
uint64_t thread;
uint32_t thread;
};
struct QueueCallstackSampleFat : public QueueCallstackSample
@@ -419,6 +520,12 @@ struct QueueCallstackFrameSize
uint8_t size;
};
struct QueueCallstackFrameSizeFat : public QueueCallstackFrameSize
{
uint64_t data;
uint64_t imageName;
};
struct QueueCallstackFrame
{
uint32_t line;
@@ -432,10 +539,10 @@ struct QueueSymbolInformation
uint64_t symAddr;
};
struct QueueCodeInformation
struct QueueSymbolInformationFat : public QueueSymbolInformation
{
uint64_t ptr;
uint32_t line;
uint64_t fileString;
uint8_t needFree;
};
struct QueueCrashReport
@@ -444,6 +551,11 @@ struct QueueCrashReport
uint64_t text; // ptr
};
struct QueueCrashReportThread
{
uint32_t thread;
};
struct QueueSysTime
{
int64_t time;
@@ -453,8 +565,8 @@ struct QueueSysTime
struct QueueContextSwitch
{
int64_t time;
uint64_t oldThread;
uint64_t newThread;
uint32_t oldThread;
uint32_t newThread;
uint8_t cpu;
uint8_t reason;
uint8_t state;
@@ -463,7 +575,7 @@ struct QueueContextSwitch
struct QueueThreadWakeup
{
int64_t time;
uint64_t thread;
uint32_t thread;
};
struct QueueTidToPid
@@ -472,10 +584,19 @@ struct QueueTidToPid
uint64_t pid;
};
struct QueueHwSample
{
uint64_t ip;
int64_t time;
};
struct QueuePlotConfig
{
uint64_t name; // ptr
uint8_t type;
uint8_t step;
uint8_t fill;
uint32_t color;
};
struct QueueParamSetup
@@ -486,6 +607,11 @@ struct QueueParamSetup
int32_t val;
};
struct QueueSourceCodeNotAvailable
{
uint32_t id;
};
struct QueueCpuTopology
{
uint32_t package;
@@ -493,6 +619,27 @@ struct QueueCpuTopology
uint32_t thread;
};
struct QueueExternalNameMetadata
{
uint64_t thread;
uint64_t name;
uint64_t threadName;
};
struct QueueSymbolCodeMetadata
{
uint64_t symbol;
uint64_t ptr;
uint32_t size;
};
struct QueueSourceCodeMetadata
{
uint64_t ptr;
uint32_t size;
uint32_t id;
};
struct QueueHeader
{
union
@@ -510,31 +657,45 @@ struct QueueItem
QueueThreadContext threadCtx;
QueueZoneBegin zoneBegin;
QueueZoneBeginLean zoneBeginLean;
QueueZoneBeginThread zoneBeginThread;
QueueZoneEnd zoneEnd;
QueueZoneEndThread zoneEndThread;
QueueZoneValidation zoneValidation;
QueueZoneValidationThread zoneValidationThread;
QueueZoneColor zoneColor;
QueueZoneColorThread zoneColorThread;
QueueZoneValue zoneValue;
QueueZoneValueThread zoneValueThread;
QueueStringTransfer stringTransfer;
QueueFrameMark frameMark;
QueueFrameVsync frameVsync;
QueueFrameImage frameImage;
QueueFrameImageFat frameImageFat;
QueueSourceLocation srcloc;
QueueZoneTextFat zoneTextFat;
QueueZoneTextFatThread zoneTextFatThread;
QueueLockAnnounce lockAnnounce;
QueueLockTerminate lockTerminate;
QueueLockWait lockWait;
QueueLockObtain lockObtain;
QueueLockRelease lockRelease;
QueueLockReleaseShared lockReleaseShared;
QueueLockMark lockMark;
QueueLockName lockName;
QueueLockNameFat lockNameFat;
QueuePlotData plotData;
QueuePlotDataInt plotDataInt;
QueuePlotDataFloat plotDataFloat;
QueuePlotDataDouble plotDataDouble;
QueueMessage message;
QueueMessageColor messageColor;
QueueMessageLiteral messageLiteral;
QueueMessageLiteralThread messageLiteralThread;
QueueMessageColorLiteral messageColorLiteral;
QueueMessageColorLiteralThread messageColorLiteralThread;
QueueMessageFat messageFat;
QueueMessageFatThread messageFatThread;
QueueMessageColorFat messageColorFat;
QueueMessageColorFatThread messageColorFatThread;
QueueGpuNewContext gpuNewContext;
QueueGpuZoneBegin gpuZoneBegin;
QueueGpuZoneBeginLean gpuZoneBeginLean;
@@ -547,24 +708,35 @@ struct QueueItem
QueueMemFree memFree;
QueueMemNamePayload memName;
QueueCallstackFat callstackFat;
QueueCallstackFatThread callstackFatThread;
QueueCallstackAllocFat callstackAllocFat;
QueueCallstackAllocFatThread callstackAllocFatThread;
QueueCallstackSample callstackSample;
QueueCallstackSampleFat callstackSampleFat;
QueueCallstackFrameSize callstackFrameSize;
QueueCallstackFrameSizeFat callstackFrameSizeFat;
QueueCallstackFrame callstackFrame;
QueueSymbolInformation symbolInformation;
QueueCodeInformation codeInformation;
QueueSymbolInformationFat symbolInformationFat;
QueueCrashReport crashReport;
QueueCrashReportThread crashReportThread;
QueueSysTime sysTime;
QueueContextSwitch contextSwitch;
QueueThreadWakeup threadWakeup;
QueueTidToPid tidToPid;
QueueHwSample hwSample;
QueuePlotConfig plotConfig;
QueueParamSetup paramSetup;
QueueCpuTopology cpuTopology;
QueueExternalNameMetadata externalNameMetadata;
QueueSymbolCodeMetadata symbolCodeMetadata;
QueueSourceCodeMetadata sourceCodeMetadata;
QueueSourceCodeNotAvailable sourceCodeNotAvailable;
QueueFiberEnter fiberEnter;
QueueFiberLeave fiberLeave;
};
};
#pragma pack()
#pragma pack( pop )
enum { QueueItemSize = sizeof( QueueItem ) };
@@ -583,6 +755,7 @@ static constexpr size_t QueueDataSize[] = {
sizeof( QueueHeader ), // callstack
sizeof( QueueHeader ), // callstack alloc
sizeof( QueueHeader ) + sizeof( QueueCallstackSample ),
sizeof( QueueHeader ) + sizeof( QueueCallstackSample ), // context switch
sizeof( QueueHeader ) + sizeof( QueueFrameImage ),
sizeof( QueueHeader ) + sizeof( QueueZoneBegin ),
sizeof( QueueHeader ) + sizeof( QueueZoneBegin ), // callstack
@@ -592,7 +765,7 @@ static constexpr size_t QueueDataSize[] = {
sizeof( QueueHeader ) + sizeof( QueueLockRelease ),
sizeof( QueueHeader ) + sizeof( QueueLockWait ), // shared
sizeof( QueueHeader ) + sizeof( QueueLockObtain ), // shared
sizeof( QueueHeader ) + sizeof( QueueLockRelease ), // shared
sizeof( QueueHeader ) + sizeof( QueueLockReleaseShared ),
sizeof( QueueHeader ) + sizeof( QueueLockName ),
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ),
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // named
@@ -612,11 +785,20 @@ static constexpr size_t QueueDataSize[] = {
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// serial, allocated source location
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// serial, allocated source location, callstack
sizeof( QueueHeader ) + sizeof( QueueGpuZoneEnd ), // serial
sizeof( QueueHeader ) + sizeof( QueuePlotData ),
sizeof( QueueHeader ) + sizeof( QueuePlotDataInt ),
sizeof( QueueHeader ) + sizeof( QueuePlotDataFloat ),
sizeof( QueueHeader ) + sizeof( QueuePlotDataDouble ),
sizeof( QueueHeader ) + sizeof( QueueContextSwitch ),
sizeof( QueueHeader ) + sizeof( QueueThreadWakeup ),
sizeof( QueueHeader ) + sizeof( QueueGpuTime ),
sizeof( QueueHeader ) + sizeof( QueueGpuContextName ),
sizeof( QueueHeader ) + sizeof( QueueCallstackFrameSize ),
sizeof( QueueHeader ) + sizeof( QueueSymbolInformation ),
sizeof( QueueHeader ), // ExternalNameMetadata - not for wire transfer
sizeof( QueueHeader ), // SymbolCodeMetadata - not for wire transfer
sizeof( QueueHeader ), // SourceCodeMetadata - not for wire transfer
sizeof( QueueHeader ) + sizeof( QueueFiberEnter ),
sizeof( QueueHeader ) + sizeof( QueueFiberLeave ),
// above items must be first
sizeof( QueueHeader ), // terminate
sizeof( QueueHeader ), // keep alive
@@ -630,6 +812,7 @@ static constexpr size_t QueueDataSize[] = {
sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // continuous frames
sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // start
sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // end
sizeof( QueueHeader ) + sizeof( QueueFrameVsync ),
sizeof( QueueHeader ) + sizeof( QueueSourceLocation ),
sizeof( QueueHeader ) + sizeof( QueueLockAnnounce ),
sizeof( QueueHeader ) + sizeof( QueueLockTerminate ),
@@ -639,16 +822,20 @@ static constexpr size_t QueueDataSize[] = {
sizeof( QueueHeader ) + sizeof( QueueMessageLiteral ), // callstack
sizeof( QueueHeader ) + sizeof( QueueMessageColorLiteral ), // callstack
sizeof( QueueHeader ) + sizeof( QueueGpuNewContext ),
sizeof( QueueHeader ) + sizeof( QueueCallstackFrameSize ),
sizeof( QueueHeader ) + sizeof( QueueCallstackFrame ),
sizeof( QueueHeader ) + sizeof( QueueSymbolInformation ),
sizeof( QueueHeader ) + sizeof( QueueCodeInformation ),
sizeof( QueueHeader ) + sizeof( QueueSysTime ),
sizeof( QueueHeader ) + sizeof( QueueTidToPid ),
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // cpu cycle
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // instruction retired
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // cache reference
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // cache miss
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // branch retired
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // branch miss
sizeof( QueueHeader ) + sizeof( QueuePlotConfig ),
sizeof( QueueHeader ) + sizeof( QueueParamSetup ),
sizeof( QueueHeader ), // server query acknowledgement
sizeof( QueueHeader ), // source code not available
sizeof( QueueHeader ) + sizeof( QueueSourceCodeNotAvailable ),
sizeof( QueueHeader ), // symbol code not available
sizeof( QueueHeader ) + sizeof( QueueCpuTopology ),
sizeof( QueueHeader ), // single string data
sizeof( QueueHeader ), // second string data
@@ -666,6 +853,7 @@ static constexpr size_t QueueDataSize[] = {
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // external thread name
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // symbol code
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // source code
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // fiber name
};
static_assert( QueueItemSize == 32, "Queue item size not 32 bytes" );

View File

@@ -8,6 +8,7 @@
#include "TracyAlloc.hpp"
#include "TracySocket.hpp"
#include "TracySystem.hpp"
#ifdef _WIN32
# ifndef NOMINMAX
@@ -454,7 +455,7 @@ static int addrinfo_and_socket_for_family( uint16_t port, int ai_family, struct
hints.ai_family = ai_family;
hints.ai_socktype = SOCK_STREAM;
#ifndef TRACY_ONLY_LOCALHOST
const char* onlyLocalhost = getenv( "TRACY_ONLY_LOCALHOST" );
const char* onlyLocalhost = GetEnvVar( "TRACY_ONLY_LOCALHOST" );
if( !onlyLocalhost || onlyLocalhost[0] != '1' )
{
hints.ai_flags = AI_PASSIVE;
@@ -475,7 +476,7 @@ bool ListenSocket::Listen( uint16_t port, int backlog )
struct addrinfo* res = nullptr;
#if !defined TRACY_ONLY_IPV4 && !defined TRACY_ONLY_LOCALHOST
const char* onlyIPv4 = getenv( "TRACY_ONLY_IPV4" );
const char* onlyIPv4 = GetEnvVar( "TRACY_ONLY_IPV4" );
if( !onlyIPv4 || onlyIPv4[0] != '1' )
{
m_sock = addrinfo_and_socket_for_family( port, AF_INET6, &res );
@@ -488,7 +489,7 @@ bool ListenSocket::Listen( uint16_t port, int backlog )
m_sock = addrinfo_and_socket_for_family( port, AF_INET, &res );
if( m_sock == -1 ) return false;
}
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
unsigned long val = 0;
setsockopt( m_sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&val, sizeof( val ) );
#elif defined BSD

View File

@@ -2,6 +2,7 @@
#define __TRACYSOCKET_HPP__
#include <atomic>
#include <stddef.h>
#include <stdint.h>
struct addrinfo;

View File

@@ -0,0 +1,122 @@
#include "TracyStackFrames.hpp"
namespace tracy
{
const char* s_tracyStackFrames_[] = {
"tracy::Callstack",
"tracy::Callstack(int)",
"tracy::GpuCtxScope::{ctor}",
"tracy::Profiler::SendCallstack",
"tracy::Profiler::SendCallstack(int)",
"tracy::Profiler::SendCallstack(int, unsigned long)",
"tracy::Profiler::MemAllocCallstack",
"tracy::Profiler::MemAllocCallstack(void const*, unsigned long, int)",
"tracy::Profiler::MemFreeCallstack",
"tracy::Profiler::MemFreeCallstack(void const*, int)",
"tracy::ScopedZone::{ctor}",
"tracy::ScopedZone::ScopedZone(tracy::SourceLocationData const*, int, bool)",
"tracy::Profiler::Message",
nullptr
};
const char** s_tracyStackFrames = s_tracyStackFrames_;
const StringMatch s_tracySkipSubframes_[] = {
{ "/include/arm_neon.h", 19 },
{ "/include/adxintrin.h", 20 },
{ "/include/ammintrin.h", 20 },
{ "/include/amxbf16intrin.h", 24 },
{ "/include/amxint8intrin.h", 24 },
{ "/include/amxtileintrin.h", 24 },
{ "/include/avx2intrin.h", 21 },
{ "/include/avx5124fmapsintrin.h", 29 },
{ "/include/avx5124vnniwintrin.h", 29 },
{ "/include/avx512bf16intrin.h", 27 },
{ "/include/avx512bf16vlintrin.h", 29 },
{ "/include/avx512bitalgintrin.h", 29 },
{ "/include/avx512bwintrin.h", 25 },
{ "/include/avx512cdintrin.h", 25 },
{ "/include/avx512dqintrin.h", 25 },
{ "/include/avx512erintrin.h", 25 },
{ "/include/avx512fintrin.h", 24 },
{ "/include/avx512ifmaintrin.h", 27 },
{ "/include/avx512ifmavlintrin.h", 29 },
{ "/include/avx512pfintrin.h", 25 },
{ "/include/avx512vbmi2intrin.h", 28 },
{ "/include/avx512vbmi2vlintrin.h", 30 },
{ "/include/avx512vbmiintrin.h", 27 },
{ "/include/avx512vbmivlintrin.h", 29 },
{ "/include/avx512vlbwintrin.h", 27 },
{ "/include/avx512vldqintrin.h", 27 },
{ "/include/avx512vlintrin.h", 25 },
{ "/include/avx512vnniintrin.h", 27 },
{ "/include/avx512vnnivlintrin.h", 29 },
{ "/include/avx512vp2intersectintrin.h", 35 },
{ "/include/avx512vp2intersectvlintrin.h", 37 },
{ "/include/avx512vpopcntdqintrin.h", 32 },
{ "/include/avx512vpopcntdqvlintrin.h", 34 },
{ "/include/avxintrin.h", 20 },
{ "/include/avxvnniintrin.h", 24 },
{ "/include/bmi2intrin.h", 21 },
{ "/include/bmiintrin.h", 20 },
{ "/include/bmmintrin.h", 20 },
{ "/include/cetintrin.h", 20 },
{ "/include/cldemoteintrin.h", 25 },
{ "/include/clflushoptintrin.h", 27 },
{ "/include/clwbintrin.h", 21 },
{ "/include/clzerointrin.h", 23 },
{ "/include/emmintrin.h", 20 },
{ "/include/enqcmdintrin.h", 23 },
{ "/include/f16cintrin.h", 21 },
{ "/include/fma4intrin.h", 21 },
{ "/include/fmaintrin.h", 20 },
{ "/include/fxsrintrin.h", 21 },
{ "/include/gfniintrin.h", 21 },
{ "/include/hresetintrin.h", 23 },
{ "/include/ia32intrin.h", 21 },
{ "/include/immintrin.h", 20 },
{ "/include/keylockerintrin.h", 26 },
{ "/include/lwpintrin.h", 20 },
{ "/include/lzcntintrin.h", 22 },
{ "/include/mmintrin.h", 19 },
{ "/include/movdirintrin.h", 23 },
{ "/include/mwaitxintrin.h", 23 },
{ "/include/nmmintrin.h", 20 },
{ "/include/pconfigintrin.h", 24 },
{ "/include/pkuintrin.h", 20 },
{ "/include/pmmintrin.h", 20 },
{ "/include/popcntintrin.h", 23 },
{ "/include/prfchwintrin.h", 23 },
{ "/include/rdseedintrin.h", 23 },
{ "/include/rtmintrin.h", 20 },
{ "/include/serializeintrin.h", 26 },
{ "/include/sgxintrin.h", 20 },
{ "/include/shaintrin.h", 20 },
{ "/include/smmintrin.h", 20 },
{ "/include/tbmintrin.h", 20 },
{ "/include/tmmintrin.h", 20 },
{ "/include/tsxldtrkintrin.h", 25 },
{ "/include/uintrintrin.h", 22 },
{ "/include/vaesintrin.h", 21 },
{ "/include/vpclmulqdqintrin.h", 27 },
{ "/include/waitpkgintrin.h", 24 },
{ "/include/wbnoinvdintrin.h", 25 },
{ "/include/wmmintrin.h", 20 },
{ "/include/x86gprintrin.h", 23 },
{ "/include/x86intrin.h", 20 },
{ "/include/xmmintrin.h", 20 },
{ "/include/xopintrin.h", 20 },
{ "/include/xsavecintrin.h", 23 },
{ "/include/xsaveintrin.h", 22 },
{ "/include/xsaveoptintrin.h", 25 },
{ "/include/xsavesintrin.h", 23 },
{ "/include/xtestintrin.h", 22 },
{ "/bits/atomic_base.h", 19 },
{ "/atomic", 7 },
{}
};
const StringMatch* s_tracySkipSubframes = s_tracySkipSubframes_;
}

View File

@@ -0,0 +1,22 @@
#ifndef __TRACYSTACKFRAMES_HPP__
#define __TRACYSTACKFRAMES_HPP__
#include <stddef.h>
namespace tracy
{
struct StringMatch
{
const char* str;
size_t len;
};
extern const char** s_tracyStackFrames;
extern const StringMatch* s_tracySkipSubframes;
static constexpr int s_tracySkipSubframesMinLen = 7;
}
#endif

View File

@@ -1,16 +1,16 @@
#if defined _MSC_VER || defined __CYGWIN__ || defined _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# ifndef NOMINMAX
# define NOMINMAX
# endif
#endif
#ifdef _MSC_VER
# pragma warning(disable:4996)
#endif
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# ifndef NOMINMAX
# define NOMINMAX
# endif
# include <windows.h>
# include <malloc.h>
# include "TracyUwp.hpp"
#else
# include <pthread.h>
# include <string.h>
@@ -39,7 +39,7 @@
#include "TracySystem.hpp"
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
extern "C" typedef HRESULT (WINAPI *t_SetThreadDescription)( HANDLE, PCWSTR );
extern "C" typedef HRESULT (WINAPI *t_GetThreadDescription)( HANDLE, PWSTR* );
#endif
@@ -55,19 +55,19 @@ namespace tracy
namespace detail
{
TRACY_API uint64_t GetThreadHandleImpl()
TRACY_API uint32_t GetThreadHandleImpl()
{
#if defined _WIN32 || defined __CYGWIN__
static_assert( sizeof( decltype( GetCurrentThreadId() ) ) <= sizeof( uint64_t ), "Thread handle too big to fit in protocol" );
return uint64_t( GetCurrentThreadId() );
#if defined _WIN32
static_assert( sizeof( decltype( GetCurrentThreadId() ) ) <= sizeof( uint32_t ), "Thread handle too big to fit in protocol" );
return uint32_t( GetCurrentThreadId() );
#elif defined __APPLE__
uint64_t id;
pthread_threadid_np( pthread_self(), &id );
return id;
return uint32_t( id );
#elif defined __ANDROID__
return (uint64_t)gettid();
return (uint32_t)gettid();
#elif defined __linux__
return (uint64_t)syscall( SYS_gettid );
return (uint32_t)syscall( SYS_gettid );
#elif defined __FreeBSD__
long id;
thr_self( &id );
@@ -78,9 +78,17 @@ TRACY_API uint64_t GetThreadHandleImpl()
return lwp_gettid();
#elif defined __OpenBSD__
return getthrid();
#elif defined __EMSCRIPTEN__
// Not supported, but let it compile.
return 0;
#else
static_assert( sizeof( decltype( pthread_self() ) ) <= sizeof( uint64_t ), "Thread handle too big to fit in protocol" );
return uint64_t( pthread_self() );
// To add support for a platform, retrieve and return the kernel thread identifier here.
//
// Note that pthread_t (as for example returned by pthread_self()) is *not* a kernel
// thread identifier. It is a pointer to a library-allocated data structure instead.
// Such pointers will be reused heavily, making the pthread_t non-unique. Additionally
// a 64-bit pointer cannot be reliably truncated to 32 bits.
#error "Unsupported platform!"
#endif
}
@@ -90,18 +98,44 @@ TRACY_API uint64_t GetThreadHandleImpl()
#ifdef TRACY_ENABLE
struct ThreadNameData
{
uint64_t id;
uint32_t id;
const char* name;
ThreadNameData* next;
};
std::atomic<ThreadNameData*>& GetThreadNameData();
TRACY_API void InitRPMallocThread();
#endif
#ifdef _MSC_VER
# pragma pack( push, 8 )
struct THREADNAME_INFO
{
DWORD dwType;
LPCSTR szName;
DWORD dwThreadID;
DWORD dwFlags;
};
# pragma pack( pop )
void ThreadNameMsvcMagic( const THREADNAME_INFO& info )
{
__try
{
RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
#endif
TRACY_API void SetThreadName( const char* name )
{
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
# ifdef TRACY_UWP
static auto _SetThreadDescription = &::SetThreadDescription;
# else
static auto _SetThreadDescription = (t_SetThreadDescription)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "SetThreadDescription" );
# endif
if( _SetThreadDescription )
{
wchar_t buf[256];
@@ -111,57 +145,45 @@ TRACY_API void SetThreadName( const char* name )
else
{
# if defined _MSC_VER
const DWORD MS_VC_EXCEPTION=0x406D1388;
# pragma pack( push, 8 )
struct THREADNAME_INFO
{
DWORD dwType;
LPCSTR szName;
DWORD dwThreadID;
DWORD dwFlags;
};
# pragma pack(pop)
DWORD ThreadId = GetCurrentThreadId();
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = name;
info.dwThreadID = ThreadId;
info.dwThreadID = GetCurrentThreadId();
info.dwFlags = 0;
__try
{
RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
ThreadNameMsvcMagic( info );
# endif
}
#elif defined _GNU_SOURCE && !defined __EMSCRIPTEN__ && !defined __CYGWIN__
#elif defined _GNU_SOURCE && !defined __EMSCRIPTEN__
{
const auto sz = strlen( name );
if( sz <= 15 )
{
#if defined __APPLE__
pthread_setname_np( name );
#else
pthread_setname_np( pthread_self(), name );
#endif
}
else
{
char buf[16];
memcpy( buf, name, 15 );
buf[15] = '\0';
#if defined __APPLE__
pthread_setname_np( buf );
#else
pthread_setname_np( pthread_self(), buf );
#endif
}
}
#endif
#ifdef TRACY_ENABLE
{
InitRPMallocThread();
const auto sz = strlen( name );
char* buf = (char*)tracy_malloc( sz+1 );
memcpy( buf, name, sz );
buf[sz] = '\0';
auto data = (ThreadNameData*)tracy_malloc( sizeof( ThreadNameData ) );
auto data = (ThreadNameData*)tracy_malloc_fast( sizeof( ThreadNameData ) );
data->id = detail::GetThreadHandleImpl();
data->name = buf;
data->next = GetThreadNameData().load( std::memory_order_relaxed );
@@ -170,7 +192,7 @@ TRACY_API void SetThreadName( const char* name )
#endif
}
TRACY_API const char* GetThreadName( uint64_t id )
TRACY_API const char* GetThreadName( uint32_t id )
{
static char buf[256];
#ifdef TRACY_ENABLE
@@ -184,8 +206,12 @@ TRACY_API const char* GetThreadName( uint64_t id )
ptr = ptr->next;
}
#else
# if defined _WIN32 || defined __CYGWIN__
# if defined _WIN32
# ifdef TRACY_UWP
static auto _GetThreadDescription = &::GetThreadDescription;
# else
static auto _GetThreadDescription = (t_GetThreadDescription)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "GetThreadDescription" );
# endif
if( _GetThreadDescription )
{
auto hnd = OpenThread( THREAD_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)id );
@@ -210,7 +236,7 @@ TRACY_API const char* GetThreadName( uint64_t id )
int tid = (int) syscall( SYS_gettid );
# endif
snprintf( path, sizeof( path ), "/proc/self/task/%d/comm", tid );
sprintf( buf, "%" PRIu64, id );
sprintf( buf, "%" PRIu32, id );
# ifndef __ANDROID__
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &cs );
# endif
@@ -232,8 +258,40 @@ TRACY_API const char* GetThreadName( uint64_t id )
return buf;
# endif
#endif
sprintf( buf, "%" PRIu64, id );
sprintf( buf, "%" PRIu32, id );
return buf;
}
TRACY_API const char* GetEnvVar( const char* name )
{
#if defined _WIN32
// unfortunately getenv() on Windows is just fundamentally broken. It caches the entire
// environment block once on startup, then never refreshes it again. If any environment
// strings are added or modified after startup of the CRT, those changes will not be
// seen by getenv(). This removes the possibility of an app using this SDK from
// programmatically setting any of the behaviour controlling envvars here.
//
// To work around this, we'll instead go directly to the Win32 environment strings APIs
// to get the current value.
static char buffer[1024];
DWORD const kBufferSize = DWORD(sizeof(buffer) / sizeof(buffer[0]));
DWORD count = GetEnvironmentVariableA(name, buffer, kBufferSize);
if( count == 0 )
return nullptr;
if( count >= kBufferSize )
{
char* buf = reinterpret_cast<char*>(_alloca(count + 1));
count = GetEnvironmentVariableA(name, buf, count + 1);
memcpy(buffer, buf, kBufferSize);
buffer[kBufferSize - 1] = 0;
}
return buffer;
#else
return getenv(name);
#endif
}
}

View File

@@ -32,7 +32,7 @@ enum class PlotFormatType : uint8_t
Percentage
};
typedef void(*ParameterCallback)( uint32_t idx, int32_t val );
typedef void(*ParameterCallback)( void* data, uint32_t idx, int32_t val );
struct TRACY_API SourceLocationData
{
@@ -80,20 +80,22 @@ private:
namespace detail
{
TRACY_API uint64_t GetThreadHandleImpl();
TRACY_API uint32_t GetThreadHandleImpl();
}
#ifdef TRACY_ENABLE
TRACY_API uint64_t GetThreadHandle();
TRACY_API uint32_t GetThreadHandle();
#else
static inline uint64_t GetThreadHandle()
static inline uint32_t GetThreadHandle()
{
return detail::GetThreadHandleImpl();
}
#endif
TRACY_API void SetThreadName( const char* name );
TRACY_API const char* GetThreadName( uint64_t id );
TRACY_API const char* GetThreadName( uint32_t id );
TRACY_API const char* GetEnvVar(const char* name);
}

View File

@@ -0,0 +1,11 @@
#ifndef __TRACYUWP_HPP__
#define __TRACYUWP_HPP__
#ifdef _WIN32
# include <winapifamily.h>
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
# define TRACY_UWP
# endif
#endif
#endif

View File

@@ -0,0 +1,14 @@
#ifndef __TRACYVERSION_HPP__
#define __TRACYVERSION_HPP__
namespace tracy
{
namespace Version
{
enum { Major = 0 };
enum { Minor = 9 };
enum { Patch = 0 };
}
}
#endif

View File

@@ -0,0 +1,26 @@
#ifndef __TRACYYIELD_HPP__
#define __TRACYYIELD_HPP__
#if defined __SSE2__ || defined _M_AMD64 || (defined _M_IX86_FP && _M_IX86_FP == 2)
# include <emmintrin.h>
#else
# include <thread>
#endif
namespace tracy
{
static tracy_force_inline void YieldThread()
{
#if defined __SSE2__ || defined _M_AMD64 || (defined _M_IX86_FP && _M_IX86_FP == 2)
_mm_pause();
#elif defined __aarch64__
asm volatile( "isb" : : );
#else
std::this_thread::yield();
#endif
}
}
#endif

View File

@@ -53,13 +53,14 @@ struct backtrace_state;
invalid after this function returns.
As a special case, the ERRNUM argument will be passed as -1 if no
debug info can be found for the executable, but the function
requires debug info (e.g., backtrace_full, backtrace_pcinfo). The
MSG in this case will be something along the lines of "no debug
info". Similarly, ERRNUM will be passed as -1 if there is no
symbol table, but the function requires a symbol table (e.g.,
backtrace_syminfo). This may be used as a signal that some other
approach should be tried. */
debug info can be found for the executable, or if the debug info
exists but has an unsupported version, but the function requires
debug info (e.g., backtrace_full, backtrace_pcinfo). The MSG in
this case will be something along the lines of "no debug info".
Similarly, ERRNUM will be passed as -1 if there is no symbol table,
but the function requires a symbol table (e.g., backtrace_syminfo).
This may be used as a signal that some other approach should be
tried. */
typedef void (*backtrace_error_callback) (void *data, const char *msg,
int errnum);

View File

@@ -52,6 +52,7 @@ enum dwarf_tag {
DW_TAG_compile_unit = 0x11,
DW_TAG_inlined_subroutine = 0x1d,
DW_TAG_subprogram = 0x2e,
DW_TAG_skeleton_unit = 0x4a,
};
enum dwarf_form {
@@ -746,13 +747,13 @@ struct dwarf_data
/* Report an error for a DWARF buffer. */
static void
dwarf_buf_error (struct dwarf_buf *buf, const char *msg)
dwarf_buf_error (struct dwarf_buf *buf, const char *msg, int errnum)
{
char b[200];
snprintf (b, sizeof b, "%s in %s at %d",
msg, buf->name, (int) (buf->buf - buf->start));
buf->error_callback (buf->data, b, 0);
buf->error_callback (buf->data, b, errnum);
}
/* Require at least COUNT bytes in BUF. Return 1 if all is well, 0 on
@@ -766,7 +767,7 @@ require (struct dwarf_buf *buf, size_t count)
if (!buf->reported_underflow)
{
dwarf_buf_error (buf, "DWARF underflow");
dwarf_buf_error (buf, "DWARF underflow", 0);
buf->reported_underflow = 1;
}
@@ -928,7 +929,7 @@ read_address (struct dwarf_buf *buf, int addrsize)
case 8:
return read_uint64 (buf);
default:
dwarf_buf_error (buf, "unrecognized address size");
dwarf_buf_error (buf, "unrecognized address size", 0);
return 0;
}
}
@@ -979,7 +980,7 @@ read_uleb128 (struct dwarf_buf *buf)
ret |= ((uint64_t) (b & 0x7f)) << shift;
else if (!overflow)
{
dwarf_buf_error (buf, "LEB128 overflows uint64_t");
dwarf_buf_error (buf, "LEB128 overflows uint64_t", 0);
overflow = 1;
}
shift += 7;
@@ -1014,7 +1015,7 @@ read_sleb128 (struct dwarf_buf *buf)
val |= ((uint64_t) (b & 0x7f)) << shift;
else if (!overflow)
{
dwarf_buf_error (buf, "signed LEB128 overflows uint64_t");
dwarf_buf_error (buf, "signed LEB128 overflows uint64_t", 0);
overflow = 1;
}
shift += 7;
@@ -1154,7 +1155,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
offset = read_offset (buf, is_dwarf64);
if (offset >= dwarf_sections->size[DEBUG_STR])
{
dwarf_buf_error (buf, "DW_FORM_strp out of range");
dwarf_buf_error (buf, "DW_FORM_strp out of range", 0);
return 0;
}
val->encoding = ATTR_VAL_STRING;
@@ -1169,7 +1170,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
offset = read_offset (buf, is_dwarf64);
if (offset >= dwarf_sections->size[DEBUG_LINE_STR])
{
dwarf_buf_error (buf, "DW_FORM_line_strp out of range");
dwarf_buf_error (buf, "DW_FORM_line_strp out of range", 0);
return 0;
}
val->encoding = ATTR_VAL_STRING;
@@ -1216,7 +1217,8 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
if (form == DW_FORM_implicit_const)
{
dwarf_buf_error (buf,
"DW_FORM_indirect to DW_FORM_implicit_const");
"DW_FORM_indirect to DW_FORM_implicit_const",
0);
return 0;
}
return read_attribute ((enum dwarf_form) form, 0, buf, is_dwarf64,
@@ -1349,7 +1351,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
}
if (offset >= altlink->dwarf_sections.size[DEBUG_STR])
{
dwarf_buf_error (buf, "DW_FORM_strp_sup out of range");
dwarf_buf_error (buf, "DW_FORM_strp_sup out of range", 0);
return 0;
}
val->encoding = ATTR_VAL_STRING;
@@ -1358,7 +1360,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
return 1;
}
default:
dwarf_buf_error (buf, "unrecognized DWARF form");
dwarf_buf_error (buf, "unrecognized DWARF form", -1);
return 0;
}
}
@@ -1407,7 +1409,9 @@ resolve_string (const struct dwarf_sections *dwarf_sections, int is_dwarf64,
offset = read_offset (&offset_buf, is_dwarf64);
if (offset >= dwarf_sections->size[DEBUG_STR])
{
dwarf_buf_error (&offset_buf, "DW_FORM_strx offset out of range");
dwarf_buf_error (&offset_buf,
"DW_FORM_strx offset out of range",
0);
return 0;
}
*string = (const char *) dwarf_sections->data[DEBUG_STR] + offset;
@@ -2215,7 +2219,7 @@ add_ranges_from_rnglists (
break;
default:
dwarf_buf_error (&rnglists_buf, "unrecognized DW_RLE value");
dwarf_buf_error (&rnglists_buf, "unrecognized DW_RLE value", -1);
return 0;
}
}
@@ -2322,14 +2326,16 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
break;
case DW_AT_stmt_list:
if (abbrev->tag == DW_TAG_compile_unit
if ((abbrev->tag == DW_TAG_compile_unit
|| abbrev->tag == DW_TAG_skeleton_unit)
&& (val.encoding == ATTR_VAL_UINT
|| val.encoding == ATTR_VAL_REF_SECTION))
u->lineoff = val.u.uint;
break;
case DW_AT_name:
if (abbrev->tag == DW_TAG_compile_unit)
if (abbrev->tag == DW_TAG_compile_unit
|| abbrev->tag == DW_TAG_skeleton_unit)
{
name_val = val;
have_name_val = 1;
@@ -2337,7 +2343,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
break;
case DW_AT_comp_dir:
if (abbrev->tag == DW_TAG_compile_unit)
if (abbrev->tag == DW_TAG_compile_unit
|| abbrev->tag == DW_TAG_skeleton_unit)
{
comp_dir_val = val;
have_comp_dir_val = 1;
@@ -2345,19 +2352,22 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
break;
case DW_AT_str_offsets_base:
if (abbrev->tag == DW_TAG_compile_unit
if ((abbrev->tag == DW_TAG_compile_unit
|| abbrev->tag == DW_TAG_skeleton_unit)
&& val.encoding == ATTR_VAL_REF_SECTION)
u->str_offsets_base = val.u.uint;
break;
case DW_AT_addr_base:
if (abbrev->tag == DW_TAG_compile_unit
if ((abbrev->tag == DW_TAG_compile_unit
|| abbrev->tag == DW_TAG_skeleton_unit)
&& val.encoding == ATTR_VAL_REF_SECTION)
u->addr_base = val.u.uint;
break;
case DW_AT_rnglists_base:
if (abbrev->tag == DW_TAG_compile_unit
if ((abbrev->tag == DW_TAG_compile_unit
|| abbrev->tag == DW_TAG_skeleton_unit)
&& val.encoding == ATTR_VAL_REF_SECTION)
u->rnglists_base = val.u.uint;
break;
@@ -2385,7 +2395,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
}
if (abbrev->tag == DW_TAG_compile_unit
|| abbrev->tag == DW_TAG_subprogram)
|| abbrev->tag == DW_TAG_subprogram
|| abbrev->tag == DW_TAG_skeleton_unit)
{
if (!add_ranges (state, dwarf_sections, base_address,
is_bigendian, u, pcrange.lowpc, &pcrange,
@@ -2393,9 +2404,10 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
(void *) addrs))
return 0;
/* If we found the PC range in the DW_TAG_compile_unit, we
can stop now. */
if (abbrev->tag == DW_TAG_compile_unit
/* If we found the PC range in the DW_TAG_compile_unit or
DW_TAG_skeleton_unit, we can stop now. */
if ((abbrev->tag == DW_TAG_compile_unit
|| abbrev->tag == DW_TAG_skeleton_unit)
&& (pcrange.have_ranges
|| (pcrange.have_lowpc && pcrange.have_highpc)))
return 1;
@@ -2482,7 +2494,7 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
version = read_uint16 (&unit_buf);
if (version < 2 || version > 5)
{
dwarf_buf_error (&unit_buf, "unrecognized DWARF version");
dwarf_buf_error (&unit_buf, "unrecognized DWARF version", -1);
goto fail;
}
@@ -2554,6 +2566,9 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
u->comp_dir = NULL;
u->abs_filename = NULL;
u->lineoff = 0;
u->str_offsets_base = 0;
u->addr_base = 0;
u->rnglists_base = 0;
/* The actual line number mappings will be read as needed. */
u->lines = NULL;
@@ -2761,7 +2776,8 @@ read_v2_paths (struct backtrace_state *state, struct unit *u,
{
dwarf_buf_error (hdr_buf,
("invalid directory index in "
"line number program header"));
"line number program header"),
0);
return 0;
}
dir_len = strlen (dir);
@@ -2830,7 +2846,8 @@ read_lnct (struct backtrace_state *state, struct dwarf_data *ddata,
{
dwarf_buf_error (hdr_buf,
("invalid directory index in "
"line number program header"));
"line number program header"),
0);
return 0;
}
dir = hdr->dirs[val.u.uint];
@@ -2845,7 +2862,8 @@ read_lnct (struct backtrace_state *state, struct dwarf_data *ddata,
if (path == NULL)
{
dwarf_buf_error (hdr_buf,
"missing file name in line number program header");
"missing file name in line number program header",
0);
return 0;
}
@@ -2972,7 +2990,7 @@ read_line_header (struct backtrace_state *state, struct dwarf_data *ddata,
hdr->version = read_uint16 (line_buf);
if (hdr->version < 2 || hdr->version > 5)
{
dwarf_buf_error (line_buf, "unsupported line number version");
dwarf_buf_error (line_buf, "unsupported line number version", -1);
return 0;
}
@@ -2986,7 +3004,8 @@ read_line_header (struct backtrace_state *state, struct dwarf_data *ddata,
if (read_byte (line_buf) != 0)
{
dwarf_buf_error (line_buf,
"non-zero segment_selector_size not supported");
"non-zero segment_selector_size not supported",
-1);
return 0;
}
}
@@ -3127,7 +3146,8 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
{
dwarf_buf_error (line_buf,
("invalid directory index "
"in line number program"));
"in line number program"),
0);
return 0;
}
dir_len = strlen (dir);
@@ -3185,19 +3205,15 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
uint64_t fileno;
fileno = read_uleb128 (line_buf);
if (fileno == 0)
filename = "";
else
if (fileno >= hdr->filenames_count)
{
if (fileno >= hdr->filenames_count)
{
dwarf_buf_error (line_buf,
("invalid file number in "
"line number program"));
return 0;
}
filename = hdr->filenames[fileno];
dwarf_buf_error (line_buf,
("invalid file number in "
"line number program"),
0);
return 0;
}
filename = hdr->filenames[fileno];
}
break;
case DW_LNS_set_column:
@@ -3428,7 +3444,9 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u,
code = read_uleb128 (&unit_buf);
if (code == 0)
{
dwarf_buf_error (&unit_buf, "invalid abstract origin or specification");
dwarf_buf_error (&unit_buf,
"invalid abstract origin or specification",
0);
return NULL;
}
@@ -3601,7 +3619,8 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
/* The compile unit sets the base address for any address
ranges in the function entries. */
if (abbrev->tag == DW_TAG_compile_unit
if ((abbrev->tag == DW_TAG_compile_unit
|| abbrev->tag == DW_TAG_skeleton_unit)
&& abbrev->attrs[i].name == DW_AT_low_pc)
{
if (val.encoding == ATTR_VAL_ADDRESS)
@@ -3623,20 +3642,15 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
case DW_AT_call_file:
if (val.encoding == ATTR_VAL_UINT)
{
if (val.u.uint == 0)
function->caller_filename = "";
else
if (val.u.uint >= lhdr->filenames_count)
{
if (val.u.uint >= lhdr->filenames_count)
{
dwarf_buf_error (unit_buf,
("invalid file number in "
"DW_AT_call_file attribute"));
return 0;
}
function->caller_filename =
lhdr->filenames[val.u.uint];
dwarf_buf_error (unit_buf,
("invalid file number in "
"DW_AT_call_file attribute"),
0);
return 0;
}
function->caller_filename = lhdr->filenames[val.u.uint];
}
break;
@@ -3884,7 +3898,7 @@ read_function_info (struct backtrace_state *state, struct dwarf_data *ddata,
Returns whatever CALLBACK returns, or 0 to keep going. */
static int
report_inlined_functions (uintptr_t pc, struct function *function,
report_inlined_functions (uintptr_t pc, struct function *function, const char* comp_dir,
backtrace_full_callback callback, void *data,
const char **filename, int *lineno)
{
@@ -3938,13 +3952,22 @@ report_inlined_functions (uintptr_t pc, struct function *function,
inlined = match->function;
/* Report any calls inlined into this one. */
ret = report_inlined_functions (pc, inlined, callback, data,
ret = report_inlined_functions (pc, inlined, comp_dir, callback, data,
filename, lineno);
if (ret != 0)
return ret;
/* Report this inlined call. */
ret = callback (data, pc, match->low, *filename, *lineno, inlined->name);
if (*filename[0] != '/' && comp_dir)
{
char buf[1024];
snprintf (buf, 1024, "%s/%s", comp_dir, *filename);
ret = callback (data, pc, match->low, buf, *lineno, inlined->name);
}
else
{
ret = callback (data, pc, match->low, *filename, *lineno, inlined->name);
}
if (ret != 0)
return ret;
@@ -4211,12 +4234,21 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
filename = ln->filename;
lineno = ln->lineno;
ret = report_inlined_functions (pc, function, callback, data,
ret = report_inlined_functions (pc, function, entry->u->comp_dir, callback, data,
&filename, &lineno);
if (ret != 0)
return ret;
return callback (data, pc, fmatch->low, filename, lineno, function->name);
if (filename[0] != '/' && entry->u->comp_dir)
{
char buf[1024];
snprintf (buf, 1024, "%s/%s", entry->u->comp_dir, filename);
return callback (data, pc, fmatch->low, buf, lineno, function->name);
}
else
{
return callback (data, pc, fmatch->low, filename, lineno, function->name);
}
}

View File

@@ -46,6 +46,9 @@ POSSIBILITY OF SUCH DAMAGE. */
#include "backtrace.hpp"
#include "internal.hpp"
#include "../client/TracyFastVector.hpp"
#include "../common/TracyAlloc.hpp"
#ifndef S_ISLNK
#ifndef S_IFLNK
#define S_IFLNK 0120000
@@ -70,6 +73,10 @@ POSSIBILITY OF SUCH DAMAGE. */
namespace tracy
{
#ifdef TRACY_DEBUGINFOD
int GetDebugInfoDescriptor( const char* buildid_data, size_t buildid_size );
#endif
#if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN
/* If strnlen is not declared, provide our own version. */
@@ -867,6 +874,7 @@ elf_readlink (struct backtrace_state *state, const char *filename,
static int
elf_open_debugfile_by_buildid (struct backtrace_state *state,
const char *buildid_data, size_t buildid_size,
const char *filename,
backtrace_error_callback error_callback,
void *data)
{
@@ -913,7 +921,14 @@ elf_open_debugfile_by_buildid (struct backtrace_state *state,
That seems kind of pointless to me--why would it have the right
name but not the right build ID?--so skipping the check. */
#ifdef TRACY_DEBUGINFOD
if (ret == -1)
return GetDebugInfoDescriptor( buildid_data, buildid_size, filename );
else
return ret;
#else
return ret;
#endif
}
/* Try to open a file whose name is PREFIX (length PREFIX_LEN)
@@ -1803,7 +1818,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
/* An uncompressed block. */
/* If we've read ahead more than a byte, back up. */
while (bits > 8)
while (bits >= 8)
{
--pin;
bits -= 8;
@@ -4429,7 +4444,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
int d;
d = elf_open_debugfile_by_buildid (state, buildid_data, buildid_size,
error_callback, data);
filename, error_callback, data);
if (d >= 0)
{
int ret;
@@ -4812,12 +4827,34 @@ struct phdr_data
/* Callback passed to dl_iterate_phdr. Load debug info from shared
libraries. */
struct PhdrIterate
{
char* dlpi_name;
ElfW(Addr) dlpi_addr;
};
FastVector<PhdrIterate> s_phdrData(16);
static int
phdr_callback_mock (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
void *pdata)
{
auto ptr = s_phdrData.push_next();
if (info->dlpi_name)
{
size_t sz = strlen (info->dlpi_name) + 1;
ptr->dlpi_name = (char*)tracy_malloc (sz);
memcpy (ptr->dlpi_name, info->dlpi_name, sz);
}
else ptr->dlpi_name = nullptr;
ptr->dlpi_addr = info->dlpi_addr;
return 0;
}
static int
#ifdef __i386__
__attribute__ ((__force_align_arg_pointer__))
#endif
phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
void *pdata)
phdr_callback (struct PhdrIterate *info, void *pdata)
{
struct phdr_data *pd = (struct phdr_data *) pdata;
const char *filename;
@@ -4896,7 +4933,14 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
pd.exe_filename = filename;
pd.exe_descriptor = ret < 0 ? descriptor : -1;
dl_iterate_phdr (phdr_callback, (void *) &pd);
assert (s_phdrData.empty());
dl_iterate_phdr (phdr_callback_mock, nullptr);
for (auto& v : s_phdrData)
{
phdr_callback (&v, (void *) &pd);
tracy_free (v.dlpi_name);
}
s_phdrData.clear();
if (!state->threaded)
{

View File

@@ -1271,7 +1271,7 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
mff = macho_nodebug;
if (!macho_add (state, name, d, 0, NULL, base_address, 0,
error_callback, data, &mff, &mfs))
return 0;
continue;
if (mff != macho_nodebug)
macho_fileline_fn = mff;
@@ -1292,7 +1292,7 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
else
{
if (found_sym)
backtrace_atomic_store_pointer (&state->syminfo_fn, macho_syminfo);
backtrace_atomic_store_pointer (&state->syminfo_fn, &macho_syminfo);
else
(void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL,
macho_nosyms);
@@ -1338,7 +1338,7 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
else
{
if (found_sym)
backtrace_atomic_store_pointer (&state->syminfo_fn, macho_syminfo);
backtrace_atomic_store_pointer (&state->syminfo_fn, &macho_syminfo);
else
(void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL,
macho_nosyms);

View File

@@ -34,11 +34,12 @@ public class tracy : ThirdPartyModule
options.SourcePaths.Clear();
options.SourceFiles.Clear();
options.SourceFiles.Add(Path.Combine(FolderPath, "Tracy.h"));
options.SourceFiles.Add(Path.Combine(FolderPath, "tracy", "Tracy.hpp"));
options.SourceFiles.Add(Path.Combine(FolderPath, "TracyClient.cpp"));
options.PublicDefinitions.Add("TRACY_ENABLE");
options.PrivateDefinitions.Add("TRACY_NO_INVARIANT_CHECK");
options.PrivateDefinitions.Add("TRACY_NO_FRAME_IMAGE");
if (options.Platform.Target == TargetPlatform.Windows)
{
options.PrivateDefinitions.Add("TRACY_DBGHELP_LOCK=DbgHelp");
@@ -54,7 +55,7 @@ public class tracy : ThirdPartyModule
{
base.GetFilesToDeploy(files);
files.Add(Path.Combine(FolderPath, "Tracy.h"));
files.Add(Path.Combine(FolderPath, "tracy", "Tracy.hpp"));
files.Add(Path.Combine(FolderPath, "common", "TracySystem.hpp"));
files.Add(Path.Combine(FolderPath, "client", "TracyCallstack.h"));
}

View File

@@ -24,12 +24,14 @@
#define ZoneColorV(x,y)
#define ZoneValue(x)
#define ZoneValueV(x,y)
#define ZoneIsActive false
#define ZoneIsActiveV(x) false
#define FrameMark
#define FrameMarkNamed(x)
#define TracyPlot(x,y)
#define TracyPlotConfig(x,y)
#define TracyPlotConfig(x,y,z,w,a)
#define TracyMessage(x,y)
#define TracyMessageL(x)
@@ -75,15 +77,19 @@
#define TracyMessageCS(x,y,z,w)
#define TracyMessageLCS(x,y,z)
#define TracyParameterRegister(x)
#define TracySourceCallbackRegister(x,y)
#define TracyParameterRegister(x,y)
#define TracyParameterSetup(x,y,z,w)
#define TracyFiberEnter(x)
#define TracyFiberLeave
#else
#include <string.h>
#include "common/TracySystem.hpp"
#include "client/TracyCallstack.h"
#include "../common/TracyQueue.hpp"
#include "../common/TracySystem.hpp"
namespace tracy
{
@@ -91,10 +97,12 @@ class TRACY_API Profiler
{
public:
static void SendFrameMark( const char* name );
static void SendFrameMark( const char* name, QueueType type );
static void SendFrameImage( const void* image, uint16_t w, uint16_t h, uint8_t offset, bool flip );
static void PlotData( const char* name, int64_t val );
static void PlotData( const char* name, float val );
static void PlotData( const char* name, double val );
static void ConfigurePlot( const char* name, PlotFormatType type );
static void ConfigurePlot( const char* name, PlotFormatType type, bool step, bool fill, uint32_t color );
static void Message( const char* txt, size_t size, int callstack );
static void Message( const char* txt, int callstack );
static void MessageColor( const char* txt, size_t size, uint32_t color, int callstack );
@@ -108,27 +116,29 @@ public:
static void MemFreeNamed( const void* ptr, bool secure, const char* name );
static void MemAllocCallstackNamed( const void* ptr, size_t size, int depth, bool secure, const char* name );
static void MemFreeCallstackNamed( const void* ptr, int depth, bool secure, const char* name );
static void SendCallstack( int depth );
static void ParameterRegister( ParameterCallback cb );
static void ParameterRegister( ParameterCallback cb, void* data );
static void ParameterSetup( uint32_t idx, const char* name, bool isBool, int32_t val );
};
}
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
# define ZoneNamed( varname, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
# define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
# define ZoneNamedC( varname, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
# define ZoneNamedNC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
# define ZoneNamed( varname, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active )
# define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active )
# define ZoneNamedC( varname, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active )
# define ZoneNamedNC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active )
# define ZoneTransient( varname, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), nullptr, 0, TRACY_CALLSTACK, active );
# define ZoneTransientN( varname, name, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), name, strlen( name ), TRACY_CALLSTACK, active );
# define ZoneTransient( varname, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), nullptr, 0, TRACY_CALLSTACK, active )
# define ZoneTransientN( varname, name, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), name, strlen( name ), TRACY_CALLSTACK, active )
#else
# define ZoneNamed( varname, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active );
# define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active );
# define ZoneNamedC( varname, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active );
# define ZoneNamedNC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active );
# define ZoneNamed( varname, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active )
# define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active )
# define ZoneNamedC( varname, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active )
# define ZoneNamedNC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active )
# define ZoneTransient( varname, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), nullptr, 0, active );
# define ZoneTransientN( varname, name, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), name, strlen( name ), active );
# define ZoneTransient( varname, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), nullptr, 0, active )
# define ZoneTransientN( varname, name, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), name, strlen( name ), active )
#endif
#define ZoneScoped ZoneNamed( ___tracy_scoped_zone, true )
@@ -136,83 +146,98 @@ public:
#define ZoneScopedC( color ) ZoneNamedC( ___tracy_scoped_zone, color, true )
#define ZoneScopedNC( name, color ) ZoneNamedNC( ___tracy_scoped_zone, name, color, true )
#define ZoneText( txt, size ) ___tracy_scoped_zone.Text( txt, size );
#define ZoneTextV( varname, txt, size ) varname.Text( txt, size );
#define ZoneName( txt, size ) ___tracy_scoped_zone.Name( txt, size );
#define ZoneNameV( varname, txt, size ) varname.Name( txt, size );
#define ZoneColor( color ) ___tracy_scoped_zone.Color( color );
#define ZoneColorV( varname, color ) varname.Color( color );
#define ZoneValue( value ) ___tracy_scoped_zone.Value( value );
#define ZoneValueV( varname, value ) varname.Value( value );
#define ZoneText( txt, size ) ___tracy_scoped_zone.Text( txt, size )
#define ZoneTextV( varname, txt, size ) varname.Text( txt, size )
#define ZoneName( txt, size ) ___tracy_scoped_zone.Name( txt, size )
#define ZoneNameV( varname, txt, size ) varname.Name( txt, size )
#define ZoneColor( color ) ___tracy_scoped_zone.Color( color )
#define ZoneColorV( varname, color ) varname.Color( color )
#define ZoneValue( value ) ___tracy_scoped_zone.Value( value )
#define ZoneValueV( varname, value ) varname.Value( value )
#define ZoneIsActive ___tracy_scoped_zone.IsActive()
#define ZoneIsActiveV( varname ) varname.IsActive()
#define FrameMark tracy::Profiler::SendFrameMark( nullptr );
#define FrameMarkNamed( name ) tracy::Profiler::SendFrameMark( name );
#define FrameMark tracy::Profiler::SendFrameMark( nullptr )
#define FrameMarkNamed( name ) tracy::Profiler::SendFrameMark( name )
#define FrameMarkStart( name ) tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgStart )
#define FrameMarkEnd( name ) tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgEnd )
#define TracyPlot( name, val ) tracy::Profiler::PlotData( name, val );
#define TracyPlotConfig( name, type ) tracy::Profiler::ConfigurePlot( name, type );
#define FrameImage( image, width, height, offset, flip ) tracy::Profiler::SendFrameImage( image, width, height, offset, flip )
#define TracyAppInfo( txt, size ) tracy::Profiler::MessageAppInfo( txt, size );
#define TracyLockable( type, varname ) tracy::Lockable<type> varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, #type " " #varname, __FILE__, __LINE__, 0 }; return &srcloc; }() }
#define TracyLockableN( type, varname, desc ) tracy::Lockable<type> varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, desc, __FILE__, __LINE__, 0 }; return &srcloc; }() }
#define TracySharedLockable( type, varname ) tracy::SharedLockable<type> varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, #type " " #varname, __FILE__, __LINE__, 0 }; return &srcloc; }() }
#define TracySharedLockableN( type, varname, desc ) tracy::SharedLockable<type> varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, desc, __FILE__, __LINE__, 0 }; return &srcloc; }() }
#define LockableBase( type ) tracy::Lockable<type>
#define SharedLockableBase( type ) tracy::SharedLockable<type>
#define LockMark( varname ) static constexpr tracy::SourceLocationData __tracy_lock_location_##varname { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; varname.Mark( &__tracy_lock_location_##varname )
#define LockableName( varname, txt, size ) varname.CustomName( txt, size )
#define TracyPlot( name, val ) tracy::Profiler::PlotData( name, val )
#define TracyPlotConfig( name, type, step, fill, color ) tracy::Profiler::ConfigurePlot( name, type, step, fill, color )
#define TracyAppInfo( txt, size ) tracy::Profiler::MessageAppInfo( txt, size )
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
# define TracyMessage( txt, size ) tracy::Profiler::Message( txt, size, TRACY_CALLSTACK );
# define TracyMessageL( txt ) tracy::Profiler::Message( txt, TRACY_CALLSTACK );
# define TracyMessageC( txt, size, color ) tracy::Profiler::MessageColor( txt, size, color, TRACY_CALLSTACK );
# define TracyMessageLC( txt, color ) tracy::Profiler::MessageColor( txt, color, TRACY_CALLSTACK );
# define TracyMessage( txt, size ) tracy::Profiler::Message( txt, size, TRACY_CALLSTACK )
# define TracyMessageL( txt ) tracy::Profiler::Message( txt, TRACY_CALLSTACK )
# define TracyMessageC( txt, size, color ) tracy::Profiler::MessageColor( txt, size, color, TRACY_CALLSTACK )
# define TracyMessageLC( txt, color ) tracy::Profiler::MessageColor( txt, color, TRACY_CALLSTACK )
# define TracyAlloc( ptr, size ) tracy::Profiler::MemAllocCallstack( ptr, size, TRACY_CALLSTACK, false );
# define TracyFree( ptr ) tracy::Profiler::MemFreeCallstack( ptr, TRACY_CALLSTACK, false );
# define TracySecureAlloc( ptr, size ) tracy::Profiler::MemAllocCallstack( ptr, size, TRACY_CALLSTACK, true );
# define TracySecureFree( ptr ) tracy::Profiler::MemFreeCallstack( ptr, TRACY_CALLSTACK, true );
# define TracyAlloc( ptr, size ) tracy::Profiler::MemAllocCallstack( ptr, size, TRACY_CALLSTACK, false )
# define TracyFree( ptr ) tracy::Profiler::MemFreeCallstack( ptr, TRACY_CALLSTACK, false )
# define TracySecureAlloc( ptr, size ) tracy::Profiler::MemAllocCallstack( ptr, size, TRACY_CALLSTACK, true )
# define TracySecureFree( ptr ) tracy::Profiler::MemFreeCallstack( ptr, TRACY_CALLSTACK, true )
# define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, false, name );
# define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, false, name );
# define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, true, name );
# define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, true, name );
# define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, false, name )
# define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, false, name )
# define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, true, name )
# define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, true, name )
#else
# define TracyMessage( txt, size ) tracy::Profiler::Message( txt, size, 0 );
# define TracyMessageL( txt ) tracy::Profiler::Message( txt, 0 );
# define TracyMessageC( txt, size, color ) tracy::Profiler::MessageColor( txt, size, color, 0 );
# define TracyMessageLC( txt, color ) tracy::Profiler::MessageColor( txt, color, 0 );
# define TracyMessage( txt, size ) tracy::Profiler::Message( txt, size, 0 )
# define TracyMessageL( txt ) tracy::Profiler::Message( txt, 0 )
# define TracyMessageC( txt, size, color ) tracy::Profiler::MessageColor( txt, size, color, 0 )
# define TracyMessageLC( txt, color ) tracy::Profiler::MessageColor( txt, color, 0 )
# define TracyAlloc( ptr, size ) tracy::Profiler::MemAlloc( ptr, size, false );
# define TracyFree( ptr ) tracy::Profiler::MemFree( ptr, false );
# define TracySecureAlloc( ptr, size ) tracy::Profiler::MemAlloc( ptr, size, true );
# define TracySecureFree( ptr ) tracy::Profiler::MemFree( ptr, true );
# define TracyAlloc( ptr, size ) tracy::Profiler::MemAlloc( ptr, size, false )
# define TracyFree( ptr ) tracy::Profiler::MemFree( ptr, false )
# define TracySecureAlloc( ptr, size ) tracy::Profiler::MemAlloc( ptr, size, true )
# define TracySecureFree( ptr ) tracy::Profiler::MemFree( ptr, true )
# define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, false, name );
# define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, false, name );
# define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, true, name );
# define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, true, name );
# define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, false, name )
# define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, false, name )
# define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, true, name )
# define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, true, name )
#endif
#ifdef TRACY_HAS_CALLSTACK
# define ZoneNamedS( varname, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active );
# define ZoneNamedNS( varname, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active );
# define ZoneNamedCS( varname, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active );
# define ZoneNamedNCS( varname, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active );
# define ZoneNamedS( varname, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active )
# define ZoneNamedNS( varname, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active )
# define ZoneNamedCS( varname, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active )
# define ZoneNamedNCS( varname, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active )
# define ZoneTransientS( varname, depth, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), nullptr, 0, depth, active );
# define ZoneTransientNS( varname, name, depth, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), name, strlen( name ), depth, active );
# define ZoneTransientS( varname, depth, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), nullptr, 0, depth, active )
# define ZoneTransientNS( varname, name, depth, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), name, strlen( name ), depth, active )
# define ZoneScopedS( depth ) ZoneNamedS( ___tracy_scoped_zone, depth, true )
# define ZoneScopedNS( name, depth ) ZoneNamedNS( ___tracy_scoped_zone, name, depth, true )
# define ZoneScopedCS( color, depth ) ZoneNamedCS( ___tracy_scoped_zone, color, depth, true )
# define ZoneScopedNCS( name, color, depth ) ZoneNamedNCS( ___tracy_scoped_zone, name, color, depth, true )
# define TracyAllocS( ptr, size, depth ) tracy::Profiler::MemAllocCallstack( ptr, size, depth, false );
# define TracyFreeS( ptr, depth ) tracy::Profiler::MemFreeCallstack( ptr, depth, false );
# define TracySecureAllocS( ptr, size, depth ) tracy::Profiler::MemAllocCallstack( ptr, size, depth, true );
# define TracySecureFreeS( ptr, depth ) tracy::Profiler::MemFreeCallstack( ptr, depth, true );
# define TracyAllocS( ptr, size, depth ) tracy::Profiler::MemAllocCallstack( ptr, size, depth, false )
# define TracyFreeS( ptr, depth ) tracy::Profiler::MemFreeCallstack( ptr, depth, false )
# define TracySecureAllocS( ptr, size, depth ) tracy::Profiler::MemAllocCallstack( ptr, size, depth, true )
# define TracySecureFreeS( ptr, depth ) tracy::Profiler::MemFreeCallstack( ptr, depth, true )
# define TracyAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, false, name );
# define TracyFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, false, name );
# define TracySecureAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, true, name );
# define TracySecureFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, true, name );
# define TracyAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, false, name )
# define TracyFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, false, name )
# define TracySecureAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, true, name )
# define TracySecureFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, true, name )
# define TracyMessageS( txt, size, depth ) tracy::Profiler::Message( txt, size, depth );
# define TracyMessageLS( txt, depth ) tracy::Profiler::Message( txt, depth );
# define TracyMessageCS( txt, size, color, depth ) tracy::Profiler::MessageColor( txt, size, color, depth );
# define TracyMessageLCS( txt, color, depth ) tracy::Profiler::MessageColor( txt, color, depth );
# define TracyMessageS( txt, size, depth ) tracy::Profiler::Message( txt, size, depth )
# define TracyMessageLS( txt, depth ) tracy::Profiler::Message( txt, depth )
# define TracyMessageCS( txt, size, color, depth ) tracy::Profiler::MessageColor( txt, size, color, depth )
# define TracyMessageLCS( txt, color, depth ) tracy::Profiler::MessageColor( txt, color, depth )
#else
# define ZoneNamedS( varname, depth, active ) ZoneNamed( varname, active )
# define ZoneNamedNS( varname, name, depth, active ) ZoneNamedN( varname, name, active )
@@ -232,10 +257,10 @@ public:
# define TracySecureAllocS( ptr, size, depth ) TracySecureAlloc( ptr, size )
# define TracySecureFreeS( ptr, depth ) TracySecureFree( ptr )
# define TracyAllocNS( ptr, size, depth, name ) TracyAlloc( ptr, size, name )
# define TracyFreeNS( ptr, depth, name ) TracyFree( ptr, name )
# define TracySecureAllocNS( ptr, size, depth, name ) TracySecureAlloc( ptr, size, name )
# define TracySecureFreeNS( ptr, depth, name ) TracySecureFree( ptr, name )
# define TracyAllocNS( ptr, size, depth, name ) TracyAllocN( ptr, size, name )
# define TracyFreeNS( ptr, depth, name ) TracyFreeN( ptr, name )
# define TracySecureAllocNS( ptr, size, depth, name ) TracySecureAllocN( ptr, size, name )
# define TracySecureFreeNS( ptr, depth, name ) TracySecureFreeN( ptr, name )
# define TracyMessageS( txt, size, depth ) TracyMessage( txt, size )
# define TracyMessageLS( txt, depth ) TracyMessageL( txt )
@@ -243,8 +268,15 @@ public:
# define TracyMessageLCS( txt, color, depth ) TracyMessageLC( txt, color )
#endif
#define TracyParameterRegister( cb ) tracy::Profiler::ParameterRegister( cb );
#define TracyParameterSetup( idx, name, isBool, val ) tracy::Profiler::ParameterSetup( idx, name, isBool, val );
#define TracySourceCallbackRegister( cb, data ) tracy::Profiler::SourceCallbackRegister( cb, data )
#define TracyParameterRegister( cb, data ) tracy::Profiler::ParameterRegister( cb, data )
#define TracyParameterSetup( idx, name, isBool, val ) tracy::Profiler::ParameterSetup( idx, name, isBool, val )
#define TracyIsConnected tracy::GetProfiler().IsConnected()
#ifdef TRACY_FIBERS
# define TracyFiberEnter( fiber ) tracy::Profiler::EnterFiber( fiber )
# define TracyFiberLeave tracy::Profiler::LeaveFiber()
#endif
#endif