2019-12-26 15:32:37 -05:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
2019-06-03 15:32:00 -04:00
|
|
|
|
2019-10-03 16:26:48 -04:00
|
|
|
#include "Processor.h"
|
|
|
|
|
#include "HAL/Event.h"
|
2022-05-17 13:24:57 -04:00
|
|
|
#include "HAL/LowLevelMemTracker.h"
|
2019-10-03 16:26:48 -04:00
|
|
|
#include "HAL/PlatformProcess.h"
|
|
|
|
|
#include "HAL/RunnableThread.h"
|
2019-11-25 12:03:09 -05:00
|
|
|
#include "StreamReader.h"
|
2023-01-19 05:33:25 -05:00
|
|
|
#include "TraceAnalysisModule.h"
|
|
|
|
|
#include "Logging/MessageLog.h"
|
2019-10-03 16:26:48 -04:00
|
|
|
#include "Templates/UnrealTemplate.h"
|
2020-02-05 14:26:36 -05:00
|
|
|
#include "Trace/DataStream.h"
|
2019-06-03 15:32:00 -04:00
|
|
|
|
2020-11-17 06:54:28 -04:00
|
|
|
namespace UE {
|
|
|
|
|
namespace Trace {
|
2019-06-03 15:32:00 -04:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2023-06-19 07:17:37 -04:00
|
|
|
FAnalysisProcessor::FImpl::FImpl(IInDataStream& InDataStream, TArray<IAnalyzer*>&& InAnalyzers, FMessageDelegate&& InMessage)
|
|
|
|
|
: AnalysisEngine(Forward<TArray<IAnalyzer*>>(InAnalyzers), Forward<FMessageDelegate>(InMessage))
|
2019-10-03 16:26:48 -04:00
|
|
|
, DataStream(InDataStream)
|
|
|
|
|
, StopEvent(FPlatformProcess::GetSynchEventFromPool(true))
|
|
|
|
|
, UnpausedEvent(FPlatformProcess::GetSynchEventFromPool(true))
|
2019-06-03 15:32:00 -04:00
|
|
|
{
|
2019-10-03 16:26:48 -04:00
|
|
|
Thread = FRunnableThread::Create(this, TEXT("TraceAnalysis"));
|
|
|
|
|
PauseAnalysis(false);
|
|
|
|
|
}
|
2019-06-03 15:32:00 -04:00
|
|
|
|
2019-10-03 16:26:48 -04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
FAnalysisProcessor::FImpl::~FImpl()
|
|
|
|
|
{
|
|
|
|
|
StopAnalysis();
|
|
|
|
|
FPlatformProcess::ReturnSynchEventToPool(UnpausedEvent);
|
|
|
|
|
FPlatformProcess::ReturnSynchEventToPool(StopEvent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
uint32 FAnalysisProcessor::FImpl::Run()
|
|
|
|
|
{
|
2022-05-16 07:37:42 -04:00
|
|
|
LLM_SCOPE_BYNAME(TEXT("TraceAnalysis"));
|
|
|
|
|
|
2021-07-27 04:32:25 -04:00
|
|
|
AnalysisEngine.Begin();
|
2019-11-25 12:03:09 -05:00
|
|
|
|
2022-02-10 03:53:13 -05:00
|
|
|
FStreamBuffer Buffer(4 << 20);
|
2019-11-25 12:03:09 -05:00
|
|
|
while (!StopEvent->Wait(0, true))
|
2019-06-03 15:32:00 -04:00
|
|
|
{
|
2019-11-25 12:03:09 -05:00
|
|
|
UnpausedEvent->Wait();
|
|
|
|
|
|
|
|
|
|
int32 BytesRead = Buffer.Fill([&] (uint8* Out, uint32 Size)
|
|
|
|
|
{
|
|
|
|
|
return DataStream.Read(Out, Size);
|
|
|
|
|
});
|
|
|
|
|
|
2022-02-16 10:23:17 -05:00
|
|
|
if (BytesRead <= 0)
|
2019-10-03 16:26:48 -04:00
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-25 12:03:09 -05:00
|
|
|
if (!AnalysisEngine.OnData(Buffer))
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-06-03 15:32:00 -04:00
|
|
|
}
|
2019-10-03 16:26:48 -04:00
|
|
|
|
2020-01-29 08:18:18 -05:00
|
|
|
AnalysisEngine.End();
|
2020-06-23 18:40:00 -04:00
|
|
|
bComplete = true;
|
2019-10-03 16:26:48 -04:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
bool FAnalysisProcessor::FImpl::IsActive() const
|
|
|
|
|
{
|
2020-06-23 18:40:00 -04:00
|
|
|
return !bComplete;
|
2019-10-03 16:26:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void FAnalysisProcessor::FImpl::StopAnalysis()
|
|
|
|
|
{
|
|
|
|
|
if (IsActive())
|
|
|
|
|
{
|
|
|
|
|
StopEvent->Trigger();
|
|
|
|
|
WaitOnAnalysis();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void FAnalysisProcessor::FImpl::WaitOnAnalysis()
|
|
|
|
|
{
|
|
|
|
|
if (IsActive())
|
|
|
|
|
{
|
|
|
|
|
Thread->Kill(true);
|
|
|
|
|
delete Thread;
|
|
|
|
|
Thread = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void FAnalysisProcessor::FImpl::PauseAnalysis(bool bState)
|
|
|
|
|
{
|
|
|
|
|
if (IsActive())
|
|
|
|
|
{
|
|
|
|
|
bState ? UnpausedEvent->Reset() : UnpausedEvent->Trigger();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
bool FAnalysisProcessor::IsActive() const { return (Impl != nullptr) ? Impl->IsActive() : false; }
|
|
|
|
|
void FAnalysisProcessor::Stop() { if (Impl != nullptr) { Impl->StopAnalysis(); } }
|
|
|
|
|
void FAnalysisProcessor::Wait() { if (Impl != nullptr) { Impl->WaitOnAnalysis(); } }
|
|
|
|
|
void FAnalysisProcessor::Pause(bool bState) { if (Impl != nullptr) { Impl->PauseAnalysis(bState); } }
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
FAnalysisProcessor::FAnalysisProcessor(FAnalysisProcessor&& Rhs)
|
2020-01-29 08:16:27 -05:00
|
|
|
{
|
|
|
|
|
this->operator = (MoveTemp(Rhs));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
FAnalysisProcessor& FAnalysisProcessor::operator = (FAnalysisProcessor&& Rhs)
|
2019-10-03 16:26:48 -04:00
|
|
|
{
|
|
|
|
|
Swap(Impl, Rhs.Impl);
|
2020-01-29 08:16:27 -05:00
|
|
|
return *this;
|
2019-10-03 16:26:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
FAnalysisProcessor::~FAnalysisProcessor()
|
|
|
|
|
{
|
|
|
|
|
delete Impl;
|
2019-06-03 15:32:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Trace
|
2020-11-17 06:54:28 -04:00
|
|
|
} // namespace UE
|