Files
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

121 lines
4.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreTypes.h"
#include "Containers/Map.h"
// TraceServices
#include "Common/PagedArray.h"
#include "Common/ProviderLock.h"
#include "Model/MonotonicTimeline.h"
#include "TraceServices/Model/AnalysisSession.h"
#include "TraceServices/Model/StackSamples.h"
#include "TraceServices/Model/TimingProfiler.h"
namespace TraceServices
{
class IModuleProvider;
extern thread_local FProviderLock::FThreadLocalState GStackSamplesProviderLockState;
typedef TMonotonicTimeline<FTimingProfilerEvent> FStackSamplesTimeline;
class FStackSamplesProviderThread
{
friend class FStackSamplesProvider;
public:
FStackSamplesProviderThread(uint32 InSystemThreadId)
: SystemThreadId(InSystemThreadId)
{
}
~FStackSamplesProviderThread()
{
}
uint32 GetSystemThreadId() const { return SystemThreadId; }
const TCHAR* GetName() const { return Name; }
FStackSamplesTimeline* GetTimeline() const { return Timeline.Get(); }
private:
uint32 SystemThreadId = 0;
const TCHAR* Name = nullptr;
TSharedPtr<FStackSamplesTimeline> Timeline;
TArray<uint64> LastSampleStack;
double LastSampleTime = 0.0;
};
class FStackSamplesProvider
: public IStackSamplesProvider
, public IEditableProvider
{
public:
explicit FStackSamplesProvider(IAnalysisSession& Session);
virtual ~FStackSamplesProvider();
//////////////////////////////////////////////////
// Read operations
virtual void BeginRead() const override { Lock.BeginRead(GStackSamplesProviderLockState); }
virtual void EndRead() const override { Lock.EndRead(GStackSamplesProviderLockState); }
virtual void ReadAccessCheck() const override { Lock.ReadAccessCheck(GStackSamplesProviderLockState); }
virtual uint32 GetStackFrameCount() const override;
virtual void EnumerateStackFrames(TFunctionRef<void(const FStackSampleFrame& Frame)> Callback) const override;
virtual uint32 GetThreadCount() const override;
virtual void EnumerateThreads(TFunctionRef<void(const FStackSampleThread& Thread)> Callback) const override;
virtual uint32 GetTimelineCount() const override;
virtual void EnumerateTimelines(TFunctionRef<void(const FStackSampleTimeline& Timeline, const FStackSampleThread& Thread)> Callback) const override;
virtual const FStackSampleTimeline* GetTimeline(uint32 SystemThreadId) const override;
//////////////////////////////////////////////////
// Edit operations
virtual void BeginEdit() const override { Lock.BeginWrite(GStackSamplesProviderLockState); }
virtual void EndEdit() const override { Lock.EndWrite(GStackSamplesProviderLockState); }
virtual void EditAccessCheck() const override { Lock.WriteAccessCheck(GStackSamplesProviderLockState); }
void SetSamplingInterval(uint32 Microseconds);
void AddThreadName(uint32 SystemThreadId, uint32 SystemProcessId, FStringView Name);
void AddStackSample(uint32 SystemThreadId, double Time, uint32 Count, const uint64* Addresses);
double OnAnalysisEnd();
bool UpdatePendingTimers();
//////////////////////////////////////////////////
private:
FStackSamplesProviderThread& GetOrAddThread(uint32 SystemThreadId);
FStackSampleFrame& GetOrAddStackFrame(uint64 Address);
void CreateTimer(FStackSampleFrame& StackFrame);
bool UpdateTimerName(FStackSampleFrame& StackFrame, bool bFirstTime);
private:
mutable FProviderLock Lock;
IAnalysisSession& Session;
IEditableTimingProfilerProvider* EditableTimingProfilerProvider = nullptr;
IModuleProvider* ModuleProvider = nullptr;
TPagedArray<FStackSamplesProviderThread> Threads;
TArray<FStackSamplesProviderThread*> Timelines; // the threads with a valid timeline
TMap<uint32, FStackSamplesProviderThread*> ThreadsBySystemId; // SystemThreadId --> FThreadSamplingData*
TPagedArray<FStackSampleFrame> StackFrames;
TMap<uint64, FStackSampleFrame*> StackFramesByAddress; // Address --> FStackSampleFrame*
TMap<uint32, FStackSampleFrame*> StackFramesByTimerId; // TimerId --> FStackSampleFrame*
TArray<FStackSampleFrame*> PendingTimers;
double MaxSampleDuration = 0.0;// [seconds]
uint32 SamplingIntervalUsec = 0;// [microseconds]
int32 MaxStackSize = 0;
uint64 TotalNumFrames = 0;
uint64 TotalNumSamples = 0;
};
} // namespace TraceServices