mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
sys_fs: Optimize concurrent file reads
This commit is contained in:
parent
f07e17f6aa
commit
4b827a8d9c
@ -1854,8 +1854,9 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
}
|
||||
|
||||
const auto file = std::as_const(all_files).find(file_path);
|
||||
const u64 pos = fileSet->fileOffset;
|
||||
|
||||
if (file == all_files.cend() || file->second.size() <= fileSet->fileOffset)
|
||||
if (file == all_files.cend() || file->second.size() <= pos)
|
||||
{
|
||||
cellSaveData.error("Failed to open file %s%s (size=%d, fileOffset=%d)", dir_path, file_path, file == all_files.cend() ? -1 : file->second.size(), fileSet->fileOffset);
|
||||
savedata_result = CELL_SAVEDATA_ERROR_FAILURE;
|
||||
@ -1863,8 +1864,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
}
|
||||
|
||||
// Read from memory file to vm
|
||||
file->second.seek(fileSet->fileOffset);
|
||||
const u64 rr = lv2_file::op_read(file->second, fileSet->fileBuf, fileSet->fileSize);
|
||||
const u64 rr = lv2_file::op_read(file->second, fileSet->fileBuf, fileSet->fileSize, pos);
|
||||
fileGet->excSize = ::narrow<u32>(rr);
|
||||
break;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <span>
|
||||
#include <shared_mutex>
|
||||
|
||||
LOG_CHANNEL(sys_fs);
|
||||
|
||||
@ -371,7 +372,7 @@ lv2_fs_object::lv2_fs_object(utils::serial& ar, bool)
|
||||
{
|
||||
}
|
||||
|
||||
u64 lv2_file::op_read(const fs::file& file, vm::ptr<void> buf, u64 size)
|
||||
u64 lv2_file::op_read(const fs::file& file, vm::ptr<void> buf, u64 size, u64 opt_pos)
|
||||
{
|
||||
// Copy data from intermediate buffer (avoid passing vm pointer to a native API)
|
||||
std::vector<uchar> local_buf(std::min<u64>(size, 65536));
|
||||
@ -381,7 +382,7 @@ u64 lv2_file::op_read(const fs::file& file, vm::ptr<void> buf, u64 size)
|
||||
while (result < size)
|
||||
{
|
||||
const u64 block = std::min<u64>(size - result, local_buf.size());
|
||||
const u64 nread = file.read(+local_buf.data(), block);
|
||||
const u64 nread = (opt_pos == umax ? file.read(local_buf.data(), block) : file.read_at(opt_pos + result, local_buf.data(), block));
|
||||
|
||||
std::memcpy(static_cast<uchar*>(buf.get_ptr()) + result, local_buf.data(), nread);
|
||||
result += nread;
|
||||
@ -1930,7 +1931,19 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
|
||||
sys_fs.error("%s type: Writing %u bytes to FD=%d (path=%s)", file->type, arg->size, file->name.data());
|
||||
}
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
std::unique_lock wlock(file->mp->mutex, std::defer_lock);
|
||||
std::shared_lock rlock(file->mp->mutex, std::defer_lock);
|
||||
|
||||
if (op == 0x8000000b)
|
||||
{
|
||||
// Writer lock
|
||||
wlock.lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reader lock (not needing exclusivity in this special case because the state should not change)
|
||||
rlock.lock();
|
||||
}
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
@ -1947,14 +1960,23 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
const u64 old_pos = file->file.pos();
|
||||
file->file.seek(arg->offset);
|
||||
u64 old_pos = umax;
|
||||
const u64 op_pos = arg->offset;
|
||||
|
||||
if (op == 0x8000000b)
|
||||
{
|
||||
old_pos = file->file.pos();
|
||||
file->file.seek(op_pos);
|
||||
}
|
||||
|
||||
arg->out_size = op == 0x8000000a
|
||||
? file->op_read(arg->buf, arg->size)
|
||||
? file->op_read(arg->buf, arg->size, op_pos)
|
||||
: file->op_write(arg->buf, arg->size);
|
||||
|
||||
ensure(old_pos == file->file.seek(old_pos));
|
||||
if (op == 0x8000000b)
|
||||
{
|
||||
ensure(old_pos == file->file.seek(old_pos));
|
||||
}
|
||||
|
||||
// TODO: EDATA corruption detection
|
||||
|
||||
|
@ -157,7 +157,7 @@ struct lv2_fs_mount_point
|
||||
const bs_t<lv2_mp_flag> flags{};
|
||||
lv2_fs_mount_point* const next = nullptr;
|
||||
|
||||
mutable std::recursive_mutex mutex;
|
||||
mutable shared_mutex mutex;
|
||||
};
|
||||
|
||||
extern lv2_fs_mount_point g_mp_sys_dev_hdd0;
|
||||
@ -340,11 +340,11 @@ struct lv2_file final : lv2_fs_object
|
||||
static open_result_t open(std::string_view vpath, s32 flags, s32 mode, const void* arg = {}, u64 size = 0);
|
||||
|
||||
// File reading with intermediate buffer
|
||||
static u64 op_read(const fs::file& file, vm::ptr<void> buf, u64 size);
|
||||
static u64 op_read(const fs::file& file, vm::ptr<void> buf, u64 size, u64 opt_pos = umax);
|
||||
|
||||
u64 op_read(vm::ptr<void> buf, u64 size) const
|
||||
u64 op_read(vm::ptr<void> buf, u64 size, u64 opt_pos = umax) const
|
||||
{
|
||||
return op_read(file, buf, size);
|
||||
return op_read(file, buf, size, opt_pos);
|
||||
}
|
||||
|
||||
// File writing with intermediate buffer
|
||||
|
Loading…
Reference in New Issue
Block a user