mirror of https://github.com/PCSX2/pcsx2.git
CDVD: Use ThreadedFileReader for uncompressed ISOs
This commit is contained in:
parent
f0ae33d61e
commit
29e9125b15
|
@ -53,7 +53,6 @@ else()
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
if(LINUX)
|
if(LINUX)
|
||||||
check_lib(AIO aio libaio.h)
|
|
||||||
check_lib(LIBUDEV libudev libudev.h)
|
check_lib(LIBUDEV libudev libudev.h)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,6 @@
|
||||||
|
|
||||||
#include "common/Pcsx2Defs.h"
|
#include "common/Pcsx2Defs.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include "common/RedtapeWindows.h"
|
|
||||||
#elif defined(__linux__)
|
|
||||||
#include <libaio.h>
|
|
||||||
#elif defined(__POSIX__)
|
|
||||||
#include <aio.h>
|
|
||||||
#endif
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -20,16 +13,12 @@ class Error;
|
||||||
class AsyncFileReader
|
class AsyncFileReader
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
AsyncFileReader()
|
AsyncFileReader() = default;
|
||||||
: m_dataoffset(0)
|
|
||||||
, m_blocksize(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
|
|
||||||
u32 m_dataoffset;
|
u32 m_dataoffset = 0;
|
||||||
u32 m_blocksize;
|
u32 m_blocksize = 2048;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~AsyncFileReader(){};
|
virtual ~AsyncFileReader(){};
|
||||||
|
@ -52,46 +41,3 @@ public:
|
||||||
const std::string& GetFilename() const { return m_filename; }
|
const std::string& GetFilename() const { return m_filename; }
|
||||||
u32 GetBlockSize() const { return m_blocksize; }
|
u32 GetBlockSize() const { return m_blocksize; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class FlatFileReader final : public AsyncFileReader
|
|
||||||
{
|
|
||||||
DeclareNoncopyableObject(FlatFileReader);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
HANDLE hOverlappedFile;
|
|
||||||
|
|
||||||
OVERLAPPED asyncOperationContext;
|
|
||||||
|
|
||||||
HANDLE hEvent;
|
|
||||||
|
|
||||||
bool asyncInProgress;
|
|
||||||
#elif defined(__linux__)
|
|
||||||
int m_fd; // FIXME don't know if overlap as an equivalent on linux
|
|
||||||
io_context_t m_aio_context;
|
|
||||||
#elif defined(__POSIX__)
|
|
||||||
int m_fd; // TODO OSX don't know if overlap as an equivalent on OSX
|
|
||||||
struct aiocb m_aiocb;
|
|
||||||
bool m_async_read_in_progress;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool shareWrite;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FlatFileReader(bool shareWrite = false);
|
|
||||||
~FlatFileReader() override;
|
|
||||||
|
|
||||||
bool Open(std::string filenae, Error* error) override;
|
|
||||||
|
|
||||||
int ReadSync(void* pBuffer, u32 sector, u32 count) override;
|
|
||||||
|
|
||||||
void BeginRead(void* pBuffer, u32 sector, u32 count) override;
|
|
||||||
int FinishRead() override;
|
|
||||||
void CancelRead() override;
|
|
||||||
|
|
||||||
void Close() override;
|
|
||||||
|
|
||||||
u32 GetBlockCount() const override;
|
|
||||||
|
|
||||||
void SetBlockSize(u32 bytes) override { m_blocksize = bytes; }
|
|
||||||
void SetDataOffset(u32 bytes) override { m_dataoffset = bytes; }
|
|
||||||
};
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ BlockdumpFileReader::BlockdumpFileReader() = default;
|
||||||
|
|
||||||
BlockdumpFileReader::~BlockdumpFileReader()
|
BlockdumpFileReader::~BlockdumpFileReader()
|
||||||
{
|
{
|
||||||
Close();
|
pxAssert(!m_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockdumpFileReader::Open2(std::string filename, Error* error)
|
bool BlockdumpFileReader::Open2(std::string filename, Error* error)
|
||||||
|
|
|
@ -23,6 +23,11 @@
|
||||||
|
|
||||||
#include "fmt/core.h"
|
#include "fmt/core.h"
|
||||||
|
|
||||||
|
// TODO: FIXME! Should be platform specific.
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "common/RedtapeWindows.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ENABLE_TIMESTAMPS
|
#define ENABLE_TIMESTAMPS
|
||||||
|
|
||||||
const CDVD_API* CDVD = nullptr;
|
const CDVD_API* CDVD = nullptr;
|
||||||
|
|
|
@ -18,15 +18,11 @@ static constexpr u32 MAX_PARENTS = 32; // Surely someone wouldn't be insane enou
|
||||||
static std::vector<std::pair<std::string, chd_header>> s_chd_hash_cache; // <filename, header>
|
static std::vector<std::pair<std::string, chd_header>> s_chd_hash_cache; // <filename, header>
|
||||||
static std::recursive_mutex s_chd_hash_cache_mutex;
|
static std::recursive_mutex s_chd_hash_cache_mutex;
|
||||||
|
|
||||||
ChdFileReader::ChdFileReader()
|
ChdFileReader::ChdFileReader() = default;
|
||||||
{
|
|
||||||
m_blocksize = 2048;
|
|
||||||
ChdFile = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ChdFileReader::~ChdFileReader()
|
ChdFileReader::~ChdFileReader()
|
||||||
{
|
{
|
||||||
Close();
|
pxAssert(!ChdFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
static chd_file* OpenCHD(const std::string& filename, FileSystem::ManagedCFilePtr fp, Error* error, u32 recursion_level)
|
static chd_file* OpenCHD(const std::string& filename, FileSystem::ManagedCFilePtr fp, Error* error, u32 recursion_level)
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
private:
|
private:
|
||||||
bool ParseTOC(u64* out_frame_count);
|
bool ParseTOC(u64* out_frame_count);
|
||||||
|
|
||||||
chd_file* ChdFile;
|
chd_file* ChdFile = nullptr;
|
||||||
u64 file_size;
|
u64 file_size = 0;
|
||||||
u32 hunk_size;
|
u32 hunk_size = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "AsyncFileReader.h"
|
#include "AsyncFileReader.h"
|
||||||
#include "CsoFileReader.h"
|
#include "CsoFileReader.h"
|
||||||
|
|
||||||
|
#include "common/Assertions.h"
|
||||||
#include "common/Console.h"
|
#include "common/Console.h"
|
||||||
#include "common/FileSystem.h"
|
#include "common/FileSystem.h"
|
||||||
#include "common/Error.h"
|
#include "common/Error.h"
|
||||||
|
@ -29,14 +30,11 @@ struct CsoHeader
|
||||||
|
|
||||||
static const u32 CSO_READ_BUFFER_SIZE = 256 * 1024;
|
static const u32 CSO_READ_BUFFER_SIZE = 256 * 1024;
|
||||||
|
|
||||||
CsoFileReader::CsoFileReader()
|
CsoFileReader::CsoFileReader() = default;
|
||||||
{
|
|
||||||
m_blocksize = 2048;
|
|
||||||
}
|
|
||||||
|
|
||||||
CsoFileReader::~CsoFileReader()
|
CsoFileReader::~CsoFileReader()
|
||||||
{
|
{
|
||||||
Close();
|
pxAssert(m_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CsoFileReader::ValidateHeader(const CsoHeader& hdr, Error* error)
|
bool CsoFileReader::ValidateHeader(const CsoHeader& hdr, Error* error)
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0+
|
||||||
|
|
||||||
|
#include "FlatFileReader.h"
|
||||||
|
|
||||||
|
#include "common/Assertions.h"
|
||||||
|
#include "common/Console.h"
|
||||||
|
#include "common/FileSystem.h"
|
||||||
|
#include "common/Error.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
static constexpr size_t CHUNK_SIZE = 128 * 1024;
|
||||||
|
|
||||||
|
FlatFileReader::FlatFileReader() = default;
|
||||||
|
|
||||||
|
FlatFileReader::~FlatFileReader()
|
||||||
|
{
|
||||||
|
pxAssert(!m_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FlatFileReader::Open2(std::string filename, Error* error)
|
||||||
|
{
|
||||||
|
m_filename = std::move(filename);
|
||||||
|
if (!(m_file = FileSystem::OpenCFile(m_filename.c_str(), "rb", error)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const s64 filesize = FileSystem::FSize64(m_file);
|
||||||
|
if (filesize <= 0)
|
||||||
|
{
|
||||||
|
Error::SetStringView(error, "Failed to determine file size.");
|
||||||
|
Close2();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_file_size = static_cast<u64>(filesize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadedFileReader::Chunk FlatFileReader::ChunkForOffset(u64 offset)
|
||||||
|
{
|
||||||
|
ThreadedFileReader::Chunk chunk = {};
|
||||||
|
if (offset >= m_file_size)
|
||||||
|
{
|
||||||
|
chunk.chunkID = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chunk.chunkID = offset / CHUNK_SIZE;
|
||||||
|
chunk.length = static_cast<u32>(std::min<u64>(m_file_size - offset, CHUNK_SIZE));
|
||||||
|
chunk.offset = static_cast<u64>(chunk.chunkID) * CHUNK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FlatFileReader::ReadChunk(void* dst, s64 blockID)
|
||||||
|
{
|
||||||
|
if (blockID < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const u64 file_offset = static_cast<u64>(blockID) * CHUNK_SIZE;
|
||||||
|
if (FileSystem::FSeek64(m_file, file_offset, SEEK_SET) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const u32 read_size = static_cast<u32>(std::min<u64>(m_file_size - file_offset, CHUNK_SIZE));
|
||||||
|
|
||||||
|
return (std::fread(dst, read_size, 1, m_file) == 1) ? static_cast<int>(read_size) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlatFileReader::Close2()
|
||||||
|
{
|
||||||
|
if (!m_file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::fclose(m_file);
|
||||||
|
m_file = nullptr;
|
||||||
|
m_file_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 FlatFileReader::GetBlockCount() const
|
||||||
|
{
|
||||||
|
return static_cast<u32>(m_file_size / m_blocksize);
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0+
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CDVD/ThreadedFileReader.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
class FlatFileReader final : public ThreadedFileReader
|
||||||
|
{
|
||||||
|
DeclareNoncopyableObject(FlatFileReader);
|
||||||
|
|
||||||
|
std::FILE* m_file = nullptr;
|
||||||
|
u64 m_file_size = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FlatFileReader();
|
||||||
|
~FlatFileReader() override;
|
||||||
|
|
||||||
|
bool Open2(std::string filename, Error* error) override;
|
||||||
|
|
||||||
|
Chunk ChunkForOffset(u64 offset) override;
|
||||||
|
int ReadChunk(void* dst, s64 blockID) override;
|
||||||
|
|
||||||
|
void Close2() override;
|
||||||
|
|
||||||
|
u32 GetBlockCount() const override;
|
||||||
|
};
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0+
|
// SPDX-License-Identifier: LGPL-3.0+
|
||||||
|
|
||||||
#include "CDVD/BlockdumpFileReader.h"
|
#include "CDVD/BlockdumpFileReader.h"
|
||||||
|
#include "CDVD/FlatFileReader.h"
|
||||||
#include "CDVD/IsoFileFormats.h"
|
#include "CDVD/IsoFileFormats.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Host.h"
|
#include "Host.h"
|
||||||
|
@ -203,16 +204,11 @@ bool InputIsoFile::Open(std::string srcfile, Error* error, bool testOnly)
|
||||||
|
|
||||||
// First try using a compressed reader. If it works, go with it.
|
// First try using a compressed reader. If it works, go with it.
|
||||||
m_reader = CompressedFileReader::GetNewReader(m_filename);
|
m_reader = CompressedFileReader::GetNewReader(m_filename);
|
||||||
isCompressed = m_reader != NULL;
|
isCompressed = m_reader != nullptr;
|
||||||
|
|
||||||
// If it wasn't compressed, let's open it has a FlatFileReader.
|
// If it wasn't compressed, let's open it has a FlatFileReader.
|
||||||
if (!isCompressed)
|
if (!isCompressed)
|
||||||
{
|
m_reader = new FlatFileReader();
|
||||||
// Allow write sharing of the iso based on the ini settings.
|
|
||||||
// Mostly useful for romhacking, where the disc is frequently
|
|
||||||
// changed and the emulator would block modifications
|
|
||||||
m_reader = new FlatFileReader(EmuConfig.CdvdShareWrite);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_reader->Open(m_filename, error))
|
if (!m_reader->Open(m_filename, error))
|
||||||
return false;
|
return false;
|
||||||
|
@ -274,15 +270,19 @@ bool InputIsoFile::Open(std::string srcfile, Error* error, bool testOnly)
|
||||||
|
|
||||||
void InputIsoFile::Close()
|
void InputIsoFile::Close()
|
||||||
{
|
{
|
||||||
|
if (m_reader)
|
||||||
|
{
|
||||||
|
m_reader->Close();
|
||||||
delete m_reader;
|
delete m_reader;
|
||||||
m_reader = NULL;
|
m_reader = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
_init();
|
_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputIsoFile::IsOpened() const
|
bool InputIsoFile::IsOpened() const
|
||||||
{
|
{
|
||||||
return m_reader != NULL;
|
return m_reader != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputIsoFile::tryIsoType(u32 size, u32 offset, u32 blockofs)
|
bool InputIsoFile::tryIsoType(u32 size, u32 offset, u32 blockofs)
|
||||||
|
|
|
@ -211,6 +211,7 @@ set(pcsx2CDVDSources
|
||||||
CDVD/CDVDdiscReader.cpp
|
CDVD/CDVDdiscReader.cpp
|
||||||
CDVD/CDVDisoReader.cpp
|
CDVD/CDVDisoReader.cpp
|
||||||
CDVD/CDVDdiscThread.cpp
|
CDVD/CDVDdiscThread.cpp
|
||||||
|
CDVD/FlatFileReader.cpp
|
||||||
CDVD/InputIsoFile.cpp
|
CDVD/InputIsoFile.cpp
|
||||||
CDVD/IsoHasher.cpp
|
CDVD/IsoHasher.cpp
|
||||||
CDVD/IsoReader.cpp
|
CDVD/IsoReader.cpp
|
||||||
|
@ -235,6 +236,7 @@ set(pcsx2CDVDHeaders
|
||||||
CDVD/CompressedFileReader.h
|
CDVD/CompressedFileReader.h
|
||||||
CDVD/ChdFileReader.h
|
CDVD/ChdFileReader.h
|
||||||
CDVD/CsoFileReader.h
|
CDVD/CsoFileReader.h
|
||||||
|
CDVD/FlatFileReader.h
|
||||||
CDVD/GzippedFileReader.h
|
CDVD/GzippedFileReader.h
|
||||||
CDVD/ThreadedFileReader.h
|
CDVD/ThreadedFileReader.h
|
||||||
CDVD/IsoFileFormats.h
|
CDVD/IsoFileFormats.h
|
||||||
|
@ -852,19 +854,16 @@ endif()
|
||||||
set(pcsx2LinuxSources
|
set(pcsx2LinuxSources
|
||||||
CDVD/Linux/DriveUtility.cpp
|
CDVD/Linux/DriveUtility.cpp
|
||||||
CDVD/Linux/IOCtlSrc.cpp
|
CDVD/Linux/IOCtlSrc.cpp
|
||||||
Linux/LnxFlatFileReader.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(pcsx2OSXSources
|
set(pcsx2OSXSources
|
||||||
CDVD/Darwin/DriveUtility.cpp
|
CDVD/Darwin/DriveUtility.cpp
|
||||||
CDVD/Darwin/IOCtlSrc.cpp
|
CDVD/Darwin/IOCtlSrc.cpp
|
||||||
Darwin/DarwinFlatFileReader.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(pcsx2FreeBSDSources
|
set(pcsx2FreeBSDSources
|
||||||
CDVD/Darwin/DriveUtility.cpp
|
CDVD/Darwin/DriveUtility.cpp
|
||||||
CDVD/Darwin/IOCtlSrc.cpp
|
CDVD/Darwin/IOCtlSrc.cpp
|
||||||
Darwin/DarwinFlatFileReader.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Linux headers
|
# Linux headers
|
||||||
|
@ -931,7 +930,6 @@ set(pcsx2RecordingHeaders
|
||||||
set(pcsx2WindowsSources
|
set(pcsx2WindowsSources
|
||||||
CDVD/Windows/DriveUtility.cpp
|
CDVD/Windows/DriveUtility.cpp
|
||||||
CDVD/Windows/IOCtlSrc.cpp
|
CDVD/Windows/IOCtlSrc.cpp
|
||||||
windows/FlatFileReaderWindows.cpp
|
|
||||||
windows/Optimus.cpp
|
windows/Optimus.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1065,7 +1063,6 @@ if(LINUX)
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(PCSX2_FLAGS INTERFACE
|
target_link_libraries(PCSX2_FLAGS INTERFACE
|
||||||
PkgConfig::AIO
|
|
||||||
PkgConfig::LIBUDEV
|
PkgConfig::LIBUDEV
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1110,7 +1110,6 @@ struct Pcsx2Config
|
||||||
bool
|
bool
|
||||||
CdvdVerboseReads : 1, // enables cdvd read activity verbosely dumped to the console
|
CdvdVerboseReads : 1, // enables cdvd read activity verbosely dumped to the console
|
||||||
CdvdDumpBlocks : 1, // enables cdvd block dumping
|
CdvdDumpBlocks : 1, // enables cdvd block dumping
|
||||||
CdvdShareWrite : 1, // allows the iso to be modified while it's loaded
|
|
||||||
EnablePatches : 1, // enables patch detection and application
|
EnablePatches : 1, // enables patch detection and application
|
||||||
EnableCheats : 1, // enables cheat detection and application
|
EnableCheats : 1, // enables cheat detection and application
|
||||||
EnablePINE : 1, // enables inter-process communication
|
EnablePINE : 1, // enables inter-process communication
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
|
|
||||||
// SPDX-License-Identifier: LGPL-3.0+
|
|
||||||
|
|
||||||
#include "AsyncFileReader.h"
|
|
||||||
|
|
||||||
#include "common/Console.h"
|
|
||||||
#include "common/FileSystem.h"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
// The aio module has been reported to cause issues with FreeBSD 10.3, so let's
|
|
||||||
// disable it for 10.3 and earlier and hope FreeBSD 11 and onwards is fine.
|
|
||||||
// Note: It may be worth checking whether aio provides any performance benefit.
|
|
||||||
#if defined(__FreeBSD__) && __FreeBSD__ < 11
|
|
||||||
#define DISABLE_AIO
|
|
||||||
#warning AIO has been disabled.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FlatFileReader::FlatFileReader(bool shareWrite)
|
|
||||||
: shareWrite(shareWrite)
|
|
||||||
{
|
|
||||||
m_blocksize = 2048;
|
|
||||||
m_fd = -1;
|
|
||||||
m_async_read_in_progress = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FlatFileReader::~FlatFileReader()
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FlatFileReader::Open(std::string filename, Error* error)
|
|
||||||
{
|
|
||||||
m_filename = std::move(filename);
|
|
||||||
|
|
||||||
m_fd = FileSystem::OpenFDFile(m_filename.c_str(), O_RDONLY, 0, error);
|
|
||||||
|
|
||||||
return (m_fd != -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FlatFileReader::ReadSync(void* pBuffer, u32 sector, u32 count)
|
|
||||||
{
|
|
||||||
BeginRead(pBuffer, sector, count);
|
|
||||||
return FinishRead();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlatFileReader::BeginRead(void* pBuffer, u32 sector, u32 count)
|
|
||||||
{
|
|
||||||
u64 offset = sector * (u64)m_blocksize + m_dataoffset;
|
|
||||||
|
|
||||||
u32 bytesToRead = count * m_blocksize;
|
|
||||||
|
|
||||||
m_async_read_in_progress = false;
|
|
||||||
#ifndef DISABLE_AIO
|
|
||||||
m_aiocb = {0};
|
|
||||||
m_aiocb.aio_fildes = m_fd;
|
|
||||||
m_aiocb.aio_offset = offset;
|
|
||||||
m_aiocb.aio_nbytes = bytesToRead;
|
|
||||||
m_aiocb.aio_buf = pBuffer;
|
|
||||||
|
|
||||||
if (aio_read(&m_aiocb) == 0)
|
|
||||||
{
|
|
||||||
m_async_read_in_progress = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
#if defined(__FreeBSD__)
|
|
||||||
case ENOSYS:
|
|
||||||
Console.Error("AIO read failed: Check the aio kernel module is loaded");
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case EAGAIN:
|
|
||||||
Console.Warning("AIO read failed: Out of resources. Will read synchronously");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Console.Error("AIO read failed: error code %d\n", errno);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!m_async_read_in_progress)
|
|
||||||
{
|
|
||||||
m_aiocb.aio_nbytes = pread(m_fd, pBuffer, bytesToRead, offset);
|
|
||||||
if (m_aiocb.aio_nbytes != bytesToRead)
|
|
||||||
m_aiocb.aio_nbytes = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int FlatFileReader::FinishRead()
|
|
||||||
{
|
|
||||||
if (!m_async_read_in_progress)
|
|
||||||
return m_aiocb.aio_nbytes == (size_t)-1 ? -1 : 1;
|
|
||||||
m_async_read_in_progress = true;
|
|
||||||
|
|
||||||
struct aiocb* aiocb_list[] = {&m_aiocb};
|
|
||||||
|
|
||||||
while (aio_suspend(aiocb_list, 1, nullptr) == -1 && errno == EINTR)
|
|
||||||
;
|
|
||||||
return aio_return(&m_aiocb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlatFileReader::CancelRead()
|
|
||||||
{
|
|
||||||
if (m_async_read_in_progress)
|
|
||||||
{
|
|
||||||
aio_cancel(m_fd, &m_aiocb);
|
|
||||||
m_async_read_in_progress = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlatFileReader::Close()
|
|
||||||
{
|
|
||||||
CancelRead();
|
|
||||||
if (m_fd != -1)
|
|
||||||
close(m_fd);
|
|
||||||
|
|
||||||
m_fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 FlatFileReader::GetBlockCount() const
|
|
||||||
{
|
|
||||||
return static_cast<u32>(FileSystem::GetPathFileSize(m_filename.c_str()) / m_blocksize);
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
|
|
||||||
// SPDX-License-Identifier: LGPL-3.0+
|
|
||||||
|
|
||||||
#include "AsyncFileReader.h"
|
|
||||||
|
|
||||||
#include "common/FileSystem.h"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
FlatFileReader::FlatFileReader(bool shareWrite)
|
|
||||||
: shareWrite(shareWrite)
|
|
||||||
{
|
|
||||||
m_blocksize = 2048;
|
|
||||||
m_fd = -1;
|
|
||||||
m_aio_context = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
FlatFileReader::~FlatFileReader()
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FlatFileReader::Open(std::string filename, Error* error)
|
|
||||||
{
|
|
||||||
m_filename = std::move(filename);
|
|
||||||
|
|
||||||
int err = io_setup(64, &m_aio_context);
|
|
||||||
if (err)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_fd = FileSystem::OpenFDFile(m_filename.c_str(), O_RDONLY, 0, error);
|
|
||||||
|
|
||||||
return (m_fd != -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FlatFileReader::ReadSync(void* pBuffer, u32 sector, u32 count)
|
|
||||||
{
|
|
||||||
BeginRead(pBuffer, sector, count);
|
|
||||||
return FinishRead();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlatFileReader::BeginRead(void* pBuffer, u32 sector, u32 count)
|
|
||||||
{
|
|
||||||
u64 offset;
|
|
||||||
offset = sector * (s64)m_blocksize + m_dataoffset;
|
|
||||||
|
|
||||||
u32 bytesToRead = count * m_blocksize;
|
|
||||||
|
|
||||||
struct iocb iocb;
|
|
||||||
struct iocb* iocbs = &iocb;
|
|
||||||
|
|
||||||
io_prep_pread(&iocb, m_fd, pBuffer, bytesToRead, offset);
|
|
||||||
io_submit(m_aio_context, 1, &iocbs);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FlatFileReader::FinishRead()
|
|
||||||
{
|
|
||||||
struct io_event event;
|
|
||||||
|
|
||||||
int nevents = io_getevents(m_aio_context, 1, 1, &event, NULL);
|
|
||||||
if (nevents < 1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return event.res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlatFileReader::CancelRead()
|
|
||||||
{
|
|
||||||
// Will be done when m_aio_context context is destroyed
|
|
||||||
// Note: io_cancel exists but need the iocb structure as parameter
|
|
||||||
// int io_cancel(aio_context_t ctx_id, struct iocb *iocb,
|
|
||||||
// struct io_event *result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlatFileReader::Close()
|
|
||||||
{
|
|
||||||
if (m_fd != -1)
|
|
||||||
close(m_fd);
|
|
||||||
|
|
||||||
io_destroy(m_aio_context);
|
|
||||||
|
|
||||||
m_fd = -1;
|
|
||||||
m_aio_context = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 FlatFileReader::GetBlockCount() const
|
|
||||||
{
|
|
||||||
struct stat sysStatData;
|
|
||||||
if (fstat(m_fd, &sysStatData) < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return static_cast<u32>(sysStatData.st_size / m_blocksize);
|
|
||||||
}
|
|
|
@ -1709,7 +1709,6 @@ void Pcsx2Config::LoadSaveCore(SettingsWrapper& wrap)
|
||||||
|
|
||||||
SettingsWrapBitBool(CdvdVerboseReads);
|
SettingsWrapBitBool(CdvdVerboseReads);
|
||||||
SettingsWrapBitBool(CdvdDumpBlocks);
|
SettingsWrapBitBool(CdvdDumpBlocks);
|
||||||
SettingsWrapBitBool(CdvdShareWrite);
|
|
||||||
SettingsWrapBitBool(EnablePatches);
|
SettingsWrapBitBool(EnablePatches);
|
||||||
SettingsWrapBitBool(EnableCheats);
|
SettingsWrapBitBool(EnableCheats);
|
||||||
SettingsWrapBitBool(EnablePINE);
|
SettingsWrapBitBool(EnablePINE);
|
||||||
|
|
|
@ -115,6 +115,7 @@
|
||||||
<ClCompile Include="CDVD\ChunksCache.cpp" />
|
<ClCompile Include="CDVD\ChunksCache.cpp" />
|
||||||
<ClCompile Include="CDVD\CompressedFileReader.cpp" />
|
<ClCompile Include="CDVD\CompressedFileReader.cpp" />
|
||||||
<ClCompile Include="CDVD\CsoFileReader.cpp" />
|
<ClCompile Include="CDVD\CsoFileReader.cpp" />
|
||||||
|
<ClCompile Include="CDVD\FlatFileReader.cpp" />
|
||||||
<ClCompile Include="CDVD\GzippedFileReader.cpp" />
|
<ClCompile Include="CDVD\GzippedFileReader.cpp" />
|
||||||
<ClCompile Include="CDVD\IsoReader.cpp" />
|
<ClCompile Include="CDVD\IsoReader.cpp" />
|
||||||
<ClCompile Include="CDVD\IsoHasher.cpp" />
|
<ClCompile Include="CDVD\IsoHasher.cpp" />
|
||||||
|
@ -345,10 +346,6 @@
|
||||||
<ClCompile Include="VMManager.cpp" />
|
<ClCompile Include="VMManager.cpp" />
|
||||||
<ClCompile Include="windows\Optimus.cpp" />
|
<ClCompile Include="windows\Optimus.cpp" />
|
||||||
<ClCompile Include="Pcsx2Config.cpp" />
|
<ClCompile Include="Pcsx2Config.cpp" />
|
||||||
<ClCompile Include="windows\FlatFileReaderWindows.cpp" />
|
|
||||||
<ClCompile Include="Darwin\DarwinFlatFileReader.cpp">
|
|
||||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="SaveState.cpp" />
|
<ClCompile Include="SaveState.cpp" />
|
||||||
<ClCompile Include="SourceLog.cpp" />
|
<ClCompile Include="SourceLog.cpp" />
|
||||||
<ClCompile Include="Elfheader.cpp" />
|
<ClCompile Include="Elfheader.cpp" />
|
||||||
|
@ -472,6 +469,7 @@
|
||||||
<ClInclude Include="CDVD\CompressedFileReaderUtils.h" />
|
<ClInclude Include="CDVD\CompressedFileReaderUtils.h" />
|
||||||
<ClInclude Include="CDVD\CsoFileReader.h" />
|
<ClInclude Include="CDVD\CsoFileReader.h" />
|
||||||
<ClInclude Include="CDVD\ChdFileReader.h" />
|
<ClInclude Include="CDVD\ChdFileReader.h" />
|
||||||
|
<ClInclude Include="CDVD\FlatFileReader.h" />
|
||||||
<ClInclude Include="CDVD\GzippedFileReader.h" />
|
<ClInclude Include="CDVD\GzippedFileReader.h" />
|
||||||
<ClInclude Include="CDVD\IsoReader.h" />
|
<ClInclude Include="CDVD\IsoReader.h" />
|
||||||
<ClInclude Include="CDVD\IsoHasher.h" />
|
<ClInclude Include="CDVD\IsoHasher.h" />
|
||||||
|
|
|
@ -713,12 +713,6 @@
|
||||||
<ClCompile Include="Gif_Logger.cpp">
|
<ClCompile Include="Gif_Logger.cpp">
|
||||||
<Filter>System\Ps2\GS</Filter>
|
<Filter>System\Ps2\GS</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="windows\FlatFileReaderWindows.cpp">
|
|
||||||
<Filter>System\ISO</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Darwin\DarwinFlatFileReader.cpp">
|
|
||||||
<Filter>System\ISO</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="CDVD\InputIsoFile.cpp">
|
<ClCompile Include="CDVD\InputIsoFile.cpp">
|
||||||
<Filter>System\ISO</Filter>
|
<Filter>System\ISO</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -1404,6 +1398,9 @@
|
||||||
<ClCompile Include="Host\CubebAudioStream.cpp">
|
<ClCompile Include="Host\CubebAudioStream.cpp">
|
||||||
<Filter>Misc\Host</Filter>
|
<Filter>Misc\Host</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="CDVD\FlatFileReader.cpp">
|
||||||
|
<Filter>System\ISO</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Patch.h">
|
<ClInclude Include="Patch.h">
|
||||||
|
@ -2321,6 +2318,9 @@
|
||||||
<ClInclude Include="CDVD\BlockdumpFileReader.h">
|
<ClInclude Include="CDVD\BlockdumpFileReader.h">
|
||||||
<Filter>System\ISO</Filter>
|
<Filter>System\ISO</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="CDVD\FlatFileReader.h">
|
||||||
|
<Filter>System\ISO</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuildStep Include="rdebug\deci2.h">
|
<CustomBuildStep Include="rdebug\deci2.h">
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
|
|
||||||
// SPDX-License-Identifier: LGPL-3.0+
|
|
||||||
|
|
||||||
#include "AsyncFileReader.h"
|
|
||||||
|
|
||||||
#include "common/FileSystem.h"
|
|
||||||
#include "common/Error.h"
|
|
||||||
|
|
||||||
FlatFileReader::FlatFileReader(bool shareWrite) : shareWrite(shareWrite)
|
|
||||||
{
|
|
||||||
m_blocksize = 2048;
|
|
||||||
hOverlappedFile = INVALID_HANDLE_VALUE;
|
|
||||||
hEvent = INVALID_HANDLE_VALUE;
|
|
||||||
asyncInProgress = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FlatFileReader::~FlatFileReader()
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FlatFileReader::Open(std::string filename, Error* error)
|
|
||||||
{
|
|
||||||
m_filename = std::move(filename);
|
|
||||||
|
|
||||||
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
||||||
|
|
||||||
DWORD shareMode = FILE_SHARE_READ;
|
|
||||||
if (shareWrite)
|
|
||||||
shareMode |= FILE_SHARE_WRITE;
|
|
||||||
|
|
||||||
hOverlappedFile = CreateFile(
|
|
||||||
FileSystem::GetWin32Path(m_filename).c_str(),
|
|
||||||
GENERIC_READ,
|
|
||||||
shareMode,
|
|
||||||
NULL,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (hOverlappedFile == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
Error::SetWin32(error, GetLastError());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FlatFileReader::ReadSync(void* pBuffer, u32 sector, u32 count)
|
|
||||||
{
|
|
||||||
//LARGE_INTEGER offset;
|
|
||||||
//offset.QuadPart = sector * (__int64)m_blocksize;
|
|
||||||
//
|
|
||||||
//DWORD bytesToRead = count * m_blocksize;
|
|
||||||
//DWORD bytes;
|
|
||||||
|
|
||||||
//if(!ReadFile(hOverlappedFile, pBuffer, bytesToRead, &bytes, NULL))
|
|
||||||
// return -1;
|
|
||||||
|
|
||||||
//return bytes;
|
|
||||||
BeginRead(pBuffer, sector, count);
|
|
||||||
return FinishRead();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlatFileReader::BeginRead(void* pBuffer, u32 sector, u32 count)
|
|
||||||
{
|
|
||||||
LARGE_INTEGER offset;
|
|
||||||
offset.QuadPart = sector * (s64)m_blocksize + m_dataoffset;
|
|
||||||
|
|
||||||
DWORD bytesToRead = count * m_blocksize;
|
|
||||||
|
|
||||||
ZeroMemory(&asyncOperationContext, sizeof(asyncOperationContext));
|
|
||||||
asyncOperationContext.hEvent = hEvent;
|
|
||||||
asyncOperationContext.Offset = offset.LowPart;
|
|
||||||
asyncOperationContext.OffsetHigh = offset.HighPart;
|
|
||||||
|
|
||||||
ReadFile(hOverlappedFile, pBuffer, bytesToRead, NULL, &asyncOperationContext);
|
|
||||||
asyncInProgress = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FlatFileReader::FinishRead()
|
|
||||||
{
|
|
||||||
DWORD bytes;
|
|
||||||
|
|
||||||
if(!GetOverlappedResult(hOverlappedFile, &asyncOperationContext, &bytes, TRUE))
|
|
||||||
{
|
|
||||||
asyncInProgress = false;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
asyncInProgress = false;
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlatFileReader::CancelRead()
|
|
||||||
{
|
|
||||||
CancelIo(hOverlappedFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlatFileReader::Close()
|
|
||||||
{
|
|
||||||
if(asyncInProgress)
|
|
||||||
CancelRead();
|
|
||||||
|
|
||||||
if(hOverlappedFile != INVALID_HANDLE_VALUE)
|
|
||||||
CloseHandle(hOverlappedFile);
|
|
||||||
|
|
||||||
if(hEvent != INVALID_HANDLE_VALUE)
|
|
||||||
CloseHandle(hEvent);
|
|
||||||
|
|
||||||
hOverlappedFile = INVALID_HANDLE_VALUE;
|
|
||||||
hEvent = INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 FlatFileReader::GetBlockCount(void) const
|
|
||||||
{
|
|
||||||
LARGE_INTEGER fileSize;
|
|
||||||
fileSize.LowPart = GetFileSize(hOverlappedFile, reinterpret_cast<DWORD*>(&fileSize.HighPart));
|
|
||||||
|
|
||||||
return static_cast<u32>(fileSize.QuadPart / m_blocksize);
|
|
||||||
}
|
|
Loading…
Reference in New Issue