From 65c7d0bd04f5197ebedbccd57b3b9e1f169f290f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 26 Jun 2016 23:20:05 -0700 Subject: [PATCH] Add uncached flag for file loader reads. This allows us to indicate that a read need not be cached. --- Core/FileLoaders/CachingFileLoader.cpp | 38 +++++++++++++--------- Core/FileLoaders/CachingFileLoader.h | 30 ++++++++--------- Core/FileLoaders/DiskCachingFileLoader.cpp | 16 ++++----- Core/FileLoaders/DiskCachingFileLoader.h | 30 ++++++++--------- Core/FileLoaders/HTTPFileLoader.cpp | 2 +- Core/FileLoaders/HTTPFileLoader.h | 14 ++++---- Core/FileLoaders/LocalFileLoader.cpp | 4 +-- Core/FileLoaders/LocalFileLoader.h | 4 +-- Core/FileLoaders/RamCachingFileLoader.cpp | 18 +++++----- Core/FileLoaders/RamCachingFileLoader.h | 16 ++++----- Core/FileLoaders/RetryingFileLoader.cpp | 6 ++-- Core/FileLoaders/RetryingFileLoader.h | 28 ++++++++-------- Core/FileSystems/BlockDevices.cpp | 17 ++++++---- Core/FileSystems/BlockDevices.h | 8 ++--- Core/Loaders.h | 22 +++++++++---- 15 files changed, 136 insertions(+), 117 deletions(-) diff --git a/Core/FileLoaders/CachingFileLoader.cpp b/Core/FileLoaders/CachingFileLoader.cpp index 1c46c99dbb..1b9e269a47 100644 --- a/Core/FileLoaders/CachingFileLoader.cpp +++ b/Core/FileLoaders/CachingFileLoader.cpp @@ -84,7 +84,7 @@ void CachingFileLoader::Seek(s64 absolutePos) { filepos_ = absolutePos; } -size_t CachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) { +size_t CachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) { Prepare(); if (absolutePos >= filesize_) { bytes = 0; @@ -92,19 +92,25 @@ size_t CachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) { bytes = filesize_ - absolutePos; } - size_t readSize = ReadFromCache(absolutePos, bytes, data); - // While in case the cache size is too small for the entire read. - while (readSize < bytes) { - SaveIntoCache(absolutePos + readSize, bytes - readSize); - size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); - readSize += bytesFromCache; - if (bytesFromCache == 0) { - // We can't read any more. - break; + size_t readSize = 0; + if ((flags & Flags::HINT_UNCACHED) != 0) { + lock_guard guard(backendMutex_); + readSize = backend_->ReadAt(absolutePos, bytes, data, flags); + } else { + readSize = ReadFromCache(absolutePos, bytes, data); + // While in case the cache size is too small for the entire read. + while (readSize < bytes) { + SaveIntoCache(absolutePos + readSize, bytes - readSize, flags); + size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); + readSize += bytesFromCache; + if (bytesFromCache == 0) { + // We can't read any more. + break; + } } - } - StartReadAhead(absolutePos + readSize); + StartReadAhead(absolutePos + readSize); + } filepos_ = absolutePos + readSize; return readSize; @@ -158,7 +164,7 @@ size_t CachingFileLoader::ReadFromCache(s64 pos, size_t bytes, void *data) { return readSize; } -void CachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, bool readingAhead) { +void CachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, Flags flags, bool readingAhead) { s64 cacheStartPos = pos >> BLOCK_SHIFT; s64 cacheEndPos = (pos + bytes - 1) >> BLOCK_SHIFT; @@ -184,7 +190,7 @@ void CachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, bool readingAhead) u8 *buf = new u8[BLOCK_SIZE]; backendMutex_.lock(); - backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, BLOCK_SIZE, buf); + backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, BLOCK_SIZE, buf, flags); backendMutex_.unlock(); blocksMutex_.lock(); @@ -200,7 +206,7 @@ void CachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, bool readingAhead) u8 *wholeRead = new u8[blocksToRead << BLOCK_SHIFT]; backendMutex_.lock(); - backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, blocksToRead << BLOCK_SHIFT, wholeRead); + backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, blocksToRead << BLOCK_SHIFT, wholeRead, flags); backendMutex_.unlock(); blocksMutex_.lock(); @@ -288,7 +294,7 @@ void CachingFileLoader::StartReadAhead(s64 pos) { auto block = blocks_.find(i); if (block == blocks_.end()) { blocksMutex_.unlock(); - SaveIntoCache(i << BLOCK_SHIFT, BLOCK_SIZE * BLOCK_READAHEAD, true); + SaveIntoCache(i << BLOCK_SHIFT, BLOCK_SIZE * BLOCK_READAHEAD, Flags::NONE, true); break; } } diff --git a/Core/FileLoaders/CachingFileLoader.h b/Core/FileLoaders/CachingFileLoader.h index e3c2cc9b4a..5ff12b2d89 100644 --- a/Core/FileLoaders/CachingFileLoader.h +++ b/Core/FileLoaders/CachingFileLoader.h @@ -25,25 +25,25 @@ class CachingFileLoader : public FileLoader { public: CachingFileLoader(FileLoader *backend); - virtual ~CachingFileLoader() override; + ~CachingFileLoader() override; - virtual bool Exists() override; - virtual bool ExistsFast() override; - virtual bool IsDirectory() override; - virtual s64 FileSize() override; - virtual std::string Path() const override; + bool Exists() override; + bool ExistsFast() override; + bool IsDirectory() override; + s64 FileSize() override; + std::string Path() const override; - virtual void Seek(s64 absolutePos) override; - virtual size_t Read(size_t bytes, size_t count, void *data) override { - return ReadAt(filepos_, bytes, count, data); + void Seek(s64 absolutePos) override; + size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { + return ReadAt(filepos_, bytes, count, data, flags); } - virtual size_t Read(size_t bytes, void *data) override { - return ReadAt(filepos_, bytes, data); + size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override { + return ReadAt(filepos_, bytes, data, flags); } - virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override { - return ReadAt(absolutePos, bytes * count, data) / bytes; + size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { + return ReadAt(absolutePos, bytes * count, data, flags) / bytes; } - virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override; + size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override; private: void Prepare(); @@ -51,7 +51,7 @@ private: void ShutdownCache(); size_t ReadFromCache(s64 pos, size_t bytes, void *data); // Guaranteed to read at least one block into the cache. - void SaveIntoCache(s64 pos, size_t bytes, bool readingAhead = false); + void SaveIntoCache(s64 pos, size_t bytes, Flags flags, bool readingAhead = false); bool MakeCacheSpaceFor(size_t blocks, bool readingAhead); void StartReadAhead(s64 pos); diff --git a/Core/FileLoaders/DiskCachingFileLoader.cpp b/Core/FileLoaders/DiskCachingFileLoader.cpp index 2efaff810c..27c512ce3f 100644 --- a/Core/FileLoaders/DiskCachingFileLoader.cpp +++ b/Core/FileLoaders/DiskCachingFileLoader.cpp @@ -89,7 +89,7 @@ void DiskCachingFileLoader::Seek(s64 absolutePos) { filepos_ = absolutePos; } -size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) { +size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) { Prepare(); size_t readSize; @@ -99,11 +99,11 @@ size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) bytes = filesize_ - absolutePos; } - if (cache_ && cache_->IsValid()) { + if (cache_ && cache_->IsValid() && (flags & Flags::HINT_UNCACHED) == 0) { readSize = cache_->ReadFromCache(absolutePos, bytes, data); // While in case the cache size is too small for the entire read. while (readSize < bytes) { - readSize += cache_->SaveIntoCache(backend_, absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); + readSize += cache_->SaveIntoCache(backend_, absolutePos + readSize, bytes - readSize, (u8 *)data + readSize, flags); // If there are already-cached blocks afterward, we have to read them. size_t bytesFromCache = cache_->ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); readSize += bytesFromCache; @@ -113,7 +113,7 @@ size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) } } } else { - readSize = backend_->ReadAt(absolutePos, bytes, data); + readSize = backend_->ReadAt(absolutePos, bytes, data, flags); } filepos_ = absolutePos + readSize; @@ -256,12 +256,12 @@ size_t DiskCachingFileLoaderCache::ReadFromCache(s64 pos, size_t bytes, void *da return readSize; } -size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, size_t bytes, void *data) { +size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, size_t bytes, void *data, FileLoader::Flags flags) { lock_guard guard(lock_); if (!f_) { // Just to keep things working. - return backend->ReadAt(pos, bytes, data); + return backend->ReadAt(pos, bytes, data, flags); } s64 cacheStartPos = pos / blockSize_; @@ -290,7 +290,7 @@ size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, s auto &info = index_[cacheStartPos]; u8 *buf = new u8[blockSize_]; - size_t readBytes = backend->ReadAt(cacheStartPos * (u64)blockSize_, blockSize_, buf); + size_t readBytes = backend->ReadAt(cacheStartPos * (u64)blockSize_, blockSize_, buf, flags); // Check if it was written while we were busy. Might happen if we thread. if (info.block == INVALID_BLOCK && readBytes != 0) { @@ -306,7 +306,7 @@ size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, s delete [] buf; } else { u8 *wholeRead = new u8[blocksToRead * blockSize_]; - size_t readBytes = backend->ReadAt(cacheStartPos * (u64)blockSize_, blocksToRead * blockSize_, wholeRead); + size_t readBytes = backend->ReadAt(cacheStartPos * (u64)blockSize_, blocksToRead * blockSize_, wholeRead, flags); for (size_t i = 0; i < blocksToRead; ++i) { auto &info = index_[cacheStartPos + i]; diff --git a/Core/FileLoaders/DiskCachingFileLoader.h b/Core/FileLoaders/DiskCachingFileLoader.h index e0ca3e9adc..8c845c8146 100644 --- a/Core/FileLoaders/DiskCachingFileLoader.h +++ b/Core/FileLoaders/DiskCachingFileLoader.h @@ -28,25 +28,25 @@ class DiskCachingFileLoaderCache; class DiskCachingFileLoader : public FileLoader { public: DiskCachingFileLoader(FileLoader *backend); - virtual ~DiskCachingFileLoader() override; + ~DiskCachingFileLoader() override; - virtual bool Exists() override; - virtual bool ExistsFast() override; - virtual bool IsDirectory() override; - virtual s64 FileSize() override; - virtual std::string Path() const override; + bool Exists() override; + bool ExistsFast() override; + bool IsDirectory() override; + s64 FileSize() override; + std::string Path() const override; - virtual void Seek(s64 absolutePos) override; - virtual size_t Read(size_t bytes, size_t count, void *data) override { - return ReadAt(filepos_, bytes, count, data); + void Seek(s64 absolutePos) override; + size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { + return ReadAt(filepos_, bytes, count, data, flags); } - virtual size_t Read(size_t bytes, void *data) override { - return ReadAt(filepos_, bytes, data); + size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override { + return ReadAt(filepos_, bytes, data, flags); } - virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override { - return ReadAt(absolutePos, bytes * count, data) / bytes; + size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { + return ReadAt(absolutePos, bytes * count, data, flags) / bytes; } - virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override; + size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override; static std::vector GetCachedPathsInUse(); @@ -90,7 +90,7 @@ public: size_t ReadFromCache(s64 pos, size_t bytes, void *data); // Guaranteed to read at least one block into the cache. - size_t SaveIntoCache(FileLoader *backend, s64 pos, size_t bytes, void *data); + size_t SaveIntoCache(FileLoader *backend, s64 pos, size_t bytes, void *data, FileLoader::Flags flags); bool HasData() const; diff --git a/Core/FileLoaders/HTTPFileLoader.cpp b/Core/FileLoaders/HTTPFileLoader.cpp index 725f6b0cad..8e51d38f40 100644 --- a/Core/FileLoaders/HTTPFileLoader.cpp +++ b/Core/FileLoaders/HTTPFileLoader.cpp @@ -123,7 +123,7 @@ void HTTPFileLoader::Seek(s64 absolutePos) { filepos_ = absolutePos; } -size_t HTTPFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) { +size_t HTTPFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) { Prepare(); s64 absoluteEnd = std::min(absolutePos + (s64)bytes, filesize_); if (absolutePos >= filesize_ || bytes == 0) { diff --git a/Core/FileLoaders/HTTPFileLoader.h b/Core/FileLoaders/HTTPFileLoader.h index 69c0ce5e50..38acb461ed 100644 --- a/Core/FileLoaders/HTTPFileLoader.h +++ b/Core/FileLoaders/HTTPFileLoader.h @@ -35,16 +35,16 @@ public: virtual std::string Path() const override; virtual void Seek(s64 absolutePos) override; - virtual size_t Read(size_t bytes, size_t count, void *data) override { - return ReadAt(filepos_, bytes, count, data); + virtual size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { + return ReadAt(filepos_, bytes, count, data, flags); } - virtual size_t Read(size_t bytes, void *data) override { - return ReadAt(filepos_, bytes, data); + virtual size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override { + return ReadAt(filepos_, bytes, data, flags); } - virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override { - return ReadAt(absolutePos, bytes * count, data) / bytes; + virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { + return ReadAt(absolutePos, bytes * count, data, flags) / bytes; } - virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override; + virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override; private: void Prepare(); diff --git a/Core/FileLoaders/LocalFileLoader.cpp b/Core/FileLoaders/LocalFileLoader.cpp index bcf3c69901..4d94918e21 100644 --- a/Core/FileLoaders/LocalFileLoader.cpp +++ b/Core/FileLoaders/LocalFileLoader.cpp @@ -81,7 +81,7 @@ void LocalFileLoader::Seek(s64 absolutePos) { #endif } -size_t LocalFileLoader::Read(size_t bytes, size_t count, void *data) { +size_t LocalFileLoader::Read(size_t bytes, size_t count, void *data, Flags flags) { #ifdef ANDROID return read(fd_, data, bytes * count) / bytes; #else @@ -89,7 +89,7 @@ size_t LocalFileLoader::Read(size_t bytes, size_t count, void *data) { #endif } -size_t LocalFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) { +size_t LocalFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags) { Seek(absolutePos); return Read(bytes, count, data); } diff --git a/Core/FileLoaders/LocalFileLoader.h b/Core/FileLoaders/LocalFileLoader.h index 284a805dc0..46b694736d 100644 --- a/Core/FileLoaders/LocalFileLoader.h +++ b/Core/FileLoaders/LocalFileLoader.h @@ -31,8 +31,8 @@ public: virtual std::string Path() const override; virtual void Seek(s64 absolutePos) override; - virtual size_t Read(size_t bytes, size_t count, void *data) override; - virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override; + virtual size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override; + virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override; private: // First only used by Android, but we can keep it here for everyone. diff --git a/Core/FileLoaders/RamCachingFileLoader.cpp b/Core/FileLoaders/RamCachingFileLoader.cpp index b9e75e1c2f..a465aacda6 100644 --- a/Core/FileLoaders/RamCachingFileLoader.cpp +++ b/Core/FileLoaders/RamCachingFileLoader.cpp @@ -77,16 +77,16 @@ void RamCachingFileLoader::Seek(s64 absolutePos) { filepos_ = absolutePos; } -size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) { +size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) { size_t readSize = 0; - if (cache_ == nullptr) { + if (cache_ == nullptr || (flags & Flags::HINT_UNCACHED) != 0) { lock_guard guard(backendMutex_); - readSize = backend_->ReadAt(absolutePos, bytes, data); + readSize = backend_->ReadAt(absolutePos, bytes, data, flags); } else { readSize = ReadFromCache(absolutePos, bytes, data); // While in case the cache size is too small for the entire read. while (readSize < bytes) { - SaveIntoCache(absolutePos + readSize, bytes - readSize); + SaveIntoCache(absolutePos + readSize, bytes - readSize, flags); size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); readSize += bytesFromCache; if (bytesFromCache == 0) { @@ -94,9 +94,9 @@ size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) { break; } } - } - StartReadAhead(absolutePos + readSize); + StartReadAhead(absolutePos + readSize); + } filepos_ = absolutePos + readSize; return readSize; @@ -172,7 +172,7 @@ size_t RamCachingFileLoader::ReadFromCache(s64 pos, size_t bytes, void *data) { return readSize; } -void RamCachingFileLoader::SaveIntoCache(s64 pos, size_t bytes) { +void RamCachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, Flags flags) { s64 cacheStartPos = pos >> BLOCK_SHIFT; s64 cacheEndPos = (pos + bytes - 1) >> BLOCK_SHIFT; if ((size_t)cacheEndPos >= blocks_.size()) { @@ -194,7 +194,7 @@ void RamCachingFileLoader::SaveIntoCache(s64 pos, size_t bytes) { backendMutex_.lock(); s64 cacheFilePos = cacheStartPos << BLOCK_SHIFT; - size_t bytesRead = backend_->ReadAt(cacheFilePos, blocksToRead << BLOCK_SHIFT, &cache_[cacheFilePos]); + size_t bytesRead = backend_->ReadAt(cacheFilePos, blocksToRead << BLOCK_SHIFT, &cache_[cacheFilePos], flags); backendMutex_.unlock(); // In case there was an error, let's not mark blocks that failed to read as read. @@ -247,7 +247,7 @@ void RamCachingFileLoader::StartReadAhead(s64 pos) { for (u32 i = cacheStartPos; i <= cacheEndPos; ++i) { if (blocks_[i] == 0) { - SaveIntoCache((u64)i << BLOCK_SHIFT, BLOCK_SIZE * BLOCK_READAHEAD); + SaveIntoCache((u64)i << BLOCK_SHIFT, BLOCK_SIZE * BLOCK_READAHEAD, Flags::NONE); break; } } diff --git a/Core/FileLoaders/RamCachingFileLoader.h b/Core/FileLoaders/RamCachingFileLoader.h index 38d05826f7..fd25a68edf 100644 --- a/Core/FileLoaders/RamCachingFileLoader.h +++ b/Core/FileLoaders/RamCachingFileLoader.h @@ -34,23 +34,23 @@ public: std::string Path() const override; void Seek(s64 absolutePos) override; - size_t Read(size_t bytes, size_t count, void *data) override { - return ReadAt(filepos_, bytes, count, data); + size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { + return ReadAt(filepos_, bytes, count, data, flags); } - size_t Read(size_t bytes, void *data) override { - return ReadAt(filepos_, bytes, data); + size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override { + return ReadAt(filepos_, bytes, data, flags); } - size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override { - return ReadAt(absolutePos, bytes * count, data) / bytes; + size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { + return ReadAt(absolutePos, bytes * count, data, flags) / bytes; } - size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override; + size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override; private: void InitCache(); void ShutdownCache(); size_t ReadFromCache(s64 pos, size_t bytes, void *data); // Guaranteed to read at least one block into the cache. - void SaveIntoCache(s64 pos, size_t bytes); + void SaveIntoCache(s64 pos, size_t bytes, Flags flags); void StartReadAhead(s64 pos); u32 NextAheadBlock(); diff --git a/Core/FileLoaders/RetryingFileLoader.cpp b/Core/FileLoaders/RetryingFileLoader.cpp index 28fa17a955..28d78ff09b 100644 --- a/Core/FileLoaders/RetryingFileLoader.cpp +++ b/Core/FileLoaders/RetryingFileLoader.cpp @@ -64,13 +64,13 @@ void RetryingFileLoader::Seek(s64 absolutePos) { filepos_ = absolutePos; } -size_t RetryingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) { - size_t readSize = backend_->ReadAt(absolutePos, bytes, data); +size_t RetryingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) { + size_t readSize = backend_->ReadAt(absolutePos, bytes, data, flags); int retries = 0; while (readSize < bytes && retries < MAX_RETRIES) { u8 *p = (u8 *)data; - readSize += backend_->ReadAt(absolutePos + readSize, bytes - readSize, p + readSize); + readSize += backend_->ReadAt(absolutePos + readSize, bytes - readSize, p + readSize, flags); ++retries; } diff --git a/Core/FileLoaders/RetryingFileLoader.h b/Core/FileLoaders/RetryingFileLoader.h index 24cd0c284a..646af1371e 100644 --- a/Core/FileLoaders/RetryingFileLoader.h +++ b/Core/FileLoaders/RetryingFileLoader.h @@ -23,25 +23,25 @@ class RetryingFileLoader : public FileLoader { public: RetryingFileLoader(FileLoader *backend); - virtual ~RetryingFileLoader() override; + ~RetryingFileLoader() override; - virtual bool Exists() override; - virtual bool ExistsFast() override; - virtual bool IsDirectory() override; - virtual s64 FileSize() override; - virtual std::string Path() const override; + bool Exists() override; + bool ExistsFast() override; + bool IsDirectory() override; + s64 FileSize() override; + std::string Path() const override; - virtual void Seek(s64 absolutePos) override; - virtual size_t Read(size_t bytes, size_t count, void *data) override { - return ReadAt(filepos_, bytes, count, data); + void Seek(s64 absolutePos) override; + size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { + return ReadAt(filepos_, bytes, count, data, flags); } - virtual size_t Read(size_t bytes, void *data) override { - return ReadAt(filepos_, bytes, data); + size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override { + return ReadAt(filepos_, bytes, data, flags); } - virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override { - return ReadAt(absolutePos, bytes * count, data) / bytes; + size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { + return ReadAt(absolutePos, bytes * count, data, flags) / bytes; } - virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override; + size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override; private: enum { diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index 2f0a290d72..f1b0279309 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -54,8 +54,9 @@ FileBlockDevice::FileBlockDevice(FileLoader *fileLoader) FileBlockDevice::~FileBlockDevice() { } -bool FileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) { - if (fileLoader_->ReadAt((u64)blockNumber * (u64)GetBlockSize(), 1, 2048, outPtr) != 2048) { +bool FileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) { + FileLoader::Flags flags = uncached ? FileLoader::Flags::HINT_UNCACHED : FileLoader::Flags::NONE; + if (fileLoader_->ReadAt((u64)blockNumber * (u64)GetBlockSize(), 1, 2048, outPtr, flags) != 2048) { DEBUG_LOG(FILESYS, "Could not read 2048 bytes from block"); return false; } @@ -178,8 +179,9 @@ CISOFileBlockDevice::~CISOFileBlockDevice() delete [] zlibBuffer; } -bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) +bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) { + FileLoader::Flags flags = uncached ? FileLoader::Flags::HINT_UNCACHED : FileLoader::Flags::NONE; if ((u32)blockNumber >= numBlocks) { memset(outPtr, 0, GetBlockSize()); @@ -200,7 +202,7 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) const int plain = idx & 0x80000000; if (plain) { - int readSize = (u32)fileLoader_->ReadAt(compressedReadPos + compressedOffset, 1, GetBlockSize(), outPtr); + int readSize = (u32)fileLoader_->ReadAt(compressedReadPos + compressedOffset, 1, GetBlockSize(), outPtr, flags); if (readSize < GetBlockSize()) memset(outPtr + readSize, 0, GetBlockSize() - readSize); } @@ -211,7 +213,7 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) } else { - const u32 readSize = (u32)fileLoader_->ReadAt(compressedReadPos, 1, compressedReadSize, readBuffer); + const u32 readSize = (u32)fileLoader_->ReadAt(compressedReadPos, 1, compressedReadSize, readBuffer, flags); z.zalloc = Z_NULL; z.zfree = Z_NULL; @@ -423,8 +425,9 @@ NPDRMDemoBlockDevice::~NPDRMDemoBlockDevice() int lzrc_decompress(void *out, int out_len, void *in, int in_len); -bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) +bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) { + FileLoader::Flags flags = uncached ? FileLoader::Flags::HINT_UNCACHED : FileLoader::Flags::NONE; lock_guard guard(mutex_); CIPHER_KEY ckey; int block, lba, lzsize; @@ -453,7 +456,7 @@ bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) else readBuf = blockBuf; - readSize = fileLoader_->ReadAt(psarOffset+table[block].offset, 1, table[block].size, readBuf); + readSize = fileLoader_->ReadAt(psarOffset+table[block].offset, 1, table[block].size, readBuf, flags); if(readSize != (size_t)table[block].size){ if((u32)block==(numBlocks-1)) return true; diff --git a/Core/FileSystems/BlockDevices.h b/Core/FileSystems/BlockDevices.h index c11d15b24e..57cc5baefe 100644 --- a/Core/FileSystems/BlockDevices.h +++ b/Core/FileSystems/BlockDevices.h @@ -33,7 +33,7 @@ class BlockDevice { public: virtual ~BlockDevice() {} - virtual bool ReadBlock(int blockNumber, u8 *outPtr) = 0; + virtual bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) = 0; virtual bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) { for (int b = 0; b < count; ++b) { if (!ReadBlock(minBlock + b, outPtr)) { @@ -53,7 +53,7 @@ class CISOFileBlockDevice : public BlockDevice public: CISOFileBlockDevice(FileLoader *fileLoader); ~CISOFileBlockDevice(); - bool ReadBlock(int blockNumber, u8 *outPtr) override; + bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override; bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override; u32 GetNumBlocks() override { return numBlocks; } @@ -76,7 +76,7 @@ class FileBlockDevice : public BlockDevice public: FileBlockDevice(FileLoader *fileLoader); ~FileBlockDevice(); - bool ReadBlock(int blockNumber, u8 *outPtr) override; + bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override; bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override; u32 GetNumBlocks() override {return (u32)(filesize_ / GetBlockSize());} @@ -102,7 +102,7 @@ public: NPDRMDemoBlockDevice(FileLoader *fileLoader); ~NPDRMDemoBlockDevice(); - bool ReadBlock(int blockNumber, u8 *outPtr) override; + bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override; u32 GetNumBlocks() override {return (u32)lbaSize;} private: diff --git a/Core/Loaders.h b/Core/Loaders.h index 2fe2e8cc46..a584092b8d 100644 --- a/Core/Loaders.h +++ b/Core/Loaders.h @@ -51,6 +51,12 @@ enum IdentifiedFileType { class FileLoader { public: + enum class Flags { + NONE, + // Not necessary to read from / store into cache. + HINT_UNCACHED, + }; + virtual ~FileLoader() {} virtual bool Exists() = 0; @@ -71,16 +77,20 @@ public: } virtual void Seek(s64 absolutePos) = 0; - virtual size_t Read(size_t bytes, size_t count, void *data) = 0; - virtual size_t Read(size_t bytes, void *data) { - return Read(1, bytes, data); + virtual size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) = 0; + virtual size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) { + return Read(1, bytes, data, flags); } - virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) = 0; - virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) { - return ReadAt(absolutePos, 1, bytes, data); + virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) = 0; + virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) { + return ReadAt(absolutePos, 1, bytes, data, flags); } }; +inline u32 operator & (const FileLoader::Flags &a, const FileLoader::Flags &b) { + return (u32)a & (u32)b; +} + FileLoader *ConstructFileLoader(const std::string &filename); // Resolve to the target binary, ISO, or other file (e.g. from a directory.) FileLoader *ResolveFileLoaderTarget(FileLoader *fileLoader);