Add Tracy profiler support
This commit is contained in:
25
Source/ThirdParty/tracy/common/TracyAlign.hpp
vendored
Normal file
25
Source/ThirdParty/tracy/common/TracyAlign.hpp
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef __TRACYALIGN_HPP__
|
||||
#define __TRACYALIGN_HPP__
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
tracy_force_inline T MemRead( const void* ptr )
|
||||
{
|
||||
T val;
|
||||
memcpy( &val, ptr, sizeof( T ) );
|
||||
return val;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
tracy_force_inline void MemWrite( void* ptr, T val )
|
||||
{
|
||||
memcpy( ptr, &val, sizeof( T ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
42
Source/ThirdParty/tracy/common/TracyAlloc.hpp
vendored
Normal file
42
Source/ThirdParty/tracy/common/TracyAlloc.hpp
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef __TRACYALLOC_HPP__
|
||||
#define __TRACYALLOC_HPP__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
# include "../client/tracy_rpmalloc.hpp"
|
||||
#endif
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
static inline void* tracy_malloc( size_t size )
|
||||
{
|
||||
#ifdef TRACY_ENABLE
|
||||
return rpmalloc( size );
|
||||
#else
|
||||
return malloc( size );
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void tracy_free( void* ptr )
|
||||
{
|
||||
#ifdef TRACY_ENABLE
|
||||
rpfree( ptr );
|
||||
#else
|
||||
free( ptr );
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void* tracy_realloc( void* ptr, size_t size )
|
||||
{
|
||||
#ifdef TRACY_ENABLE
|
||||
return rprealloc( ptr, size );
|
||||
#else
|
||||
return realloc( ptr, size );
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
24
Source/ThirdParty/tracy/common/TracyMutex.hpp
vendored
Normal file
24
Source/ThirdParty/tracy/common/TracyMutex.hpp
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef __TRACYMUTEX_HPP__
|
||||
#define __TRACYMUTEX_HPP__
|
||||
|
||||
#if defined _MSC_VER
|
||||
|
||||
# include <shared_mutex>
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
using TracyMutex = std::shared_mutex;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
using TracyMutex = std::mutex;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
128
Source/ThirdParty/tracy/common/TracyProtocol.hpp
vendored
Normal file
128
Source/ThirdParty/tracy/common/TracyProtocol.hpp
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
#ifndef __TRACYPROTOCOL_HPP__
|
||||
#define __TRACYPROTOCOL_HPP__
|
||||
|
||||
#include <limits>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
constexpr unsigned Lz4CompressBound( unsigned isize ) { return isize + ( isize / 255 ) + 16; }
|
||||
|
||||
enum : uint32_t { ProtocolVersion = 46 };
|
||||
enum : uint16_t { BroadcastVersion = 2 };
|
||||
|
||||
using lz4sz_t = uint32_t;
|
||||
|
||||
enum { TargetFrameSize = 256 * 1024 };
|
||||
enum { LZ4Size = Lz4CompressBound( TargetFrameSize ) };
|
||||
static_assert( LZ4Size <= std::numeric_limits<lz4sz_t>::max(), "LZ4Size greater than lz4sz_t" );
|
||||
static_assert( TargetFrameSize * 2 >= 64 * 1024, "Not enough space for LZ4 stream buffer" );
|
||||
|
||||
enum { HandshakeShibbolethSize = 8 };
|
||||
static const char HandshakeShibboleth[HandshakeShibbolethSize] = { 'T', 'r', 'a', 'c', 'y', 'P', 'r', 'f' };
|
||||
|
||||
enum HandshakeStatus : uint8_t
|
||||
{
|
||||
HandshakePending,
|
||||
HandshakeWelcome,
|
||||
HandshakeProtocolMismatch,
|
||||
HandshakeNotAvailable,
|
||||
HandshakeDropped
|
||||
};
|
||||
|
||||
enum { WelcomeMessageProgramNameSize = 64 };
|
||||
enum { WelcomeMessageHostInfoSize = 1024 };
|
||||
|
||||
#pragma pack( 1 )
|
||||
|
||||
// Must increase left query space after handling!
|
||||
enum ServerQuery : uint8_t
|
||||
{
|
||||
ServerQueryTerminate,
|
||||
ServerQueryString,
|
||||
ServerQueryThreadString,
|
||||
ServerQuerySourceLocation,
|
||||
ServerQueryPlotName,
|
||||
ServerQueryCallstackFrame,
|
||||
ServerQueryFrameName,
|
||||
ServerQueryDisconnect,
|
||||
ServerQueryExternalName,
|
||||
ServerQueryParameter,
|
||||
ServerQuerySymbol,
|
||||
ServerQuerySymbolCode,
|
||||
ServerQueryCodeLocation,
|
||||
ServerQuerySourceCode,
|
||||
ServerQueryDataTransfer,
|
||||
ServerQueryDataTransferPart
|
||||
};
|
||||
|
||||
struct ServerQueryPacket
|
||||
{
|
||||
ServerQuery type;
|
||||
uint64_t ptr;
|
||||
uint32_t extra;
|
||||
};
|
||||
|
||||
enum { ServerQueryPacketSize = sizeof( ServerQueryPacket ) };
|
||||
|
||||
|
||||
enum CpuArchitecture : uint8_t
|
||||
{
|
||||
CpuArchUnknown,
|
||||
CpuArchX86,
|
||||
CpuArchX64,
|
||||
CpuArchArm32,
|
||||
CpuArchArm64
|
||||
};
|
||||
|
||||
|
||||
struct WelcomeMessage
|
||||
{
|
||||
double timerMul;
|
||||
int64_t initBegin;
|
||||
int64_t initEnd;
|
||||
uint64_t delay;
|
||||
uint64_t resolution;
|
||||
uint64_t epoch;
|
||||
uint64_t exectime;
|
||||
uint64_t pid;
|
||||
int64_t samplingPeriod;
|
||||
uint8_t onDemand;
|
||||
uint8_t isApple;
|
||||
uint8_t cpuArch;
|
||||
uint8_t codeTransfer;
|
||||
char cpuManufacturer[12];
|
||||
uint32_t cpuId;
|
||||
char programName[WelcomeMessageProgramNameSize];
|
||||
char hostInfo[WelcomeMessageHostInfoSize];
|
||||
};
|
||||
|
||||
enum { WelcomeMessageSize = sizeof( WelcomeMessage ) };
|
||||
|
||||
|
||||
struct OnDemandPayloadMessage
|
||||
{
|
||||
uint64_t frames;
|
||||
uint64_t currentTime;
|
||||
};
|
||||
|
||||
enum { OnDemandPayloadMessageSize = sizeof( OnDemandPayloadMessage ) };
|
||||
|
||||
|
||||
struct BroadcastMessage
|
||||
{
|
||||
uint16_t broadcastVersion;
|
||||
uint16_t listenPort;
|
||||
uint32_t protocolVersion;
|
||||
int32_t activeTime; // in seconds
|
||||
char programName[WelcomeMessageProgramNameSize];
|
||||
};
|
||||
|
||||
enum { BroadcastMessageSize = sizeof( BroadcastMessage ) };
|
||||
|
||||
#pragma pack()
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
678
Source/ThirdParty/tracy/common/TracyQueue.hpp
vendored
Normal file
678
Source/ThirdParty/tracy/common/TracyQueue.hpp
vendored
Normal file
@@ -0,0 +1,678 @@
|
||||
#ifndef __TRACYQUEUE_HPP__
|
||||
#define __TRACYQUEUE_HPP__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
enum class QueueType : uint8_t
|
||||
{
|
||||
ZoneText,
|
||||
ZoneName,
|
||||
Message,
|
||||
MessageColor,
|
||||
MessageCallstack,
|
||||
MessageColorCallstack,
|
||||
MessageAppInfo,
|
||||
ZoneBeginAllocSrcLoc,
|
||||
ZoneBeginAllocSrcLocCallstack,
|
||||
CallstackSerial,
|
||||
Callstack,
|
||||
CallstackAlloc,
|
||||
CallstackSample,
|
||||
FrameImage,
|
||||
ZoneBegin,
|
||||
ZoneBeginCallstack,
|
||||
ZoneEnd,
|
||||
LockWait,
|
||||
LockObtain,
|
||||
LockRelease,
|
||||
LockSharedWait,
|
||||
LockSharedObtain,
|
||||
LockSharedRelease,
|
||||
LockName,
|
||||
MemAlloc,
|
||||
MemAllocNamed,
|
||||
MemFree,
|
||||
MemFreeNamed,
|
||||
MemAllocCallstack,
|
||||
MemAllocCallstackNamed,
|
||||
MemFreeCallstack,
|
||||
MemFreeCallstackNamed,
|
||||
GpuZoneBegin,
|
||||
GpuZoneBeginCallstack,
|
||||
GpuZoneBeginAllocSrcLoc,
|
||||
GpuZoneBeginAllocSrcLocCallstack,
|
||||
GpuZoneEnd,
|
||||
GpuZoneBeginSerial,
|
||||
GpuZoneBeginCallstackSerial,
|
||||
GpuZoneBeginAllocSrcLocSerial,
|
||||
GpuZoneBeginAllocSrcLocCallstackSerial,
|
||||
GpuZoneEndSerial,
|
||||
PlotData,
|
||||
ContextSwitch,
|
||||
ThreadWakeup,
|
||||
GpuTime,
|
||||
GpuContextName,
|
||||
Terminate,
|
||||
KeepAlive,
|
||||
ThreadContext,
|
||||
GpuCalibration,
|
||||
Crash,
|
||||
CrashReport,
|
||||
ZoneValidation,
|
||||
ZoneColor,
|
||||
ZoneValue,
|
||||
FrameMarkMsg,
|
||||
FrameMarkMsgStart,
|
||||
FrameMarkMsgEnd,
|
||||
SourceLocation,
|
||||
LockAnnounce,
|
||||
LockTerminate,
|
||||
LockMark,
|
||||
MessageLiteral,
|
||||
MessageLiteralColor,
|
||||
MessageLiteralCallstack,
|
||||
MessageLiteralColorCallstack,
|
||||
GpuNewContext,
|
||||
CallstackFrameSize,
|
||||
CallstackFrame,
|
||||
SymbolInformation,
|
||||
CodeInformation,
|
||||
SysTimeReport,
|
||||
TidToPid,
|
||||
PlotConfig,
|
||||
ParamSetup,
|
||||
AckServerQueryNoop,
|
||||
AckSourceCodeNotAvailable,
|
||||
CpuTopology,
|
||||
SingleStringData,
|
||||
SecondStringData,
|
||||
MemNamePayload,
|
||||
StringData,
|
||||
ThreadName,
|
||||
PlotName,
|
||||
SourceLocationPayload,
|
||||
CallstackPayload,
|
||||
CallstackAllocPayload,
|
||||
FrameName,
|
||||
FrameImageData,
|
||||
ExternalName,
|
||||
ExternalThreadName,
|
||||
SymbolCode,
|
||||
SourceCode,
|
||||
NUM_TYPES
|
||||
};
|
||||
|
||||
#pragma pack( 1 )
|
||||
|
||||
struct QueueThreadContext
|
||||
{
|
||||
uint64_t thread;
|
||||
};
|
||||
|
||||
struct QueueZoneBeginLean
|
||||
{
|
||||
int64_t time;
|
||||
};
|
||||
|
||||
struct QueueZoneBegin : public QueueZoneBeginLean
|
||||
{
|
||||
uint64_t srcloc; // ptr
|
||||
};
|
||||
|
||||
struct QueueZoneEnd
|
||||
{
|
||||
int64_t time;
|
||||
};
|
||||
|
||||
struct QueueZoneValidation
|
||||
{
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
struct QueueZoneColor
|
||||
{
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
struct QueueZoneValue
|
||||
{
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
struct QueueStringTransfer
|
||||
{
|
||||
uint64_t ptr;
|
||||
};
|
||||
|
||||
struct QueueFrameMark
|
||||
{
|
||||
int64_t time;
|
||||
uint64_t name; // ptr
|
||||
};
|
||||
|
||||
struct QueueFrameImage
|
||||
{
|
||||
uint32_t frame;
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
uint8_t flip;
|
||||
};
|
||||
|
||||
struct QueueFrameImageFat : public QueueFrameImage
|
||||
{
|
||||
uint64_t image; // ptr
|
||||
};
|
||||
|
||||
struct QueueSourceLocation
|
||||
{
|
||||
uint64_t name;
|
||||
uint64_t function; // ptr
|
||||
uint64_t file; // ptr
|
||||
uint32_t line;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
struct QueueZoneTextFat
|
||||
{
|
||||
uint64_t text; // ptr
|
||||
uint16_t size;
|
||||
};
|
||||
|
||||
enum class LockType : uint8_t
|
||||
{
|
||||
Lockable,
|
||||
SharedLockable
|
||||
};
|
||||
|
||||
struct QueueLockAnnounce
|
||||
{
|
||||
uint32_t id;
|
||||
int64_t time;
|
||||
uint64_t lckloc; // ptr
|
||||
LockType type;
|
||||
};
|
||||
|
||||
struct QueueLockTerminate
|
||||
{
|
||||
uint32_t id;
|
||||
int64_t time;
|
||||
};
|
||||
|
||||
struct QueueLockWait
|
||||
{
|
||||
uint64_t thread;
|
||||
uint32_t id;
|
||||
int64_t time;
|
||||
};
|
||||
|
||||
struct QueueLockObtain
|
||||
{
|
||||
uint64_t thread;
|
||||
uint32_t id;
|
||||
int64_t time;
|
||||
};
|
||||
|
||||
struct QueueLockRelease
|
||||
{
|
||||
uint64_t thread;
|
||||
uint32_t id;
|
||||
int64_t time;
|
||||
};
|
||||
|
||||
struct QueueLockMark
|
||||
{
|
||||
uint64_t thread;
|
||||
uint32_t id;
|
||||
uint64_t srcloc; // ptr
|
||||
};
|
||||
|
||||
struct QueueLockName
|
||||
{
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
struct QueueLockNameFat : public QueueLockName
|
||||
{
|
||||
uint64_t name; // ptr
|
||||
uint16_t size;
|
||||
};
|
||||
|
||||
enum class PlotDataType : uint8_t
|
||||
{
|
||||
Float,
|
||||
Double,
|
||||
Int
|
||||
};
|
||||
|
||||
struct QueuePlotData
|
||||
{
|
||||
uint64_t name; // ptr
|
||||
int64_t time;
|
||||
PlotDataType type;
|
||||
union
|
||||
{
|
||||
double d;
|
||||
float f;
|
||||
int64_t i;
|
||||
} data;
|
||||
};
|
||||
|
||||
struct QueueMessage
|
||||
{
|
||||
int64_t time;
|
||||
};
|
||||
|
||||
struct QueueMessageColor : public QueueMessage
|
||||
{
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
struct QueueMessageLiteral : public QueueMessage
|
||||
{
|
||||
uint64_t text; // ptr
|
||||
};
|
||||
|
||||
struct QueueMessageColorLiteral : public QueueMessageColor
|
||||
{
|
||||
uint64_t text; // ptr
|
||||
};
|
||||
|
||||
struct QueueMessageFat : public QueueMessage
|
||||
{
|
||||
uint64_t text; // ptr
|
||||
uint16_t size;
|
||||
};
|
||||
|
||||
struct QueueMessageColorFat : public QueueMessageColor
|
||||
{
|
||||
uint64_t text; // ptr
|
||||
uint16_t size;
|
||||
};
|
||||
|
||||
// Don't change order, only add new entries at the end, this is also used on trace dumps!
|
||||
enum class GpuContextType : uint8_t
|
||||
{
|
||||
Invalid,
|
||||
OpenGl,
|
||||
Vulkan,
|
||||
OpenCL,
|
||||
Direct3D12
|
||||
};
|
||||
|
||||
enum GpuContextFlags : uint8_t
|
||||
{
|
||||
GpuContextCalibration = 1 << 0
|
||||
};
|
||||
|
||||
struct QueueGpuNewContext
|
||||
{
|
||||
int64_t cpuTime;
|
||||
int64_t gpuTime;
|
||||
uint64_t thread;
|
||||
float period;
|
||||
uint8_t context;
|
||||
GpuContextFlags flags;
|
||||
GpuContextType type;
|
||||
};
|
||||
|
||||
struct QueueGpuZoneBeginLean
|
||||
{
|
||||
int64_t cpuTime;
|
||||
uint64_t thread;
|
||||
uint16_t queryId;
|
||||
uint8_t context;
|
||||
};
|
||||
|
||||
struct QueueGpuZoneBegin : public QueueGpuZoneBeginLean
|
||||
{
|
||||
uint64_t srcloc;
|
||||
};
|
||||
|
||||
struct QueueGpuZoneEnd
|
||||
{
|
||||
int64_t cpuTime;
|
||||
uint64_t thread;
|
||||
uint16_t queryId;
|
||||
uint8_t context;
|
||||
};
|
||||
|
||||
struct QueueGpuTime
|
||||
{
|
||||
int64_t gpuTime;
|
||||
uint16_t queryId;
|
||||
uint8_t context;
|
||||
};
|
||||
|
||||
struct QueueGpuCalibration
|
||||
{
|
||||
int64_t gpuTime;
|
||||
int64_t cpuTime;
|
||||
int64_t cpuDelta;
|
||||
uint8_t context;
|
||||
};
|
||||
|
||||
struct QueueGpuContextName
|
||||
{
|
||||
uint8_t context;
|
||||
};
|
||||
|
||||
struct QueueGpuContextNameFat : public QueueGpuContextName
|
||||
{
|
||||
uint64_t ptr;
|
||||
uint16_t size;
|
||||
};
|
||||
|
||||
struct QueueMemNamePayload
|
||||
{
|
||||
uint64_t name;
|
||||
};
|
||||
|
||||
struct QueueMemAlloc
|
||||
{
|
||||
int64_t time;
|
||||
uint64_t thread;
|
||||
uint64_t ptr;
|
||||
char size[6];
|
||||
};
|
||||
|
||||
struct QueueMemFree
|
||||
{
|
||||
int64_t time;
|
||||
uint64_t thread;
|
||||
uint64_t ptr;
|
||||
};
|
||||
|
||||
struct QueueCallstackFat
|
||||
{
|
||||
uint64_t ptr;
|
||||
};
|
||||
|
||||
struct QueueCallstackAllocFat
|
||||
{
|
||||
uint64_t ptr;
|
||||
uint64_t nativePtr;
|
||||
};
|
||||
|
||||
struct QueueCallstackSample
|
||||
{
|
||||
int64_t time;
|
||||
uint64_t thread;
|
||||
};
|
||||
|
||||
struct QueueCallstackSampleFat : public QueueCallstackSample
|
||||
{
|
||||
uint64_t ptr;
|
||||
};
|
||||
|
||||
struct QueueCallstackFrameSize
|
||||
{
|
||||
uint64_t ptr;
|
||||
uint8_t size;
|
||||
};
|
||||
|
||||
struct QueueCallstackFrame
|
||||
{
|
||||
uint32_t line;
|
||||
uint64_t symAddr;
|
||||
uint32_t symLen;
|
||||
};
|
||||
|
||||
struct QueueSymbolInformation
|
||||
{
|
||||
uint32_t line;
|
||||
uint64_t symAddr;
|
||||
};
|
||||
|
||||
struct QueueCodeInformation
|
||||
{
|
||||
uint64_t ptr;
|
||||
uint32_t line;
|
||||
};
|
||||
|
||||
struct QueueCrashReport
|
||||
{
|
||||
int64_t time;
|
||||
uint64_t text; // ptr
|
||||
};
|
||||
|
||||
struct QueueSysTime
|
||||
{
|
||||
int64_t time;
|
||||
float sysTime;
|
||||
};
|
||||
|
||||
struct QueueContextSwitch
|
||||
{
|
||||
int64_t time;
|
||||
uint64_t oldThread;
|
||||
uint64_t newThread;
|
||||
uint8_t cpu;
|
||||
uint8_t reason;
|
||||
uint8_t state;
|
||||
};
|
||||
|
||||
struct QueueThreadWakeup
|
||||
{
|
||||
int64_t time;
|
||||
uint64_t thread;
|
||||
};
|
||||
|
||||
struct QueueTidToPid
|
||||
{
|
||||
uint64_t tid;
|
||||
uint64_t pid;
|
||||
};
|
||||
|
||||
struct QueuePlotConfig
|
||||
{
|
||||
uint64_t name; // ptr
|
||||
uint8_t type;
|
||||
};
|
||||
|
||||
struct QueueParamSetup
|
||||
{
|
||||
uint32_t idx;
|
||||
uint64_t name; // ptr
|
||||
uint8_t isBool;
|
||||
int32_t val;
|
||||
};
|
||||
|
||||
struct QueueCpuTopology
|
||||
{
|
||||
uint32_t package;
|
||||
uint32_t core;
|
||||
uint32_t thread;
|
||||
};
|
||||
|
||||
struct QueueHeader
|
||||
{
|
||||
union
|
||||
{
|
||||
QueueType type;
|
||||
uint8_t idx;
|
||||
};
|
||||
};
|
||||
|
||||
struct QueueItem
|
||||
{
|
||||
QueueHeader hdr;
|
||||
union
|
||||
{
|
||||
QueueThreadContext threadCtx;
|
||||
QueueZoneBegin zoneBegin;
|
||||
QueueZoneBeginLean zoneBeginLean;
|
||||
QueueZoneEnd zoneEnd;
|
||||
QueueZoneValidation zoneValidation;
|
||||
QueueZoneColor zoneColor;
|
||||
QueueZoneValue zoneValue;
|
||||
QueueStringTransfer stringTransfer;
|
||||
QueueFrameMark frameMark;
|
||||
QueueFrameImage frameImage;
|
||||
QueueFrameImageFat frameImageFat;
|
||||
QueueSourceLocation srcloc;
|
||||
QueueZoneTextFat zoneTextFat;
|
||||
QueueLockAnnounce lockAnnounce;
|
||||
QueueLockTerminate lockTerminate;
|
||||
QueueLockWait lockWait;
|
||||
QueueLockObtain lockObtain;
|
||||
QueueLockRelease lockRelease;
|
||||
QueueLockMark lockMark;
|
||||
QueueLockName lockName;
|
||||
QueueLockNameFat lockNameFat;
|
||||
QueuePlotData plotData;
|
||||
QueueMessage message;
|
||||
QueueMessageColor messageColor;
|
||||
QueueMessageLiteral messageLiteral;
|
||||
QueueMessageColorLiteral messageColorLiteral;
|
||||
QueueMessageFat messageFat;
|
||||
QueueMessageColorFat messageColorFat;
|
||||
QueueGpuNewContext gpuNewContext;
|
||||
QueueGpuZoneBegin gpuZoneBegin;
|
||||
QueueGpuZoneBeginLean gpuZoneBeginLean;
|
||||
QueueGpuZoneEnd gpuZoneEnd;
|
||||
QueueGpuTime gpuTime;
|
||||
QueueGpuCalibration gpuCalibration;
|
||||
QueueGpuContextName gpuContextName;
|
||||
QueueGpuContextNameFat gpuContextNameFat;
|
||||
QueueMemAlloc memAlloc;
|
||||
QueueMemFree memFree;
|
||||
QueueMemNamePayload memName;
|
||||
QueueCallstackFat callstackFat;
|
||||
QueueCallstackAllocFat callstackAllocFat;
|
||||
QueueCallstackSample callstackSample;
|
||||
QueueCallstackSampleFat callstackSampleFat;
|
||||
QueueCallstackFrameSize callstackFrameSize;
|
||||
QueueCallstackFrame callstackFrame;
|
||||
QueueSymbolInformation symbolInformation;
|
||||
QueueCodeInformation codeInformation;
|
||||
QueueCrashReport crashReport;
|
||||
QueueSysTime sysTime;
|
||||
QueueContextSwitch contextSwitch;
|
||||
QueueThreadWakeup threadWakeup;
|
||||
QueueTidToPid tidToPid;
|
||||
QueuePlotConfig plotConfig;
|
||||
QueueParamSetup paramSetup;
|
||||
QueueCpuTopology cpuTopology;
|
||||
};
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
|
||||
enum { QueueItemSize = sizeof( QueueItem ) };
|
||||
|
||||
static constexpr size_t QueueDataSize[] = {
|
||||
sizeof( QueueHeader ), // zone text
|
||||
sizeof( QueueHeader ), // zone name
|
||||
sizeof( QueueHeader ) + sizeof( QueueMessage ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueMessageColor ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueMessage ), // callstack
|
||||
sizeof( QueueHeader ) + sizeof( QueueMessageColor ), // callstack
|
||||
sizeof( QueueHeader ) + sizeof( QueueMessage ), // app info
|
||||
sizeof( QueueHeader ) + sizeof( QueueZoneBeginLean ), // allocated source location
|
||||
sizeof( QueueHeader ) + sizeof( QueueZoneBeginLean ), // allocated source location, callstack
|
||||
sizeof( QueueHeader ), // callstack memory
|
||||
sizeof( QueueHeader ), // callstack
|
||||
sizeof( QueueHeader ), // callstack alloc
|
||||
sizeof( QueueHeader ) + sizeof( QueueCallstackSample ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueFrameImage ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueZoneBegin ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueZoneBegin ), // callstack
|
||||
sizeof( QueueHeader ) + sizeof( QueueZoneEnd ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueLockWait ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueLockObtain ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueLockRelease ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueLockWait ), // shared
|
||||
sizeof( QueueHeader ) + sizeof( QueueLockObtain ), // shared
|
||||
sizeof( QueueHeader ) + sizeof( QueueLockRelease ), // shared
|
||||
sizeof( QueueHeader ) + sizeof( QueueLockName ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // named
|
||||
sizeof( QueueHeader ) + sizeof( QueueMemFree ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueMemFree ), // named
|
||||
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // callstack
|
||||
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // callstack, named
|
||||
sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack
|
||||
sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack, named
|
||||
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // callstack
|
||||
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// allocated source location
|
||||
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// allocated source location, callstack
|
||||
sizeof( QueueHeader ) + sizeof( QueueGpuZoneEnd ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // serial
|
||||
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // serial, callstack
|
||||
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( QueueContextSwitch ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueThreadWakeup ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueGpuTime ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueGpuContextName ),
|
||||
// above items must be first
|
||||
sizeof( QueueHeader ), // terminate
|
||||
sizeof( QueueHeader ), // keep alive
|
||||
sizeof( QueueHeader ) + sizeof( QueueThreadContext ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueGpuCalibration ),
|
||||
sizeof( QueueHeader ), // crash
|
||||
sizeof( QueueHeader ) + sizeof( QueueCrashReport ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueZoneValidation ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueZoneColor ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueZoneValue ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // continuous frames
|
||||
sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // start
|
||||
sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // end
|
||||
sizeof( QueueHeader ) + sizeof( QueueSourceLocation ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueLockAnnounce ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueLockTerminate ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueLockMark ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueMessageLiteral ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueMessageColorLiteral ),
|
||||
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( QueuePlotConfig ),
|
||||
sizeof( QueueHeader ) + sizeof( QueueParamSetup ),
|
||||
sizeof( QueueHeader ), // server query acknowledgement
|
||||
sizeof( QueueHeader ), // source code not available
|
||||
sizeof( QueueHeader ) + sizeof( QueueCpuTopology ),
|
||||
sizeof( QueueHeader ), // single string data
|
||||
sizeof( QueueHeader ), // second string data
|
||||
sizeof( QueueHeader ) + sizeof( QueueMemNamePayload ),
|
||||
// keep all QueueStringTransfer below
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // string data
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // thread name
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // plot name
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // allocated source location payload
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack payload
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack alloc payload
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame name
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame image data
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // external name
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // external thread name
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // symbol code
|
||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // source code
|
||||
};
|
||||
|
||||
static_assert( QueueItemSize == 32, "Queue item size not 32 bytes" );
|
||||
static_assert( sizeof( QueueDataSize ) / sizeof( size_t ) == (uint8_t)QueueType::NUM_TYPES, "QueueDataSize mismatch" );
|
||||
static_assert( sizeof( void* ) <= sizeof( uint64_t ), "Pointer size > 8 bytes" );
|
||||
static_assert( sizeof( void* ) == sizeof( uintptr_t ), "Pointer size != uintptr_t" );
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
748
Source/ThirdParty/tracy/common/TracySocket.cpp
vendored
Normal file
748
Source/ThirdParty/tracy/common/TracySocket.cpp
vendored
Normal file
@@ -0,0 +1,748 @@
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "TracyAlloc.hpp"
|
||||
#include "TracySocket.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(disable:4244)
|
||||
# pragma warning(disable:4267)
|
||||
# endif
|
||||
# define poll WSAPoll
|
||||
#else
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/param.h>
|
||||
# include <errno.h>
|
||||
# include <fcntl.h>
|
||||
# include <netinet/in.h>
|
||||
# include <netdb.h>
|
||||
# include <unistd.h>
|
||||
# include <poll.h>
|
||||
#endif
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
# define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef SOCKET socket_t;
|
||||
#else
|
||||
typedef int socket_t;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
struct __wsinit
|
||||
{
|
||||
__wsinit()
|
||||
{
|
||||
WSADATA wsaData;
|
||||
if( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != 0 )
|
||||
{
|
||||
fprintf( stderr, "Cannot init winsock.\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void InitWinSock()
|
||||
{
|
||||
static __wsinit init;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
enum { BufSize = 128 * 1024 };
|
||||
|
||||
Socket::Socket()
|
||||
: m_buf( (char*)tracy_malloc( BufSize ) )
|
||||
, m_bufPtr( nullptr )
|
||||
, m_sock( -1 )
|
||||
, m_bufLeft( 0 )
|
||||
, m_ptr( nullptr )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
InitWinSock();
|
||||
#endif
|
||||
}
|
||||
|
||||
Socket::Socket( int sock )
|
||||
: m_buf( (char*)tracy_malloc( BufSize ) )
|
||||
, m_bufPtr( nullptr )
|
||||
, m_sock( sock )
|
||||
, m_bufLeft( 0 )
|
||||
, m_ptr( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
Socket::~Socket()
|
||||
{
|
||||
tracy_free( m_buf );
|
||||
if( m_sock.load( std::memory_order_relaxed ) != -1 )
|
||||
{
|
||||
Close();
|
||||
}
|
||||
if( m_ptr )
|
||||
{
|
||||
freeaddrinfo( m_res );
|
||||
#ifdef _WIN32
|
||||
closesocket( m_connSock );
|
||||
#else
|
||||
close( m_connSock );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool Socket::Connect( const char* addr, uint16_t port )
|
||||
{
|
||||
assert( !IsValid() );
|
||||
|
||||
if( m_ptr )
|
||||
{
|
||||
const auto c = connect( m_connSock, m_ptr->ai_addr, m_ptr->ai_addrlen );
|
||||
if( c == -1 )
|
||||
{
|
||||
#if defined _WIN32
|
||||
const auto err = WSAGetLastError();
|
||||
if( err == WSAEALREADY || err == WSAEINPROGRESS ) return false;
|
||||
if( err != WSAEISCONN )
|
||||
{
|
||||
freeaddrinfo( m_res );
|
||||
closesocket( m_connSock );
|
||||
m_ptr = nullptr;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
const auto err = errno;
|
||||
if( err == EALREADY || err == EINPROGRESS ) return false;
|
||||
if( err != EISCONN )
|
||||
{
|
||||
freeaddrinfo( m_res );
|
||||
close( m_connSock );
|
||||
m_ptr = nullptr;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined _WIN32
|
||||
u_long nonblocking = 0;
|
||||
ioctlsocket( m_connSock, FIONBIO, &nonblocking );
|
||||
#else
|
||||
int flags = fcntl( m_connSock, F_GETFL, 0 );
|
||||
fcntl( m_connSock, F_SETFL, flags & ~O_NONBLOCK );
|
||||
#endif
|
||||
m_sock.store( m_connSock, std::memory_order_relaxed );
|
||||
freeaddrinfo( m_res );
|
||||
m_ptr = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res, *ptr;
|
||||
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
char portbuf[32];
|
||||
sprintf( portbuf, "%" PRIu16, port );
|
||||
|
||||
if( getaddrinfo( addr, portbuf, &hints, &res ) != 0 ) return false;
|
||||
int sock = 0;
|
||||
for( ptr = res; ptr; ptr = ptr->ai_next )
|
||||
{
|
||||
if( ( sock = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol ) ) == -1 ) continue;
|
||||
#if defined __APPLE__
|
||||
int val = 1;
|
||||
setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) );
|
||||
#endif
|
||||
#if defined _WIN32
|
||||
u_long nonblocking = 1;
|
||||
ioctlsocket( sock, FIONBIO, &nonblocking );
|
||||
#else
|
||||
int flags = fcntl( sock, F_GETFL, 0 );
|
||||
fcntl( sock, F_SETFL, flags | O_NONBLOCK );
|
||||
#endif
|
||||
if( connect( sock, ptr->ai_addr, ptr->ai_addrlen ) == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined _WIN32
|
||||
const auto err = WSAGetLastError();
|
||||
if( err != WSAEWOULDBLOCK )
|
||||
{
|
||||
closesocket( sock );
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
if( errno != EINPROGRESS )
|
||||
{
|
||||
close( sock );
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
m_res = res;
|
||||
m_ptr = ptr;
|
||||
m_connSock = sock;
|
||||
return false;
|
||||
}
|
||||
freeaddrinfo( res );
|
||||
if( !ptr ) return false;
|
||||
|
||||
#if defined _WIN32
|
||||
u_long nonblocking = 0;
|
||||
ioctlsocket( sock, FIONBIO, &nonblocking );
|
||||
#else
|
||||
int flags = fcntl( sock, F_GETFL, 0 );
|
||||
fcntl( sock, F_SETFL, flags & ~O_NONBLOCK );
|
||||
#endif
|
||||
|
||||
m_sock.store( sock, std::memory_order_relaxed );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Socket::ConnectBlocking( const char* addr, uint16_t port )
|
||||
{
|
||||
assert( !IsValid() );
|
||||
assert( !m_ptr );
|
||||
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res, *ptr;
|
||||
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
char portbuf[32];
|
||||
sprintf( portbuf, "%" PRIu16, port );
|
||||
|
||||
if( getaddrinfo( addr, portbuf, &hints, &res ) != 0 ) return false;
|
||||
int sock = 0;
|
||||
for( ptr = res; ptr; ptr = ptr->ai_next )
|
||||
{
|
||||
if( ( sock = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol ) ) == -1 ) continue;
|
||||
#if defined __APPLE__
|
||||
int val = 1;
|
||||
setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) );
|
||||
#endif
|
||||
if( connect( sock, ptr->ai_addr, ptr->ai_addrlen ) == -1 )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
closesocket( sock );
|
||||
#else
|
||||
close( sock );
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
freeaddrinfo( res );
|
||||
if( !ptr ) return false;
|
||||
|
||||
m_sock.store( sock, std::memory_order_relaxed );
|
||||
return true;
|
||||
}
|
||||
|
||||
void Socket::Close()
|
||||
{
|
||||
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||
assert( sock != -1 );
|
||||
#ifdef _WIN32
|
||||
closesocket( sock );
|
||||
#else
|
||||
close( sock );
|
||||
#endif
|
||||
m_sock.store( -1, std::memory_order_relaxed );
|
||||
}
|
||||
|
||||
int Socket::Send( const void* _buf, int len )
|
||||
{
|
||||
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||
auto buf = (const char*)_buf;
|
||||
assert( sock != -1 );
|
||||
auto start = buf;
|
||||
while( len > 0 )
|
||||
{
|
||||
auto ret = send( sock, buf, len, MSG_NOSIGNAL );
|
||||
if( ret == -1 ) return -1;
|
||||
len -= ret;
|
||||
buf += ret;
|
||||
}
|
||||
return int( buf - start );
|
||||
}
|
||||
|
||||
int Socket::GetSendBufSize()
|
||||
{
|
||||
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||
int bufSize;
|
||||
#if defined _WIN32
|
||||
int sz = sizeof( bufSize );
|
||||
getsockopt( sock, SOL_SOCKET, SO_SNDBUF, (char*)&bufSize, &sz );
|
||||
#else
|
||||
socklen_t sz = sizeof( bufSize );
|
||||
getsockopt( sock, SOL_SOCKET, SO_SNDBUF, &bufSize, &sz );
|
||||
#endif
|
||||
return bufSize;
|
||||
}
|
||||
|
||||
int Socket::RecvBuffered( void* buf, int len, int timeout )
|
||||
{
|
||||
if( len <= m_bufLeft )
|
||||
{
|
||||
memcpy( buf, m_bufPtr, len );
|
||||
m_bufPtr += len;
|
||||
m_bufLeft -= len;
|
||||
return len;
|
||||
}
|
||||
|
||||
if( m_bufLeft > 0 )
|
||||
{
|
||||
memcpy( buf, m_bufPtr, m_bufLeft );
|
||||
const auto ret = m_bufLeft;
|
||||
m_bufLeft = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if( len >= BufSize ) return Recv( buf, len, timeout );
|
||||
|
||||
m_bufLeft = Recv( m_buf, BufSize, timeout );
|
||||
if( m_bufLeft <= 0 ) return m_bufLeft;
|
||||
|
||||
const auto sz = len < m_bufLeft ? len : m_bufLeft;
|
||||
memcpy( buf, m_buf, sz );
|
||||
m_bufPtr = m_buf + sz;
|
||||
m_bufLeft -= sz;
|
||||
return sz;
|
||||
}
|
||||
|
||||
int Socket::Recv( void* _buf, int len, int timeout )
|
||||
{
|
||||
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||
auto buf = (char*)_buf;
|
||||
|
||||
struct pollfd fd;
|
||||
fd.fd = (socket_t)sock;
|
||||
fd.events = POLLIN;
|
||||
|
||||
if( poll( &fd, 1, timeout ) > 0 )
|
||||
{
|
||||
return recv( sock, buf, len, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int Socket::ReadUpTo( void* _buf, int len, int timeout )
|
||||
{
|
||||
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||
auto buf = (char*)_buf;
|
||||
|
||||
int rd = 0;
|
||||
while( len > 0 )
|
||||
{
|
||||
const auto res = recv( sock, buf, len, 0 );
|
||||
if( res == 0 ) break;
|
||||
if( res == -1 ) return -1;
|
||||
len -= res;
|
||||
rd += res;
|
||||
buf += res;
|
||||
}
|
||||
return rd;
|
||||
}
|
||||
|
||||
bool Socket::Read( void* buf, int len, int timeout )
|
||||
{
|
||||
auto cbuf = (char*)buf;
|
||||
while( len > 0 )
|
||||
{
|
||||
if( !ReadImpl( cbuf, len, timeout ) ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Socket::ReadImpl( char*& buf, int& len, int timeout )
|
||||
{
|
||||
const auto sz = RecvBuffered( buf, len, timeout );
|
||||
switch( sz )
|
||||
{
|
||||
case 0:
|
||||
return false;
|
||||
case -1:
|
||||
#ifdef _WIN32
|
||||
{
|
||||
auto err = WSAGetLastError();
|
||||
if( err == WSAECONNABORTED || err == WSAECONNRESET ) return false;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
len -= sz;
|
||||
buf += sz;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Socket::ReadRaw( void* _buf, int len, int timeout )
|
||||
{
|
||||
auto buf = (char*)_buf;
|
||||
while( len > 0 )
|
||||
{
|
||||
const auto sz = Recv( buf, len, timeout );
|
||||
if( sz <= 0 ) return false;
|
||||
len -= sz;
|
||||
buf += sz;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Socket::HasData()
|
||||
{
|
||||
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||
if( m_bufLeft > 0 ) return true;
|
||||
|
||||
struct pollfd fd;
|
||||
fd.fd = (socket_t)sock;
|
||||
fd.events = POLLIN;
|
||||
|
||||
return poll( &fd, 1, 0 ) > 0;
|
||||
}
|
||||
|
||||
bool Socket::IsValid() const
|
||||
{
|
||||
return m_sock.load( std::memory_order_relaxed ) >= 0;
|
||||
}
|
||||
|
||||
|
||||
ListenSocket::ListenSocket()
|
||||
: m_sock( -1 )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
InitWinSock();
|
||||
#endif
|
||||
}
|
||||
|
||||
ListenSocket::~ListenSocket()
|
||||
{
|
||||
if( m_sock != -1 ) Close();
|
||||
}
|
||||
|
||||
static int addrinfo_and_socket_for_family( uint16_t port, int ai_family, struct addrinfo** res )
|
||||
{
|
||||
struct addrinfo hints;
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
hints.ai_family = ai_family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
#ifndef TRACY_ONLY_LOCALHOST
|
||||
const char* onlyLocalhost = getenv( "TRACY_ONLY_LOCALHOST" );
|
||||
if( !onlyLocalhost || onlyLocalhost[0] != '1' )
|
||||
{
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
}
|
||||
#endif
|
||||
char portbuf[32];
|
||||
sprintf( portbuf, "%" PRIu16, port );
|
||||
if( getaddrinfo( nullptr, portbuf, &hints, res ) != 0 ) return -1;
|
||||
int sock = socket( (*res)->ai_family, (*res)->ai_socktype, (*res)->ai_protocol );
|
||||
if (sock == -1) freeaddrinfo( *res );
|
||||
return sock;
|
||||
}
|
||||
|
||||
bool ListenSocket::Listen( uint16_t port, int backlog )
|
||||
{
|
||||
assert( m_sock == -1 );
|
||||
|
||||
struct addrinfo* res = nullptr;
|
||||
|
||||
#if !defined TRACY_ONLY_IPV4 && !defined TRACY_ONLY_LOCALHOST
|
||||
const char* onlyIPv4 = getenv( "TRACY_ONLY_IPV4" );
|
||||
if( !onlyIPv4 || onlyIPv4[0] != '1' )
|
||||
{
|
||||
m_sock = addrinfo_and_socket_for_family( port, AF_INET6, &res );
|
||||
}
|
||||
#endif
|
||||
if (m_sock == -1)
|
||||
{
|
||||
// IPV6 protocol may not be available/is disabled. Try to create a socket
|
||||
// with the IPV4 protocol
|
||||
m_sock = addrinfo_and_socket_for_family( port, AF_INET, &res );
|
||||
if( m_sock == -1 ) return false;
|
||||
}
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
unsigned long val = 0;
|
||||
setsockopt( m_sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&val, sizeof( val ) );
|
||||
#elif defined BSD
|
||||
int val = 0;
|
||||
setsockopt( m_sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&val, sizeof( val ) );
|
||||
val = 1;
|
||||
setsockopt( m_sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof( val ) );
|
||||
#else
|
||||
int val = 1;
|
||||
setsockopt( m_sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof( val ) );
|
||||
#endif
|
||||
if( bind( m_sock, res->ai_addr, res->ai_addrlen ) == -1 ) { freeaddrinfo( res ); Close(); return false; }
|
||||
if( listen( m_sock, backlog ) == -1 ) { freeaddrinfo( res ); Close(); return false; }
|
||||
freeaddrinfo( res );
|
||||
return true;
|
||||
}
|
||||
|
||||
Socket* ListenSocket::Accept()
|
||||
{
|
||||
struct sockaddr_storage remote;
|
||||
socklen_t sz = sizeof( remote );
|
||||
|
||||
struct pollfd fd;
|
||||
fd.fd = (socket_t)m_sock;
|
||||
fd.events = POLLIN;
|
||||
|
||||
if( poll( &fd, 1, 10 ) > 0 )
|
||||
{
|
||||
int sock = accept( m_sock, (sockaddr*)&remote, &sz);
|
||||
if( sock == -1 ) return nullptr;
|
||||
|
||||
#if defined __APPLE__
|
||||
int val = 1;
|
||||
setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) );
|
||||
#endif
|
||||
|
||||
auto ptr = (Socket*)tracy_malloc( sizeof( Socket ) );
|
||||
new(ptr) Socket( sock );
|
||||
return ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ListenSocket::Close()
|
||||
{
|
||||
assert( m_sock != -1 );
|
||||
#ifdef _WIN32
|
||||
closesocket( m_sock );
|
||||
#else
|
||||
close( m_sock );
|
||||
#endif
|
||||
m_sock = -1;
|
||||
}
|
||||
|
||||
UdpBroadcast::UdpBroadcast()
|
||||
: m_sock( -1 )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
InitWinSock();
|
||||
#endif
|
||||
}
|
||||
|
||||
UdpBroadcast::~UdpBroadcast()
|
||||
{
|
||||
if( m_sock != -1 ) Close();
|
||||
}
|
||||
|
||||
bool UdpBroadcast::Open( const char* addr, uint16_t port )
|
||||
{
|
||||
assert( m_sock == -1 );
|
||||
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res, *ptr;
|
||||
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
|
||||
char portbuf[32];
|
||||
sprintf( portbuf, "%" PRIu16, port );
|
||||
|
||||
if( getaddrinfo( addr, portbuf, &hints, &res ) != 0 ) return false;
|
||||
int sock = 0;
|
||||
for( ptr = res; ptr; ptr = ptr->ai_next )
|
||||
{
|
||||
if( ( sock = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol ) ) == -1 ) continue;
|
||||
#if defined __APPLE__
|
||||
int val = 1;
|
||||
setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) );
|
||||
#endif
|
||||
#if defined _WIN32
|
||||
unsigned long broadcast = 1;
|
||||
if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof( broadcast ) ) == -1 )
|
||||
#else
|
||||
int broadcast = 1;
|
||||
if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof( broadcast ) ) == -1 )
|
||||
#endif
|
||||
{
|
||||
#ifdef _WIN32
|
||||
closesocket( sock );
|
||||
#else
|
||||
close( sock );
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
freeaddrinfo( res );
|
||||
if( !ptr ) return false;
|
||||
|
||||
m_sock = sock;
|
||||
inet_pton( AF_INET, addr, &m_addr );
|
||||
return true;
|
||||
}
|
||||
|
||||
void UdpBroadcast::Close()
|
||||
{
|
||||
assert( m_sock != -1 );
|
||||
#ifdef _WIN32
|
||||
closesocket( m_sock );
|
||||
#else
|
||||
close( m_sock );
|
||||
#endif
|
||||
m_sock = -1;
|
||||
}
|
||||
|
||||
int UdpBroadcast::Send( uint16_t port, const void* data, int len )
|
||||
{
|
||||
assert( m_sock != -1 );
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons( port );
|
||||
addr.sin_addr.s_addr = m_addr;
|
||||
return sendto( m_sock, (const char*)data, len, MSG_NOSIGNAL, (sockaddr*)&addr, sizeof( addr ) );
|
||||
}
|
||||
|
||||
IpAddress::IpAddress()
|
||||
: m_number( 0 )
|
||||
{
|
||||
*m_text = '\0';
|
||||
}
|
||||
|
||||
IpAddress::~IpAddress()
|
||||
{
|
||||
}
|
||||
|
||||
void IpAddress::Set( const struct sockaddr& addr )
|
||||
{
|
||||
#if defined _WIN32 && ( !defined NTDDI_WIN10 || NTDDI_VERSION < NTDDI_WIN10 )
|
||||
struct sockaddr_in tmp;
|
||||
memcpy( &tmp, &addr, sizeof( tmp ) );
|
||||
auto ai = &tmp;
|
||||
#else
|
||||
auto ai = (const struct sockaddr_in*)&addr;
|
||||
#endif
|
||||
inet_ntop( AF_INET, &ai->sin_addr, m_text, 17 );
|
||||
m_number = ai->sin_addr.s_addr;
|
||||
}
|
||||
|
||||
UdpListen::UdpListen()
|
||||
: m_sock( -1 )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
InitWinSock();
|
||||
#endif
|
||||
}
|
||||
|
||||
UdpListen::~UdpListen()
|
||||
{
|
||||
if( m_sock != -1 ) Close();
|
||||
}
|
||||
|
||||
bool UdpListen::Listen( uint16_t port )
|
||||
{
|
||||
assert( m_sock == -1 );
|
||||
|
||||
int sock;
|
||||
if( ( sock = socket( AF_INET, SOCK_DGRAM, 0 ) ) == -1 ) return false;
|
||||
|
||||
#if defined __APPLE__
|
||||
int val = 1;
|
||||
setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) );
|
||||
#endif
|
||||
#if defined _WIN32
|
||||
unsigned long reuse = 1;
|
||||
setsockopt( m_sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof( reuse ) );
|
||||
#else
|
||||
int reuse = 1;
|
||||
setsockopt( m_sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof( reuse ) );
|
||||
#endif
|
||||
#if defined _WIN32
|
||||
unsigned long broadcast = 1;
|
||||
if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof( broadcast ) ) == -1 )
|
||||
#else
|
||||
int broadcast = 1;
|
||||
if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof( broadcast ) ) == -1 )
|
||||
#endif
|
||||
{
|
||||
#ifdef _WIN32
|
||||
closesocket( sock );
|
||||
#else
|
||||
close( sock );
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons( port );
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if( bind( sock, (sockaddr*)&addr, sizeof( addr ) ) == -1 )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
closesocket( sock );
|
||||
#else
|
||||
close( sock );
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
m_sock = sock;
|
||||
return true;
|
||||
}
|
||||
|
||||
void UdpListen::Close()
|
||||
{
|
||||
assert( m_sock != -1 );
|
||||
#ifdef _WIN32
|
||||
closesocket( m_sock );
|
||||
#else
|
||||
close( m_sock );
|
||||
#endif
|
||||
m_sock = -1;
|
||||
}
|
||||
|
||||
const char* UdpListen::Read( size_t& len, IpAddress& addr, int timeout )
|
||||
{
|
||||
static char buf[2048];
|
||||
|
||||
struct pollfd fd;
|
||||
fd.fd = (socket_t)m_sock;
|
||||
fd.events = POLLIN;
|
||||
if( poll( &fd, 1, timeout ) <= 0 ) return nullptr;
|
||||
|
||||
sockaddr sa;
|
||||
socklen_t salen = sizeof( struct sockaddr );
|
||||
len = (size_t)recvfrom( m_sock, buf, 2048, 0, &sa, &salen );
|
||||
addr.Set( sa );
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
}
|
||||
154
Source/ThirdParty/tracy/common/TracySocket.hpp
vendored
Normal file
154
Source/ThirdParty/tracy/common/TracySocket.hpp
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
#ifndef __TRACYSOCKET_HPP__
|
||||
#define __TRACYSOCKET_HPP__
|
||||
|
||||
#include <atomic>
|
||||
#include <stdint.h>
|
||||
|
||||
struct addrinfo;
|
||||
struct sockaddr;
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
void InitWinSock();
|
||||
#endif
|
||||
|
||||
class Socket
|
||||
{
|
||||
public:
|
||||
Socket();
|
||||
Socket( int sock );
|
||||
~Socket();
|
||||
|
||||
bool Connect( const char* addr, uint16_t port );
|
||||
bool ConnectBlocking( const char* addr, uint16_t port );
|
||||
void Close();
|
||||
|
||||
int Send( const void* buf, int len );
|
||||
int GetSendBufSize();
|
||||
|
||||
int ReadUpTo( void* buf, int len, int timeout );
|
||||
bool Read( void* buf, int len, int timeout );
|
||||
|
||||
template<typename ShouldExit>
|
||||
bool Read( void* buf, int len, int timeout, ShouldExit exitCb )
|
||||
{
|
||||
auto cbuf = (char*)buf;
|
||||
while( len > 0 )
|
||||
{
|
||||
if( exitCb() ) return false;
|
||||
if( !ReadImpl( cbuf, len, timeout ) ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadRaw( void* buf, int len, int timeout );
|
||||
bool HasData();
|
||||
bool IsValid() const;
|
||||
|
||||
Socket( const Socket& ) = delete;
|
||||
Socket( Socket&& ) = delete;
|
||||
Socket& operator=( const Socket& ) = delete;
|
||||
Socket& operator=( Socket&& ) = delete;
|
||||
|
||||
private:
|
||||
int RecvBuffered( void* buf, int len, int timeout );
|
||||
int Recv( void* buf, int len, int timeout );
|
||||
|
||||
bool ReadImpl( char*& buf, int& len, int timeout );
|
||||
|
||||
char* m_buf;
|
||||
char* m_bufPtr;
|
||||
std::atomic<int> m_sock;
|
||||
int m_bufLeft;
|
||||
|
||||
struct addrinfo *m_res;
|
||||
struct addrinfo *m_ptr;
|
||||
int m_connSock;
|
||||
};
|
||||
|
||||
class ListenSocket
|
||||
{
|
||||
public:
|
||||
ListenSocket();
|
||||
~ListenSocket();
|
||||
|
||||
bool Listen( uint16_t port, int backlog );
|
||||
Socket* Accept();
|
||||
void Close();
|
||||
|
||||
ListenSocket( const ListenSocket& ) = delete;
|
||||
ListenSocket( ListenSocket&& ) = delete;
|
||||
ListenSocket& operator=( const ListenSocket& ) = delete;
|
||||
ListenSocket& operator=( ListenSocket&& ) = delete;
|
||||
|
||||
private:
|
||||
int m_sock;
|
||||
};
|
||||
|
||||
class UdpBroadcast
|
||||
{
|
||||
public:
|
||||
UdpBroadcast();
|
||||
~UdpBroadcast();
|
||||
|
||||
bool Open( const char* addr, uint16_t port );
|
||||
void Close();
|
||||
|
||||
int Send( uint16_t port, const void* data, int len );
|
||||
|
||||
UdpBroadcast( const UdpBroadcast& ) = delete;
|
||||
UdpBroadcast( UdpBroadcast&& ) = delete;
|
||||
UdpBroadcast& operator=( const UdpBroadcast& ) = delete;
|
||||
UdpBroadcast& operator=( UdpBroadcast&& ) = delete;
|
||||
|
||||
private:
|
||||
int m_sock;
|
||||
uint32_t m_addr;
|
||||
};
|
||||
|
||||
class IpAddress
|
||||
{
|
||||
public:
|
||||
IpAddress();
|
||||
~IpAddress();
|
||||
|
||||
void Set( const struct sockaddr& addr );
|
||||
|
||||
uint32_t GetNumber() const { return m_number; }
|
||||
const char* GetText() const { return m_text; }
|
||||
|
||||
IpAddress( const IpAddress& ) = delete;
|
||||
IpAddress( IpAddress&& ) = delete;
|
||||
IpAddress& operator=( const IpAddress& ) = delete;
|
||||
IpAddress& operator=( IpAddress&& ) = delete;
|
||||
|
||||
private:
|
||||
uint32_t m_number;
|
||||
char m_text[17];
|
||||
};
|
||||
|
||||
class UdpListen
|
||||
{
|
||||
public:
|
||||
UdpListen();
|
||||
~UdpListen();
|
||||
|
||||
bool Listen( uint16_t port );
|
||||
void Close();
|
||||
|
||||
const char* Read( size_t& len, IpAddress& addr, int timeout );
|
||||
|
||||
UdpListen( const UdpListen& ) = delete;
|
||||
UdpListen( UdpListen&& ) = delete;
|
||||
UdpListen& operator=( const UdpListen& ) = delete;
|
||||
UdpListen& operator=( UdpListen&& ) = delete;
|
||||
|
||||
private:
|
||||
int m_sock;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
239
Source/ThirdParty/tracy/common/TracySystem.cpp
vendored
Normal file
239
Source/ThirdParty/tracy/common/TracySystem.cpp
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
#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__
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <pthread.h>
|
||||
# include <string.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
# ifdef __ANDROID__
|
||||
# include <sys/types.h>
|
||||
# else
|
||||
# include <sys/syscall.h>
|
||||
# endif
|
||||
# include <fcntl.h>
|
||||
#elif defined __FreeBSD__
|
||||
# include <sys/thr.h>
|
||||
#elif defined __NetBSD__ || defined __DragonFly__
|
||||
# include <sys/lwp.h>
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "TracySystem.hpp"
|
||||
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
extern "C" typedef HRESULT (WINAPI *t_SetThreadDescription)( HANDLE, PCWSTR );
|
||||
extern "C" typedef HRESULT (WINAPI *t_GetThreadDescription)( HANDLE, PWSTR* );
|
||||
#endif
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
# include <atomic>
|
||||
# include "TracyAlloc.hpp"
|
||||
#endif
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
TRACY_API uint64_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() );
|
||||
#elif defined __APPLE__
|
||||
uint64_t id;
|
||||
pthread_threadid_np( pthread_self(), &id );
|
||||
return id;
|
||||
#elif defined __ANDROID__
|
||||
return (uint64_t)gettid();
|
||||
#elif defined __linux__
|
||||
return (uint64_t)syscall( SYS_gettid );
|
||||
#elif defined __FreeBSD__
|
||||
long id;
|
||||
thr_self( &id );
|
||||
return id;
|
||||
#elif defined __NetBSD__
|
||||
return _lwp_self();
|
||||
#elif defined __DragonFly__
|
||||
return lwp_gettid();
|
||||
#elif defined __OpenBSD__
|
||||
return getthrid();
|
||||
#else
|
||||
static_assert( sizeof( decltype( pthread_self() ) ) <= sizeof( uint64_t ), "Thread handle too big to fit in protocol" );
|
||||
return uint64_t( pthread_self() );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
struct ThreadNameData
|
||||
{
|
||||
uint64_t id;
|
||||
const char* name;
|
||||
ThreadNameData* next;
|
||||
};
|
||||
std::atomic<ThreadNameData*>& GetThreadNameData();
|
||||
TRACY_API void InitRPMallocThread();
|
||||
#endif
|
||||
|
||||
TRACY_API void SetThreadName( const char* name )
|
||||
{
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
static auto _SetThreadDescription = (t_SetThreadDescription)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "SetThreadDescription" );
|
||||
if( _SetThreadDescription )
|
||||
{
|
||||
wchar_t buf[256];
|
||||
mbstowcs( buf, name, 256 );
|
||||
_SetThreadDescription( GetCurrentThread(), buf );
|
||||
}
|
||||
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.dwFlags = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#elif defined _GNU_SOURCE && !defined __EMSCRIPTEN__ && !defined __CYGWIN__
|
||||
{
|
||||
const auto sz = strlen( name );
|
||||
if( sz <= 15 )
|
||||
{
|
||||
pthread_setname_np( pthread_self(), name );
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[16];
|
||||
memcpy( buf, name, 15 );
|
||||
buf[15] = '\0';
|
||||
pthread_setname_np( pthread_self(), buf );
|
||||
}
|
||||
}
|
||||
#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 ) );
|
||||
data->id = detail::GetThreadHandleImpl();
|
||||
data->name = buf;
|
||||
data->next = GetThreadNameData().load( std::memory_order_relaxed );
|
||||
while( !GetThreadNameData().compare_exchange_weak( data->next, data, std::memory_order_release, std::memory_order_relaxed ) ) {}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TRACY_API const char* GetThreadName( uint64_t id )
|
||||
{
|
||||
static char buf[256];
|
||||
#ifdef TRACY_ENABLE
|
||||
auto ptr = GetThreadNameData().load( std::memory_order_relaxed );
|
||||
while( ptr )
|
||||
{
|
||||
if( ptr->id == id )
|
||||
{
|
||||
return ptr->name;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
#else
|
||||
# if defined _WIN32 || defined __CYGWIN__
|
||||
static auto _GetThreadDescription = (t_GetThreadDescription)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "GetThreadDescription" );
|
||||
if( _GetThreadDescription )
|
||||
{
|
||||
auto hnd = OpenThread( THREAD_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)id );
|
||||
if( hnd != 0 )
|
||||
{
|
||||
PWSTR tmp;
|
||||
_GetThreadDescription( hnd, &tmp );
|
||||
auto ret = wcstombs( buf, tmp, 256 );
|
||||
CloseHandle( hnd );
|
||||
if( ret != 0 )
|
||||
{
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
# elif defined __linux__
|
||||
int cs, fd;
|
||||
char path[32];
|
||||
# ifdef __ANDROID__
|
||||
int tid = gettid();
|
||||
# else
|
||||
int tid = (int) syscall( SYS_gettid );
|
||||
# endif
|
||||
snprintf( path, sizeof( path ), "/proc/self/task/%d/comm", tid );
|
||||
sprintf( buf, "%" PRIu64, id );
|
||||
# ifndef __ANDROID__
|
||||
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &cs );
|
||||
# endif
|
||||
if ( ( fd = open( path, O_RDONLY ) ) > 0) {
|
||||
int len = read( fd, buf, 255 );
|
||||
if( len > 0 )
|
||||
{
|
||||
buf[len] = 0;
|
||||
if( len > 1 && buf[len-1] == '\n' )
|
||||
{
|
||||
buf[len-1] = 0;
|
||||
}
|
||||
}
|
||||
close( fd );
|
||||
}
|
||||
# ifndef __ANDROID__
|
||||
pthread_setcancelstate( cs, 0 );
|
||||
# endif
|
||||
return buf;
|
||||
# endif
|
||||
#endif
|
||||
sprintf( buf, "%" PRIu64, id );
|
||||
return buf;
|
||||
}
|
||||
|
||||
}
|
||||
95
Source/ThirdParty/tracy/common/TracySystem.hpp
vendored
Normal file
95
Source/ThirdParty/tracy/common/TracySystem.hpp
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
#ifndef __TRACYSYSTEM_HPP__
|
||||
#define __TRACYSYSTEM_HPP__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Tracy -> Flax integration:
|
||||
// - use LZ4 from Flax
|
||||
// - use engine symbols export
|
||||
// - use engine types and macros
|
||||
// - remove AddVectoredExceptionHandler from win32 to prevent messing with Flax crashes reporting
|
||||
// - hide implementation from includers to reduce compilation overhead
|
||||
// - optimize includes (faster compilation)
|
||||
// - remove some features (colors, frame image, dx1 compression)
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
#define TRACY_API FLAXENGINE_API
|
||||
#define tracy_force_inline FORCE_INLINE
|
||||
#define tracy_no_inline FORCE_NOINLINE
|
||||
|
||||
#ifndef TracyConcat
|
||||
# define TracyConcat(x,y) TracyConcatIndirect(x,y)
|
||||
#endif
|
||||
#ifndef TracyConcatIndirect
|
||||
# define TracyConcatIndirect(x,y) x##y
|
||||
#endif
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
enum class PlotFormatType : uint8_t
|
||||
{
|
||||
Number,
|
||||
Memory,
|
||||
Percentage
|
||||
};
|
||||
|
||||
typedef void(*ParameterCallback)( uint32_t idx, int32_t val );
|
||||
|
||||
struct TRACY_API SourceLocationData
|
||||
{
|
||||
const char* name;
|
||||
const char* function;
|
||||
const char* file;
|
||||
uint32_t line;
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
class TRACY_API ScopedZone
|
||||
{
|
||||
public:
|
||||
ScopedZone( const ScopedZone& ) = delete;
|
||||
ScopedZone( ScopedZone&& ) = delete;
|
||||
ScopedZone& operator=( const ScopedZone& ) = delete;
|
||||
ScopedZone& operator=( ScopedZone&& ) = delete;
|
||||
|
||||
ScopedZone( const SourceLocationData* srcloc, bool is_active = true );
|
||||
ScopedZone( const SourceLocationData* srcloc, int depth, bool is_active = true );
|
||||
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 = true );
|
||||
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 = true );
|
||||
|
||||
~ScopedZone();
|
||||
|
||||
void Text( const char* txt, size_t size );
|
||||
void Name( const char* txt, size_t size );
|
||||
void Name( const Char* txt, size_t size );
|
||||
void Color( uint32_t color );
|
||||
void Value( uint64_t value );
|
||||
bool IsActive() const;
|
||||
|
||||
private:
|
||||
const bool m_active;
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
uint64_t m_connectionId;
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
TRACY_API uint64_t GetThreadHandleImpl();
|
||||
}
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
TRACY_API uint64_t GetThreadHandle();
|
||||
#else
|
||||
static inline uint64_t GetThreadHandle()
|
||||
{
|
||||
return detail::GetThreadHandleImpl();
|
||||
}
|
||||
#endif
|
||||
|
||||
TRACY_API void SetThreadName( const char* name );
|
||||
TRACY_API const char* GetThreadName( uint64_t id );
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user