312 lines
9.3 KiB
C++
312 lines
9.3 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "Trace/Trace.inl" // should be Config.h :(
|
|
|
|
#if TRACE_PRIVATE_MINIMAL_ENABLED
|
|
|
|
#include "Misc/CString.h"
|
|
#include "Trace/Detail/Channel.h"
|
|
|
|
|
|
namespace UE {
|
|
namespace Trace {
|
|
|
|
namespace Private
|
|
{
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void Message_SetCallback(OnMessageFunc* Callback);
|
|
void Writer_SetUpdateCallback(OnUpdateFunc* Callback);
|
|
void Writer_MemorySetHooks(AllocFunc, FreeFunc);
|
|
void Writer_Initialize(const FInitializeDesc&);
|
|
void Writer_WorkerCreate();
|
|
void Writer_UnsetBlockPoolLimit();
|
|
void Writer_Shutdown();
|
|
void Writer_Update();
|
|
bool Writer_SendTo(const ANSICHAR*, uint32, uint32);
|
|
bool Writer_WriteTo(const ANSICHAR*, uint32);
|
|
bool Writer_RelayTo(UPTRINT, IoWriteFunc, IoCloseFunc, uint16);
|
|
bool Writer_WriteSnapshotTo(const ANSICHAR*);
|
|
bool Writer_SendSnapshotTo(const ANSICHAR*, uint32);
|
|
bool Writer_IsTracing();
|
|
bool Writer_IsTracingTo(uint32 (&OutSessionGuid)[4], uint32 (&OutTraceGuid)[4]);
|
|
bool Writer_Stop();
|
|
uint32 Writer_GetThreadId();
|
|
|
|
extern FStatistics GTraceStatistics;
|
|
|
|
UE_TRACE_MINIMAL_EVENT_BEGIN($Trace, TraceStall)
|
|
UE_TRACE_MINIMAL_EVENT_FIELD(uint64, StartCycle)
|
|
UE_TRACE_MINIMAL_EVENT_FIELD(uint64, EndCycle)
|
|
UE_TRACE_MINIMAL_EVENT_END()
|
|
|
|
void LogStall(uint64 Start, uint64 End)
|
|
{
|
|
UE_TRACE_LOG($Trace, TraceStall, true)
|
|
<< TraceStall.StartCycle(Start)
|
|
<< TraceStall.EndCycle(End);
|
|
}
|
|
|
|
} // namespace Private
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
template <int DestSize, typename SRC_TYPE>
|
|
static uint32 ToAnsiCheap(ANSICHAR (&Dest)[DestSize], const SRC_TYPE* Src)
|
|
{
|
|
const SRC_TYPE* Cursor = Src;
|
|
for (ANSICHAR& Out : Dest)
|
|
{
|
|
Out = ANSICHAR(*Cursor++ & 0x7f);
|
|
if (Out == '\0')
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
Dest[DestSize - 1] = '\0';
|
|
return uint32(UPTRINT(Cursor - Src));
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SetMemoryHooks(AllocFunc Alloc, FreeFunc Free)
|
|
{
|
|
Private::Writer_MemorySetHooks(Alloc, Free);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SetMessageCallback(OnMessageFunc* MessageFunc)
|
|
{
|
|
Private::Message_SetCallback(MessageFunc);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SetUpdateCallback(OnUpdateFunc* UpdateFunc)
|
|
{
|
|
Private::Writer_SetUpdateCallback(UpdateFunc);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void Initialize(const FInitializeDesc& Desc)
|
|
{
|
|
Private::Writer_Initialize(Desc);
|
|
FChannel::Initialize();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void Exit()
|
|
{
|
|
Private::Writer_UnsetBlockPoolLimit();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void Shutdown()
|
|
{
|
|
Private::Writer_Shutdown();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void Panic()
|
|
{
|
|
FChannel::PanicDisableAll();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void Update()
|
|
{
|
|
Private::Writer_Update();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void GetStatistics(FStatistics& Out)
|
|
{
|
|
Out.BytesSent = Private::AtomicLoadRelaxed(&Private::GTraceStatistics.BytesSent);
|
|
Out.BytesTraced = Private::AtomicLoadRelaxed(&Private::GTraceStatistics.BytesTraced);
|
|
Out.BytesEmitted = Private::AtomicLoadRelaxed(&Private::GTraceStatistics.BytesEmitted);
|
|
Out.MemoryUsed = Private::AtomicLoadRelaxed(&Private::GTraceStatistics.MemoryUsed);
|
|
Out.BlockPoolAllocated = Private::AtomicLoadRelaxed(&Private::GTraceStatistics.BlockPoolAllocated);
|
|
Out.SharedBufferAllocated = Private::AtomicLoadRelaxed(&Private::GTraceStatistics.SharedBufferAllocated);
|
|
Out.FixedBufferAllocated = Private::AtomicLoadRelaxed(&Private::GTraceStatistics.FixedBufferAllocated);
|
|
Out.CacheAllocated = Private::AtomicLoadRelaxed(&Private::GTraceStatistics.CacheAllocated);
|
|
Out.CacheUsed = Private::AtomicLoadRelaxed(&Private::GTraceStatistics.CacheUsed);
|
|
Out.CacheWaste = Private::AtomicLoadRelaxed(&Private::GTraceStatistics.CacheWaste);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool SendTo(const TCHAR* InHost, uint32 Port, uint16 Flags)
|
|
{
|
|
char Host[256];
|
|
ToAnsiCheap(Host, InHost);
|
|
return Private::Writer_SendTo(Host, Flags, Port);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool WriteTo(const TCHAR* InPath, uint16 Flags)
|
|
{
|
|
char Path[512];
|
|
ToAnsiCheap(Path, InPath);
|
|
return Private::Writer_WriteTo(Path, Flags);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool RelayTo(UPTRINT InHandle, IoWriteFunc WriteFunc, IoCloseFunc CloseFunc, uint16 Flags)
|
|
{
|
|
return Private::Writer_RelayTo(InHandle, WriteFunc, CloseFunc, Flags);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool WriteSnapshotTo(const TCHAR* InPath)
|
|
{
|
|
char Path[512];
|
|
ToAnsiCheap(Path, InPath);
|
|
return Private::Writer_WriteSnapshotTo(Path);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool SendSnapshotTo(const TCHAR* InHost, uint32 InPort)
|
|
{
|
|
char Host[512];
|
|
ToAnsiCheap(Host, InHost);
|
|
return Private::Writer_SendSnapshotTo(Host, InPort);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool IsTracing()
|
|
{
|
|
return Private::Writer_IsTracing();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool IsTracingTo(uint32 (&OutSessionGuid)[4], uint32 (&OutTraceGuid)[4])
|
|
{
|
|
return Private::Writer_IsTracingTo(OutSessionGuid, OutTraceGuid);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool Stop()
|
|
{
|
|
return Private::Writer_Stop();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool IsChannel(const TCHAR* ChannelName)
|
|
{
|
|
ANSICHAR ChannelNameA[64];
|
|
ToAnsiCheap(ChannelNameA, ChannelName);
|
|
return FChannel::FindChannel(ChannelNameA) != nullptr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool ToggleChannel(const TCHAR* ChannelName, bool bEnabled)
|
|
{
|
|
ANSICHAR ChannelNameA[64];
|
|
ToAnsiCheap(ChannelNameA, ChannelName);
|
|
return FChannel::Toggle(ChannelNameA, bEnabled);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void EnumerateChannels(ChannelIterFunc IterFunc, void* User)
|
|
{
|
|
struct FCallbackDataWrapper
|
|
{
|
|
ChannelIterFunc* Func;
|
|
void* User;
|
|
};
|
|
|
|
FCallbackDataWrapper Wrapper;
|
|
Wrapper.Func = IterFunc;
|
|
Wrapper.User = User;
|
|
|
|
FChannel::EnumerateChannels([](const FChannelInfo& Info, void* User)
|
|
{
|
|
FCallbackDataWrapper* Wrapper = (FCallbackDataWrapper*)User;
|
|
(*Wrapper).Func(Info.Name, Info.bIsEnabled, (*Wrapper).User);
|
|
return true;
|
|
}, &Wrapper);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void EnumerateChannels(ChannelIterCallback IterFunc, void* User)
|
|
{
|
|
FChannel::EnumerateChannels(IterFunc, User);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void StartWorkerThread()
|
|
{
|
|
Private::Writer_WorkerCreate();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
FChannel* FindChannel(const TCHAR* ChannelName)
|
|
{
|
|
ANSICHAR ChannelNameA[64];
|
|
ToAnsiCheap(ChannelNameA, ChannelName);
|
|
return FChannel::FindChannel(ChannelNameA);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
FChannel* FindChannel(FChannelId ChannelId)
|
|
{
|
|
return FChannel::FindChannel(ChannelId);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
UE_TRACE_MINIMAL_CHANNEL_EXTERN(TraceLogChannel)
|
|
|
|
UE_TRACE_MINIMAL_EVENT_BEGIN($Trace, ThreadInfo, NoSync|Important)
|
|
UE_TRACE_MINIMAL_EVENT_FIELD(uint32, ThreadId)
|
|
UE_TRACE_MINIMAL_EVENT_FIELD(uint32, SystemId)
|
|
UE_TRACE_MINIMAL_EVENT_FIELD(int32, SortHint)
|
|
UE_TRACE_MINIMAL_EVENT_FIELD(AnsiString, Name)
|
|
UE_TRACE_MINIMAL_EVENT_END()
|
|
|
|
UE_TRACE_MINIMAL_EVENT_BEGIN($Trace, ThreadGroupBegin, NoSync|Important)
|
|
UE_TRACE_MINIMAL_EVENT_FIELD(AnsiString, Name)
|
|
UE_TRACE_MINIMAL_EVENT_END()
|
|
|
|
UE_TRACE_MINIMAL_EVENT_BEGIN($Trace, ThreadGroupEnd, NoSync|Important)
|
|
UE_TRACE_MINIMAL_EVENT_END()
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void ThreadRegister(const TCHAR* Name, uint32 SystemId, int32 SortHint)
|
|
{
|
|
ANSICHAR NameA[96];
|
|
|
|
uint32 ThreadId = Private::Writer_GetThreadId();
|
|
uint32 NameLen = ToAnsiCheap(NameA, Name);
|
|
UE_TRACE_MINIMAL_LOG($Trace, ThreadInfo, TraceLogChannel, NameLen * sizeof(ANSICHAR))
|
|
<< ThreadInfo.ThreadId(ThreadId)
|
|
<< ThreadInfo.SystemId(SystemId)
|
|
<< ThreadInfo.SortHint(SortHint)
|
|
<< ThreadInfo.Name(NameA, NameLen);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void ThreadGroupBegin(const TCHAR* Name)
|
|
{
|
|
ANSICHAR NameA[96];
|
|
|
|
uint32 NameLen = ToAnsiCheap(NameA, Name);
|
|
UE_TRACE_MINIMAL_LOG($Trace, ThreadGroupBegin, TraceLogChannel, NameLen * sizeof(ANSICHAR))
|
|
<< ThreadGroupBegin.Name(Name, NameLen);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void ThreadGroupEnd()
|
|
{
|
|
UE_TRACE_MINIMAL_LOG($Trace, ThreadGroupEnd, TraceLogChannel);
|
|
}
|
|
|
|
} // namespace Trace
|
|
} // namespace UE
|
|
|
|
#else
|
|
|
|
// Workaround for module not having any exported symbols
|
|
TRACELOG_API int TraceLogExportedSymbol = 0;
|
|
|
|
#endif // TRACE_PRIVATE_MINIMAL_ENABLED
|