2019-12-26 15:32:37 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-06-03 15:32:00 -04:00
# include "TraceServices/AnalysisService.h"
# include "AnalysisServicePrivate.h"
# include "Trace/Analyzer.h"
# include "Trace/Analysis.h"
# include "Trace/DataStream.h"
# include "HAL/PlatformFile.h"
# include "Analyzers/MiscTraceAnalysis.h"
# include "Analyzers/LogTraceAnalysis.h"
# include "Math/RandomStream.h"
# include "ModuleServicePrivate.h"
# include "Model/LogPrivate.h"
# include "Model/FramesPrivate.h"
# include "Model/BookmarksPrivate.h"
# include "Model/ThreadsPrivate.h"
2019-10-03 16:26:48 -04:00
# include "Model/CountersPrivate.h"
# include "Model/NetProfilerProvider.h"
2020-06-23 18:40:00 -04:00
# include "Model/MemoryPrivate.h"
2020-01-13 07:16:09 -05:00
# include "Model/Channel.h"
2020-06-23 18:40:00 -04:00
# include "Model/DiagnosticsPrivate.h"
2022-03-22 12:35:42 -04:00
# include "Model/ScreenshotProviderPrivate.h"
2019-06-03 15:32:00 -04:00
2020-11-13 05:29:37 -04:00
namespace TraceServices
2019-06-03 15:32:00 -04:00
{
2019-12-13 11:07:03 -05:00
thread_local FAnalysisSessionLock * GThreadCurrentSessionLock ;
thread_local int32 GThreadCurrentReadLockCount ;
thread_local int32 GThreadCurrentWriteLockCount ;
2019-06-03 15:32:00 -04:00
void FAnalysisSessionLock : : ReadAccessCheck ( ) const
{
2019-12-13 11:07:03 -05:00
checkf ( GThreadCurrentSessionLock = = this & & ( GThreadCurrentReadLockCount > 0 | | GThreadCurrentWriteLockCount > 0 ) , TEXT ( " Trying to read from session outside of a ReadScope " ) ) ;
2019-06-03 15:32:00 -04:00
}
void FAnalysisSessionLock : : WriteAccessCheck ( ) const
{
2019-12-13 11:07:03 -05:00
checkf ( GThreadCurrentSessionLock = = this & & GThreadCurrentWriteLockCount > 0 , TEXT ( " Trying to write to session outside of an EditScope " ) ) ;
2019-06-03 15:32:00 -04:00
}
void FAnalysisSessionLock : : BeginRead ( )
{
2019-12-13 11:07:03 -05:00
check ( ! GThreadCurrentSessionLock | | GThreadCurrentSessionLock = = this ) ;
checkf ( GThreadCurrentWriteLockCount = = 0 , TEXT ( " Trying to lock for read while holding write access " ) ) ;
if ( GThreadCurrentReadLockCount + + = = 0 )
{
GThreadCurrentSessionLock = this ;
RWLock . ReadLock ( ) ;
}
2019-06-03 15:32:00 -04:00
}
void FAnalysisSessionLock : : EndRead ( )
{
2019-12-13 11:07:03 -05:00
check ( GThreadCurrentReadLockCount > 0 ) ;
if ( - - GThreadCurrentReadLockCount = = 0 )
{
RWLock . ReadUnlock ( ) ;
GThreadCurrentSessionLock = nullptr ;
}
2019-06-03 15:32:00 -04:00
}
void FAnalysisSessionLock : : BeginEdit ( )
{
2019-12-13 11:07:03 -05:00
check ( ! GThreadCurrentSessionLock | | GThreadCurrentSessionLock = = this ) ;
2020-09-24 00:43:27 -04:00
checkf ( GThreadCurrentReadLockCount = = 0 , TEXT ( " Trying to lock for edit while holding read access " ) ) ;
2019-12-13 11:07:03 -05:00
if ( GThreadCurrentWriteLockCount + + = = 0 )
{
GThreadCurrentSessionLock = this ;
RWLock . WriteLock ( ) ;
}
2019-06-03 15:32:00 -04:00
}
void FAnalysisSessionLock : : EndEdit ( )
{
2019-12-13 11:07:03 -05:00
check ( GThreadCurrentWriteLockCount > 0 ) ;
if ( - - GThreadCurrentWriteLockCount = = 0 )
{
RWLock . WriteUnlock ( ) ;
GThreadCurrentSessionLock = nullptr ;
}
2019-06-03 15:32:00 -04:00
}
2021-10-27 15:14:40 -04:00
FAnalysisSession : : FAnalysisSession ( uint32 InTraceId , const TCHAR * SessionName , TUniquePtr < UE : : Trace : : IInDataStream > & & InDataStream )
2019-06-03 15:32:00 -04:00
: Name ( SessionName )
2021-10-27 15:14:40 -04:00
, TraceId ( InTraceId )
2019-06-03 15:32:00 -04:00
, DurationSeconds ( 0.0 )
, Allocator ( 32 < < 20 )
, StringStore ( Allocator )
2021-06-01 04:06:54 -04:00
, Cache ( * Name )
2020-01-29 08:58:49 -05:00
, DataStream ( MoveTemp ( InDataStream ) )
2019-06-03 15:32:00 -04:00
{
}
FAnalysisSession : : ~ FAnalysisSession ( )
{
2019-10-03 16:26:48 -04:00
for ( int32 AnalyzerIndex = Analyzers . Num ( ) - 1 ; AnalyzerIndex > = 0 ; - - AnalyzerIndex )
2019-06-03 15:32:00 -04:00
{
2019-10-03 16:26:48 -04:00
delete Analyzers [ AnalyzerIndex ] ;
2019-06-03 15:32:00 -04:00
}
2019-10-03 16:26:48 -04:00
for ( int32 ProviderIndex = Providers . Num ( ) - 1 ; ProviderIndex > = 0 ; - - ProviderIndex )
{
delete Providers [ ProviderIndex ] ;
}
2019-05-13 09:05:12 -04:00
}
2020-01-29 08:58:49 -05:00
void FAnalysisSession : : Start ( )
{
2020-11-17 06:54:28 -04:00
UE : : Trace : : FAnalysisContext Context ;
for ( UE : : Trace : : IAnalyzer * Analyzer : ReadAnalyzers ( ) )
2020-01-29 08:58:49 -05:00
{
Context . AddAnalyzer ( * Analyzer ) ;
}
Processor = Context . Process ( * DataStream ) ;
}
void FAnalysisSession : : Stop ( bool bAndWait ) const
{
2021-05-06 11:07:53 -04:00
DataStream - > Close ( ) ;
2021-04-16 09:23:58 -04:00
Processor . Stop ( ) ;
2020-01-29 08:58:49 -05:00
if ( bAndWait )
{
Wait ( ) ;
}
}
void FAnalysisSession : : Wait ( ) const
{
Processor . Wait ( ) ;
}
2020-11-17 06:54:28 -04:00
void FAnalysisSession : : AddAnalyzer ( UE : : Trace : : IAnalyzer * Analyzer )
2019-05-13 09:05:12 -04:00
{
2019-10-03 16:26:48 -04:00
Analyzers . Add ( Analyzer ) ;
2019-06-03 15:32:00 -04:00
}
void FAnalysisSession : : AddProvider ( const FName & InName , IProvider * Provider )
{
2019-10-03 16:26:48 -04:00
Providers . Add ( Provider ) ;
ProvidersMap . Add ( InName , Provider ) ;
2019-06-03 15:32:00 -04:00
}
const IProvider * FAnalysisSession : : ReadProviderPrivate ( const FName & InName ) const
{
2019-10-03 16:26:48 -04:00
IProvider * const * FindIt = ProvidersMap . Find ( InName ) ;
if ( FindIt )
{
return * FindIt ;
}
else
{
return nullptr ;
}
2019-05-13 09:05:12 -04:00
}
2019-10-03 16:26:48 -04:00
IProvider * FAnalysisSession : : EditProviderPrivate ( const FName & InName )
2019-05-13 09:05:12 -04:00
{
2019-10-03 16:26:48 -04:00
IProvider * * FindIt = ProvidersMap . Find ( InName ) ;
2019-06-03 15:32:00 -04:00
if ( FindIt )
{
return * FindIt ;
}
else
{
return nullptr ;
}
}
FAnalysisService : : FAnalysisService ( FModuleService & InModuleService )
: ModuleService ( InModuleService )
{
}
FAnalysisService : : ~ FAnalysisService ( )
{
}
2019-11-25 12:03:09 -05:00
TSharedPtr < const IAnalysisSession > FAnalysisService : : Analyze ( const TCHAR * SessionUri )
2019-06-03 15:32:00 -04:00
{
2020-02-05 14:26:36 -05:00
TSharedPtr < const IAnalysisSession > AnalysisSession = StartAnalysis ( SessionUri ) ;
2020-01-29 08:58:49 -05:00
AnalysisSession - > Wait ( ) ;
2019-11-25 12:03:09 -05:00
return AnalysisSession ;
}
TSharedPtr < const IAnalysisSession > FAnalysisService : : StartAnalysis ( const TCHAR * SessionUri )
{
2020-02-05 14:26:36 -05:00
struct FFileDataStream
2020-11-17 06:54:28 -04:00
: public UE : : Trace : : IInDataStream
2020-02-05 14:26:36 -05:00
{
virtual int32 Read ( void * Data , uint32 Size ) override
{
if ( Remaining < = 0 )
{
return 0 ;
}
Size = ( Size < Remaining ) ? Size : Remaining ;
Remaining - = Size ;
return Handle - > Read ( ( uint8 * ) Data , Size ) ? Size : 0 ;
}
TUniquePtr < IFileHandle > Handle ;
int64 Remaining ;
} ;
IPlatformFile & FileSystem = IPlatformFile : : GetPlatformPhysical ( ) ;
IFileHandle * Handle = FileSystem . OpenRead ( SessionUri , true ) ;
if ( ! Handle )
2019-11-25 12:03:09 -05:00
{
return nullptr ;
}
2020-02-05 14:26:36 -05:00
FFileDataStream * FileStream = new FFileDataStream ( ) ;
FileStream - > Handle = TUniquePtr < IFileHandle > ( Handle ) ;
FileStream - > Remaining = Handle - > Size ( ) ;
2020-11-17 06:54:28 -04:00
TUniquePtr < UE : : Trace : : IInDataStream > DataStream ( FileStream ) ;
2021-10-27 15:14:40 -04:00
return StartAnalysis ( ~ 0 , SessionUri , MoveTemp ( DataStream ) ) ;
2019-06-03 15:32:00 -04:00
}
2021-10-27 15:14:40 -04:00
TSharedPtr < const IAnalysisSession > FAnalysisService : : StartAnalysis ( uint32 TraceId , const TCHAR * SessionName , TUniquePtr < UE : : Trace : : IInDataStream > & & DataStream )
2019-06-03 15:32:00 -04:00
{
2021-10-27 15:14:40 -04:00
TSharedRef < FAnalysisSession > Session = MakeShared < FAnalysisSession > ( TraceId , SessionName , MoveTemp ( DataStream ) ) ;
2020-01-29 08:58:49 -05:00
2020-11-13 05:29:37 -04:00
FAnalysisSessionEditScope _ ( * Session ) ;
2020-01-29 08:58:49 -05:00
FBookmarkProvider * BookmarkProvider = new FBookmarkProvider ( * Session ) ;
Session - > AddProvider ( FBookmarkProvider : : ProviderName , BookmarkProvider ) ;
FLogProvider * LogProvider = new FLogProvider ( * Session ) ;
Session - > AddProvider ( FLogProvider : : ProviderName , LogProvider ) ;
FThreadProvider * ThreadProvider = new FThreadProvider ( * Session ) ;
Session - > AddProvider ( FThreadProvider : : ProviderName , ThreadProvider ) ;
FFrameProvider * FrameProvider = new FFrameProvider ( * Session ) ;
Session - > AddProvider ( FFrameProvider : : ProviderName , FrameProvider ) ;
FCounterProvider * CounterProvider = new FCounterProvider ( * Session , * FrameProvider ) ;
Session - > AddProvider ( FCounterProvider : : ProviderName , CounterProvider ) ;
FChannelProvider * ChannelProvider = new FChannelProvider ( ) ;
Session - > AddProvider ( FChannelProvider : : ProviderName , ChannelProvider ) ;
2022-03-22 12:35:42 -04:00
FScreenshotProvider * ScreenshotProvider = new FScreenshotProvider ( * Session ) ;
Session - > AddProvider ( FScreenshotProvider : : ProviderName , ScreenshotProvider ) ;
Session - > AddAnalyzer ( new FMiscTraceAnalyzer ( * Session , * ThreadProvider , * BookmarkProvider , * LogProvider , * FrameProvider , * ChannelProvider , * ScreenshotProvider ) ) ;
2020-01-29 08:58:49 -05:00
Session - > AddAnalyzer ( new FLogTraceAnalyzer ( * Session , * LogProvider ) ) ;
ModuleService . OnAnalysisBegin ( * Session ) ;
Session - > Start ( ) ;
return Session ;
2019-06-03 15:32:00 -04:00
}
2020-11-13 05:29:37 -04:00
} // namespace TraceServices