2020-01-07 17:07:47 -05:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
2019-12-13 11:07:03 -05:00
|
|
|
|
|
|
|
|
#include "GenericPlatformIoDispatcher.h"
|
2021-12-15 03:24:48 -05:00
|
|
|
#include "IoDispatcherFileBackend.h"
|
2019-12-13 11:07:03 -05:00
|
|
|
#include "Async/AsyncFileHandle.h"
|
|
|
|
|
#include "HAL/Event.h"
|
2020-05-06 17:58:18 -04:00
|
|
|
#include "HAL/PlatformFileManager.h"
|
2020-01-28 06:54:05 -05:00
|
|
|
#include "HAL/RunnableThread.h"
|
2020-04-01 05:00:26 -04:00
|
|
|
#include "HAL/IConsoleManager.h"
|
2020-02-07 14:04:54 -05:00
|
|
|
#include "Misc/ScopeLock.h"
|
2020-01-28 06:54:05 -05:00
|
|
|
|
|
|
|
|
//PRAGMA_DISABLE_OPTIMIZATION
|
|
|
|
|
|
2019-12-13 11:07:03 -05:00
|
|
|
|
2021-06-15 16:38:03 -04:00
|
|
|
TRACE_DECLARE_INT_COUNTER_EXTERN(IoDispatcherFileBackendSequentialReads);
|
|
|
|
|
TRACE_DECLARE_INT_COUNTER_EXTERN(IoDispatcherFileBackendForwardSeeks);
|
|
|
|
|
TRACE_DECLARE_INT_COUNTER_EXTERN(IoDispatcherFileBackendBackwardSeeks);
|
|
|
|
|
TRACE_DECLARE_INT_COUNTER_EXTERN(IoDispatcherFileBackendSwitchContainerSeeks);
|
|
|
|
|
TRACE_DECLARE_MEMORY_COUNTER_EXTERN(IoDispatcherFileBackendTotalSeekDistance);
|
|
|
|
|
TRACE_DECLARE_INT_COUNTER_EXTERN(IoDispatcherFileBackendFileSystemRequests);
|
|
|
|
|
TRACE_DECLARE_MEMORY_COUNTER_EXTERN(IoDispatcherFileBackendFileSystemTotalBytesRead);
|
|
|
|
|
|
2021-01-19 04:39:56 -04:00
|
|
|
FGenericFileIoStoreEventQueue::FGenericFileIoStoreEventQueue()
|
|
|
|
|
: ServiceEvent(FPlatformProcess::GetSynchEventFromPool())
|
2019-12-13 11:07:03 -05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-19 04:39:56 -04:00
|
|
|
FGenericFileIoStoreEventQueue::~FGenericFileIoStoreEventQueue()
|
2019-12-13 11:07:03 -05:00
|
|
|
{
|
2020-09-01 14:07:48 -04:00
|
|
|
FPlatformProcess::ReturnSynchEventToPool(ServiceEvent);
|
2019-12-13 11:07:03 -05:00
|
|
|
}
|
|
|
|
|
|
2021-01-19 04:39:56 -04:00
|
|
|
void FGenericFileIoStoreEventQueue::ServiceNotify()
|
2020-09-01 14:07:48 -04:00
|
|
|
{
|
|
|
|
|
ServiceEvent->Trigger();
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-19 04:39:56 -04:00
|
|
|
void FGenericFileIoStoreEventQueue::ServiceWait()
|
2020-09-01 14:07:48 -04:00
|
|
|
{
|
|
|
|
|
ServiceEvent->Wait();
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-15 02:54:32 -04:00
|
|
|
FGenericFileIoStoreImpl::FGenericFileIoStoreImpl()
|
2019-12-13 11:07:03 -05:00
|
|
|
{
|
2020-01-28 06:54:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FGenericFileIoStoreImpl::~FGenericFileIoStoreImpl()
|
|
|
|
|
{
|
2019-12-13 11:07:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool FGenericFileIoStoreImpl::OpenContainer(const TCHAR* ContainerFilePath, uint64& ContainerFileHandle, uint64& ContainerFileSize)
|
|
|
|
|
{
|
2020-09-01 14:07:48 -04:00
|
|
|
IPlatformFile& Ipf = IPlatformFile::GetPlatformPhysical();
|
|
|
|
|
int64 FileSize = Ipf.FileSize(ContainerFilePath);
|
|
|
|
|
if (FileSize < 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-01-28 06:54:05 -05:00
|
|
|
IFileHandle* FileHandle = Ipf.OpenReadNoBuffering(ContainerFilePath);
|
2019-12-13 11:07:03 -05:00
|
|
|
if (!FileHandle)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-01-28 06:54:05 -05:00
|
|
|
ContainerFileHandle = reinterpret_cast<UPTRINT>(FileHandle);
|
2020-09-01 14:07:48 -04:00
|
|
|
ContainerFileSize = uint64(FileSize);
|
2020-01-17 03:29:28 -05:00
|
|
|
return true;
|
2019-12-13 11:07:03 -05:00
|
|
|
}
|
|
|
|
|
|
2021-04-29 19:32:06 -04:00
|
|
|
void FGenericFileIoStoreImpl::CloseContainer(uint64 ContainerFileHandle)
|
|
|
|
|
{
|
|
|
|
|
check(ContainerFileHandle);
|
|
|
|
|
IFileHandle* FileHandle = reinterpret_cast<IFileHandle*>(ContainerFileHandle);
|
|
|
|
|
delete FileHandle;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-01 14:07:48 -04:00
|
|
|
bool FGenericFileIoStoreImpl::StartRequests(FFileIoStoreRequestQueue& RequestQueue)
|
2019-12-13 11:07:03 -05:00
|
|
|
{
|
2022-10-18 07:55:38 -04:00
|
|
|
if (!AcquiredBuffer)
|
|
|
|
|
{
|
|
|
|
|
AcquiredBuffer = BufferAllocator->AllocBuffer();
|
|
|
|
|
if (!AcquiredBuffer)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-24 18:42:39 -04:00
|
|
|
FFileIoStoreReadRequest* NextRequest = RequestQueue.Pop();
|
2020-09-01 14:07:48 -04:00
|
|
|
if (!NextRequest)
|
2019-12-13 11:07:03 -05:00
|
|
|
{
|
2020-09-01 14:07:48 -04:00
|
|
|
return false;
|
2019-12-13 11:07:03 -05:00
|
|
|
}
|
|
|
|
|
|
2022-10-18 07:55:38 -04:00
|
|
|
if (NextRequest->bCancelled | NextRequest->bFailed)
|
2020-12-11 14:21:20 -04:00
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
FScopeLock _(&CompletedRequestsCritical);
|
|
|
|
|
CompletedRequests.Add(NextRequest);
|
|
|
|
|
}
|
2021-01-19 04:39:56 -04:00
|
|
|
WakeUpDispatcherThreadDelegate->Execute();
|
2020-12-11 14:21:20 -04:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-01 14:07:48 -04:00
|
|
|
uint8* Dest;
|
2021-08-23 10:49:29 -04:00
|
|
|
check(!NextRequest->ImmediateScatter.Request);
|
2022-10-18 07:55:38 -04:00
|
|
|
|
|
|
|
|
NextRequest->Buffer = AcquiredBuffer;
|
|
|
|
|
AcquiredBuffer = nullptr;
|
2021-08-23 10:49:29 -04:00
|
|
|
Dest = NextRequest->Buffer->Memory;
|
|
|
|
|
|
2021-09-15 02:54:32 -04:00
|
|
|
if (!BlockCache->Read(NextRequest))
|
2020-09-01 14:07:48 -04:00
|
|
|
{
|
2022-10-18 07:55:38 -04:00
|
|
|
IFileHandle* FileHandle = reinterpret_cast<IFileHandle*>(static_cast<UPTRINT>(NextRequest->ContainerFilePartition->FileHandle));
|
2021-05-31 16:31:24 -04:00
|
|
|
|
2021-11-22 16:44:27 -05:00
|
|
|
Stats->OnFilesystemReadStarted(NextRequest);
|
2020-04-01 05:00:26 -04:00
|
|
|
{
|
2020-09-01 14:07:48 -04:00
|
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(ReadBlockFromFile);
|
2020-09-24 00:43:27 -04:00
|
|
|
NextRequest->bFailed = true;
|
|
|
|
|
int32 RetryCount = 0;
|
|
|
|
|
while (RetryCount++ < 10)
|
|
|
|
|
{
|
|
|
|
|
if (!FileHandle->Seek(NextRequest->Offset))
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(LogIoDispatcher, Warning, TEXT("Failed seeking to offset %lld (Retries: %d)"), NextRequest->Offset, (RetryCount - 1));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (!FileHandle->Read(Dest, NextRequest->Size))
|
|
|
|
|
{
|
|
|
|
|
UE_LOG(LogIoDispatcher, Warning, TEXT("Failed reading %lld bytes at offset %lld (Retries: %d)"), NextRequest->Size, NextRequest->Offset, (RetryCount - 1));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
NextRequest->bFailed = false;
|
2021-11-22 16:44:27 -05:00
|
|
|
Stats->OnFilesystemReadCompleted(NextRequest);
|
2021-09-15 02:54:32 -04:00
|
|
|
BlockCache->Store(NextRequest);
|
2020-09-24 00:43:27 -04:00
|
|
|
break;
|
|
|
|
|
}
|
2020-01-28 06:54:05 -05:00
|
|
|
}
|
|
|
|
|
}
|
2020-04-01 05:00:26 -04:00
|
|
|
{
|
2020-09-01 14:07:48 -04:00
|
|
|
FScopeLock _(&CompletedRequestsCritical);
|
|
|
|
|
CompletedRequests.Add(NextRequest);
|
2020-04-01 05:00:26 -04:00
|
|
|
}
|
2021-01-19 04:39:56 -04:00
|
|
|
WakeUpDispatcherThreadDelegate->Execute();
|
2020-09-01 14:07:48 -04:00
|
|
|
return true;
|
2020-04-01 05:00:26 -04:00
|
|
|
}
|
|
|
|
|
|
2020-09-01 14:07:48 -04:00
|
|
|
void FGenericFileIoStoreImpl::GetCompletedRequests(FFileIoStoreReadRequestList& OutRequests)
|
2020-04-01 05:00:26 -04:00
|
|
|
{
|
2020-09-01 14:07:48 -04:00
|
|
|
FScopeLock _(&CompletedRequestsCritical);
|
2021-05-25 02:43:26 -04:00
|
|
|
OutRequests.AppendSteal(CompletedRequests);
|
2020-01-28 06:54:05 -05:00
|
|
|
}
|