mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Add uncached flag for file loader reads.
This allows us to indicate that a read need not be cached.
This commit is contained in:
parent
cbb1ab17ca
commit
65c7d0bd04
15 changed files with 136 additions and 117 deletions
|
@ -84,7 +84,7 @@ void CachingFileLoader::Seek(s64 absolutePos) {
|
||||||
filepos_ = 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();
|
Prepare();
|
||||||
if (absolutePos >= filesize_) {
|
if (absolutePos >= filesize_) {
|
||||||
bytes = 0;
|
bytes = 0;
|
||||||
|
@ -92,10 +92,15 @@ size_t CachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
||||||
bytes = filesize_ - absolutePos;
|
bytes = filesize_ - absolutePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t readSize = ReadFromCache(absolutePos, bytes, data);
|
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 in case the cache size is too small for the entire read.
|
||||||
while (readSize < bytes) {
|
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);
|
size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize);
|
||||||
readSize += bytesFromCache;
|
readSize += bytesFromCache;
|
||||||
if (bytesFromCache == 0) {
|
if (bytesFromCache == 0) {
|
||||||
|
@ -105,6 +110,7 @@ size_t CachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
StartReadAhead(absolutePos + readSize);
|
StartReadAhead(absolutePos + readSize);
|
||||||
|
}
|
||||||
|
|
||||||
filepos_ = absolutePos + readSize;
|
filepos_ = absolutePos + readSize;
|
||||||
return readSize;
|
return readSize;
|
||||||
|
@ -158,7 +164,7 @@ size_t CachingFileLoader::ReadFromCache(s64 pos, size_t bytes, void *data) {
|
||||||
return readSize;
|
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 cacheStartPos = pos >> BLOCK_SHIFT;
|
||||||
s64 cacheEndPos = (pos + bytes - 1) >> 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];
|
u8 *buf = new u8[BLOCK_SIZE];
|
||||||
backendMutex_.lock();
|
backendMutex_.lock();
|
||||||
backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, BLOCK_SIZE, buf);
|
backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, BLOCK_SIZE, buf, flags);
|
||||||
backendMutex_.unlock();
|
backendMutex_.unlock();
|
||||||
|
|
||||||
blocksMutex_.lock();
|
blocksMutex_.lock();
|
||||||
|
@ -200,7 +206,7 @@ void CachingFileLoader::SaveIntoCache(s64 pos, size_t bytes, bool readingAhead)
|
||||||
|
|
||||||
u8 *wholeRead = new u8[blocksToRead << BLOCK_SHIFT];
|
u8 *wholeRead = new u8[blocksToRead << BLOCK_SHIFT];
|
||||||
backendMutex_.lock();
|
backendMutex_.lock();
|
||||||
backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, blocksToRead << BLOCK_SHIFT, wholeRead);
|
backend_->ReadAt(cacheStartPos << BLOCK_SHIFT, blocksToRead << BLOCK_SHIFT, wholeRead, flags);
|
||||||
backendMutex_.unlock();
|
backendMutex_.unlock();
|
||||||
|
|
||||||
blocksMutex_.lock();
|
blocksMutex_.lock();
|
||||||
|
@ -288,7 +294,7 @@ void CachingFileLoader::StartReadAhead(s64 pos) {
|
||||||
auto block = blocks_.find(i);
|
auto block = blocks_.find(i);
|
||||||
if (block == blocks_.end()) {
|
if (block == blocks_.end()) {
|
||||||
blocksMutex_.unlock();
|
blocksMutex_.unlock();
|
||||||
SaveIntoCache(i << BLOCK_SHIFT, BLOCK_SIZE * BLOCK_READAHEAD, true);
|
SaveIntoCache(i << BLOCK_SHIFT, BLOCK_SIZE * BLOCK_READAHEAD, Flags::NONE, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,25 +25,25 @@
|
||||||
class CachingFileLoader : public FileLoader {
|
class CachingFileLoader : public FileLoader {
|
||||||
public:
|
public:
|
||||||
CachingFileLoader(FileLoader *backend);
|
CachingFileLoader(FileLoader *backend);
|
||||||
virtual ~CachingFileLoader() override;
|
~CachingFileLoader() override;
|
||||||
|
|
||||||
virtual bool Exists() override;
|
bool Exists() override;
|
||||||
virtual bool ExistsFast() override;
|
bool ExistsFast() override;
|
||||||
virtual bool IsDirectory() override;
|
bool IsDirectory() override;
|
||||||
virtual s64 FileSize() override;
|
s64 FileSize() override;
|
||||||
virtual std::string Path() const override;
|
std::string Path() const override;
|
||||||
|
|
||||||
virtual void Seek(s64 absolutePos) override;
|
void Seek(s64 absolutePos) override;
|
||||||
virtual size_t Read(size_t bytes, size_t count, void *data) override {
|
size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(filepos_, bytes, count, data);
|
return ReadAt(filepos_, bytes, count, data, flags);
|
||||||
}
|
}
|
||||||
virtual size_t Read(size_t bytes, void *data) override {
|
size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(filepos_, bytes, data);
|
return ReadAt(filepos_, bytes, data, flags);
|
||||||
}
|
}
|
||||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override {
|
size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(absolutePos, bytes * count, data) / bytes;
|
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:
|
private:
|
||||||
void Prepare();
|
void Prepare();
|
||||||
|
@ -51,7 +51,7 @@ private:
|
||||||
void ShutdownCache();
|
void ShutdownCache();
|
||||||
size_t ReadFromCache(s64 pos, size_t bytes, void *data);
|
size_t ReadFromCache(s64 pos, size_t bytes, void *data);
|
||||||
// Guaranteed to read at least one block into the cache.
|
// 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);
|
bool MakeCacheSpaceFor(size_t blocks, bool readingAhead);
|
||||||
void StartReadAhead(s64 pos);
|
void StartReadAhead(s64 pos);
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ void DiskCachingFileLoader::Seek(s64 absolutePos) {
|
||||||
filepos_ = 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();
|
Prepare();
|
||||||
size_t readSize;
|
size_t readSize;
|
||||||
|
|
||||||
|
@ -99,11 +99,11 @@ size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data)
|
||||||
bytes = filesize_ - absolutePos;
|
bytes = filesize_ - absolutePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache_ && cache_->IsValid()) {
|
if (cache_ && cache_->IsValid() && (flags & Flags::HINT_UNCACHED) == 0) {
|
||||||
readSize = cache_->ReadFromCache(absolutePos, bytes, data);
|
readSize = cache_->ReadFromCache(absolutePos, bytes, data);
|
||||||
// While in case the cache size is too small for the entire read.
|
// While in case the cache size is too small for the entire read.
|
||||||
while (readSize < bytes) {
|
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.
|
// If there are already-cached blocks afterward, we have to read them.
|
||||||
size_t bytesFromCache = cache_->ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize);
|
size_t bytesFromCache = cache_->ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize);
|
||||||
readSize += bytesFromCache;
|
readSize += bytesFromCache;
|
||||||
|
@ -113,7 +113,7 @@ size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
readSize = backend_->ReadAt(absolutePos, bytes, data);
|
readSize = backend_->ReadAt(absolutePos, bytes, data, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
filepos_ = absolutePos + readSize;
|
filepos_ = absolutePos + readSize;
|
||||||
|
@ -256,12 +256,12 @@ size_t DiskCachingFileLoaderCache::ReadFromCache(s64 pos, size_t bytes, void *da
|
||||||
return readSize;
|
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_);
|
lock_guard guard(lock_);
|
||||||
|
|
||||||
if (!f_) {
|
if (!f_) {
|
||||||
// Just to keep things working.
|
// Just to keep things working.
|
||||||
return backend->ReadAt(pos, bytes, data);
|
return backend->ReadAt(pos, bytes, data, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 cacheStartPos = pos / blockSize_;
|
s64 cacheStartPos = pos / blockSize_;
|
||||||
|
@ -290,7 +290,7 @@ size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, s
|
||||||
auto &info = index_[cacheStartPos];
|
auto &info = index_[cacheStartPos];
|
||||||
|
|
||||||
u8 *buf = new u8[blockSize_];
|
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.
|
// Check if it was written while we were busy. Might happen if we thread.
|
||||||
if (info.block == INVALID_BLOCK && readBytes != 0) {
|
if (info.block == INVALID_BLOCK && readBytes != 0) {
|
||||||
|
@ -306,7 +306,7 @@ size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, s
|
||||||
delete [] buf;
|
delete [] buf;
|
||||||
} else {
|
} else {
|
||||||
u8 *wholeRead = new u8[blocksToRead * blockSize_];
|
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) {
|
for (size_t i = 0; i < blocksToRead; ++i) {
|
||||||
auto &info = index_[cacheStartPos + i];
|
auto &info = index_[cacheStartPos + i];
|
||||||
|
|
|
@ -28,25 +28,25 @@ class DiskCachingFileLoaderCache;
|
||||||
class DiskCachingFileLoader : public FileLoader {
|
class DiskCachingFileLoader : public FileLoader {
|
||||||
public:
|
public:
|
||||||
DiskCachingFileLoader(FileLoader *backend);
|
DiskCachingFileLoader(FileLoader *backend);
|
||||||
virtual ~DiskCachingFileLoader() override;
|
~DiskCachingFileLoader() override;
|
||||||
|
|
||||||
virtual bool Exists() override;
|
bool Exists() override;
|
||||||
virtual bool ExistsFast() override;
|
bool ExistsFast() override;
|
||||||
virtual bool IsDirectory() override;
|
bool IsDirectory() override;
|
||||||
virtual s64 FileSize() override;
|
s64 FileSize() override;
|
||||||
virtual std::string Path() const override;
|
std::string Path() const override;
|
||||||
|
|
||||||
virtual void Seek(s64 absolutePos) override;
|
void Seek(s64 absolutePos) override;
|
||||||
virtual size_t Read(size_t bytes, size_t count, void *data) override {
|
size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(filepos_, bytes, count, data);
|
return ReadAt(filepos_, bytes, count, data, flags);
|
||||||
}
|
}
|
||||||
virtual size_t Read(size_t bytes, void *data) override {
|
size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(filepos_, bytes, data);
|
return ReadAt(filepos_, bytes, data, flags);
|
||||||
}
|
}
|
||||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override {
|
size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(absolutePos, bytes * count, data) / bytes;
|
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<std::string> GetCachedPathsInUse();
|
static std::vector<std::string> GetCachedPathsInUse();
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ public:
|
||||||
|
|
||||||
size_t ReadFromCache(s64 pos, size_t bytes, void *data);
|
size_t ReadFromCache(s64 pos, size_t bytes, void *data);
|
||||||
// Guaranteed to read at least one block into the cache.
|
// 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;
|
bool HasData() const;
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ void HTTPFileLoader::Seek(s64 absolutePos) {
|
||||||
filepos_ = 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();
|
Prepare();
|
||||||
s64 absoluteEnd = std::min(absolutePos + (s64)bytes, filesize_);
|
s64 absoluteEnd = std::min(absolutePos + (s64)bytes, filesize_);
|
||||||
if (absolutePos >= filesize_ || bytes == 0) {
|
if (absolutePos >= filesize_ || bytes == 0) {
|
||||||
|
|
|
@ -35,16 +35,16 @@ public:
|
||||||
virtual std::string Path() const override;
|
virtual std::string Path() const override;
|
||||||
|
|
||||||
virtual void Seek(s64 absolutePos) override;
|
virtual void Seek(s64 absolutePos) override;
|
||||||
virtual size_t Read(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 {
|
||||||
return ReadAt(filepos_, bytes, count, data);
|
return ReadAt(filepos_, bytes, count, data, flags);
|
||||||
}
|
}
|
||||||
virtual size_t Read(size_t bytes, void *data) override {
|
virtual size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(filepos_, bytes, data);
|
return ReadAt(filepos_, bytes, data, flags);
|
||||||
}
|
}
|
||||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override {
|
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) / bytes;
|
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:
|
private:
|
||||||
void Prepare();
|
void Prepare();
|
||||||
|
|
|
@ -81,7 +81,7 @@ void LocalFileLoader::Seek(s64 absolutePos) {
|
||||||
#endif
|
#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
|
#ifdef ANDROID
|
||||||
return read(fd_, data, bytes * count) / bytes;
|
return read(fd_, data, bytes * count) / bytes;
|
||||||
#else
|
#else
|
||||||
|
@ -89,7 +89,7 @@ size_t LocalFileLoader::Read(size_t bytes, size_t count, void *data) {
|
||||||
#endif
|
#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);
|
Seek(absolutePos);
|
||||||
return Read(bytes, count, data);
|
return Read(bytes, count, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,8 @@ public:
|
||||||
virtual std::string Path() const override;
|
virtual std::string Path() const override;
|
||||||
|
|
||||||
virtual void Seek(s64 absolutePos) override;
|
virtual void Seek(s64 absolutePos) override;
|
||||||
virtual size_t Read(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) override;
|
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// First only used by Android, but we can keep it here for everyone.
|
// First only used by Android, but we can keep it here for everyone.
|
||||||
|
|
|
@ -77,16 +77,16 @@ void RamCachingFileLoader::Seek(s64 absolutePos) {
|
||||||
filepos_ = 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;
|
size_t readSize = 0;
|
||||||
if (cache_ == nullptr) {
|
if (cache_ == nullptr || (flags & Flags::HINT_UNCACHED) != 0) {
|
||||||
lock_guard guard(backendMutex_);
|
lock_guard guard(backendMutex_);
|
||||||
readSize = backend_->ReadAt(absolutePos, bytes, data);
|
readSize = backend_->ReadAt(absolutePos, bytes, data, flags);
|
||||||
} else {
|
} else {
|
||||||
readSize = ReadFromCache(absolutePos, bytes, data);
|
readSize = ReadFromCache(absolutePos, bytes, data);
|
||||||
// While in case the cache size is too small for the entire read.
|
// While in case the cache size is too small for the entire read.
|
||||||
while (readSize < bytes) {
|
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);
|
size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize);
|
||||||
readSize += bytesFromCache;
|
readSize += bytesFromCache;
|
||||||
if (bytesFromCache == 0) {
|
if (bytesFromCache == 0) {
|
||||||
|
@ -94,9 +94,9 @@ size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
StartReadAhead(absolutePos + readSize);
|
StartReadAhead(absolutePos + readSize);
|
||||||
|
}
|
||||||
|
|
||||||
filepos_ = absolutePos + readSize;
|
filepos_ = absolutePos + readSize;
|
||||||
return readSize;
|
return readSize;
|
||||||
|
@ -172,7 +172,7 @@ size_t RamCachingFileLoader::ReadFromCache(s64 pos, size_t bytes, void *data) {
|
||||||
return readSize;
|
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 cacheStartPos = pos >> BLOCK_SHIFT;
|
||||||
s64 cacheEndPos = (pos + bytes - 1) >> BLOCK_SHIFT;
|
s64 cacheEndPos = (pos + bytes - 1) >> BLOCK_SHIFT;
|
||||||
if ((size_t)cacheEndPos >= blocks_.size()) {
|
if ((size_t)cacheEndPos >= blocks_.size()) {
|
||||||
|
@ -194,7 +194,7 @@ void RamCachingFileLoader::SaveIntoCache(s64 pos, size_t bytes) {
|
||||||
|
|
||||||
backendMutex_.lock();
|
backendMutex_.lock();
|
||||||
s64 cacheFilePos = cacheStartPos << BLOCK_SHIFT;
|
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();
|
backendMutex_.unlock();
|
||||||
|
|
||||||
// In case there was an error, let's not mark blocks that failed to read as read.
|
// 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) {
|
for (u32 i = cacheStartPos; i <= cacheEndPos; ++i) {
|
||||||
if (blocks_[i] == 0) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,23 +34,23 @@ public:
|
||||||
std::string Path() const override;
|
std::string Path() const override;
|
||||||
|
|
||||||
void Seek(s64 absolutePos) override;
|
void Seek(s64 absolutePos) override;
|
||||||
size_t Read(size_t bytes, size_t count, void *data) override {
|
size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(filepos_, bytes, count, data);
|
return ReadAt(filepos_, bytes, count, data, flags);
|
||||||
}
|
}
|
||||||
size_t Read(size_t bytes, void *data) override {
|
size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(filepos_, bytes, data);
|
return ReadAt(filepos_, bytes, data, flags);
|
||||||
}
|
}
|
||||||
size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override {
|
size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(absolutePos, bytes * count, data) / bytes;
|
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:
|
private:
|
||||||
void InitCache();
|
void InitCache();
|
||||||
void ShutdownCache();
|
void ShutdownCache();
|
||||||
size_t ReadFromCache(s64 pos, size_t bytes, void *data);
|
size_t ReadFromCache(s64 pos, size_t bytes, void *data);
|
||||||
// Guaranteed to read at least one block into the cache.
|
// 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);
|
void StartReadAhead(s64 pos);
|
||||||
u32 NextAheadBlock();
|
u32 NextAheadBlock();
|
||||||
|
|
||||||
|
|
|
@ -64,13 +64,13 @@ void RetryingFileLoader::Seek(s64 absolutePos) {
|
||||||
filepos_ = absolutePos;
|
filepos_ = absolutePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RetryingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
size_t RetryingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) {
|
||||||
size_t readSize = backend_->ReadAt(absolutePos, bytes, data);
|
size_t readSize = backend_->ReadAt(absolutePos, bytes, data, flags);
|
||||||
|
|
||||||
int retries = 0;
|
int retries = 0;
|
||||||
while (readSize < bytes && retries < MAX_RETRIES) {
|
while (readSize < bytes && retries < MAX_RETRIES) {
|
||||||
u8 *p = (u8 *)data;
|
u8 *p = (u8 *)data;
|
||||||
readSize += backend_->ReadAt(absolutePos + readSize, bytes - readSize, p + readSize);
|
readSize += backend_->ReadAt(absolutePos + readSize, bytes - readSize, p + readSize, flags);
|
||||||
++retries;
|
++retries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,25 +23,25 @@
|
||||||
class RetryingFileLoader : public FileLoader {
|
class RetryingFileLoader : public FileLoader {
|
||||||
public:
|
public:
|
||||||
RetryingFileLoader(FileLoader *backend);
|
RetryingFileLoader(FileLoader *backend);
|
||||||
virtual ~RetryingFileLoader() override;
|
~RetryingFileLoader() override;
|
||||||
|
|
||||||
virtual bool Exists() override;
|
bool Exists() override;
|
||||||
virtual bool ExistsFast() override;
|
bool ExistsFast() override;
|
||||||
virtual bool IsDirectory() override;
|
bool IsDirectory() override;
|
||||||
virtual s64 FileSize() override;
|
s64 FileSize() override;
|
||||||
virtual std::string Path() const override;
|
std::string Path() const override;
|
||||||
|
|
||||||
virtual void Seek(s64 absolutePos) override;
|
void Seek(s64 absolutePos) override;
|
||||||
virtual size_t Read(size_t bytes, size_t count, void *data) override {
|
size_t Read(size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(filepos_, bytes, count, data);
|
return ReadAt(filepos_, bytes, count, data, flags);
|
||||||
}
|
}
|
||||||
virtual size_t Read(size_t bytes, void *data) override {
|
size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(filepos_, bytes, data);
|
return ReadAt(filepos_, bytes, data, flags);
|
||||||
}
|
}
|
||||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data) override {
|
size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override {
|
||||||
return ReadAt(absolutePos, bytes * count, data) / bytes;
|
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:
|
private:
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -54,8 +54,9 @@ FileBlockDevice::FileBlockDevice(FileLoader *fileLoader)
|
||||||
FileBlockDevice::~FileBlockDevice() {
|
FileBlockDevice::~FileBlockDevice() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) {
|
bool FileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached) {
|
||||||
if (fileLoader_->ReadAt((u64)blockNumber * (u64)GetBlockSize(), 1, 2048, outPtr) != 2048) {
|
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");
|
DEBUG_LOG(FILESYS, "Could not read 2048 bytes from block");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -178,8 +179,9 @@ CISOFileBlockDevice::~CISOFileBlockDevice()
|
||||||
delete [] zlibBuffer;
|
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)
|
if ((u32)blockNumber >= numBlocks)
|
||||||
{
|
{
|
||||||
memset(outPtr, 0, GetBlockSize());
|
memset(outPtr, 0, GetBlockSize());
|
||||||
|
@ -200,7 +202,7 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
|
||||||
const int plain = idx & 0x80000000;
|
const int plain = idx & 0x80000000;
|
||||||
if (plain)
|
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())
|
if (readSize < GetBlockSize())
|
||||||
memset(outPtr + readSize, 0, GetBlockSize() - readSize);
|
memset(outPtr + readSize, 0, GetBlockSize() - readSize);
|
||||||
}
|
}
|
||||||
|
@ -211,7 +213,7 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
|
||||||
}
|
}
|
||||||
else
|
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.zalloc = Z_NULL;
|
||||||
z.zfree = 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);
|
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_);
|
lock_guard guard(mutex_);
|
||||||
CIPHER_KEY ckey;
|
CIPHER_KEY ckey;
|
||||||
int block, lba, lzsize;
|
int block, lba, lzsize;
|
||||||
|
@ -453,7 +456,7 @@ bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
|
||||||
else
|
else
|
||||||
readBuf = blockBuf;
|
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(readSize != (size_t)table[block].size){
|
||||||
if((u32)block==(numBlocks-1))
|
if((u32)block==(numBlocks-1))
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -33,7 +33,7 @@ class BlockDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~BlockDevice() {}
|
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) {
|
virtual bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) {
|
||||||
for (int b = 0; b < count; ++b) {
|
for (int b = 0; b < count; ++b) {
|
||||||
if (!ReadBlock(minBlock + b, outPtr)) {
|
if (!ReadBlock(minBlock + b, outPtr)) {
|
||||||
|
@ -53,7 +53,7 @@ class CISOFileBlockDevice : public BlockDevice
|
||||||
public:
|
public:
|
||||||
CISOFileBlockDevice(FileLoader *fileLoader);
|
CISOFileBlockDevice(FileLoader *fileLoader);
|
||||||
~CISOFileBlockDevice();
|
~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;
|
bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override;
|
||||||
u32 GetNumBlocks() override { return numBlocks; }
|
u32 GetNumBlocks() override { return numBlocks; }
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ class FileBlockDevice : public BlockDevice
|
||||||
public:
|
public:
|
||||||
FileBlockDevice(FileLoader *fileLoader);
|
FileBlockDevice(FileLoader *fileLoader);
|
||||||
~FileBlockDevice();
|
~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;
|
bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override;
|
||||||
u32 GetNumBlocks() override {return (u32)(filesize_ / GetBlockSize());}
|
u32 GetNumBlocks() override {return (u32)(filesize_ / GetBlockSize());}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ public:
|
||||||
NPDRMDemoBlockDevice(FileLoader *fileLoader);
|
NPDRMDemoBlockDevice(FileLoader *fileLoader);
|
||||||
~NPDRMDemoBlockDevice();
|
~NPDRMDemoBlockDevice();
|
||||||
|
|
||||||
bool ReadBlock(int blockNumber, u8 *outPtr) override;
|
bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override;
|
||||||
u32 GetNumBlocks() override {return (u32)lbaSize;}
|
u32 GetNumBlocks() override {return (u32)lbaSize;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -51,6 +51,12 @@ enum IdentifiedFileType {
|
||||||
|
|
||||||
class FileLoader {
|
class FileLoader {
|
||||||
public:
|
public:
|
||||||
|
enum class Flags {
|
||||||
|
NONE,
|
||||||
|
// Not necessary to read from / store into cache.
|
||||||
|
HINT_UNCACHED,
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~FileLoader() {}
|
virtual ~FileLoader() {}
|
||||||
|
|
||||||
virtual bool Exists() = 0;
|
virtual bool Exists() = 0;
|
||||||
|
@ -71,16 +77,20 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Seek(s64 absolutePos) = 0;
|
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, size_t count, void *data, Flags flags = Flags::NONE) = 0;
|
||||||
virtual size_t Read(size_t bytes, void *data) {
|
virtual size_t Read(size_t bytes, void *data, Flags flags = Flags::NONE) {
|
||||||
return Read(1, bytes, data);
|
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, size_t count, void *data, Flags flags = Flags::NONE) = 0;
|
||||||
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) {
|
||||||
return ReadAt(absolutePos, 1, bytes, data);
|
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);
|
FileLoader *ConstructFileLoader(const std::string &filename);
|
||||||
// Resolve to the target binary, ISO, or other file (e.g. from a directory.)
|
// Resolve to the target binary, ISO, or other file (e.g. from a directory.)
|
||||||
FileLoader *ResolveFileLoaderTarget(FileLoader *fileLoader);
|
FileLoader *ResolveFileLoaderTarget(FileLoader *fileLoader);
|
||||||
|
|
Loading…
Add table
Reference in a new issue