Skip to content

Commit

Permalink
sys_fs: Optimize concurrent file reads
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Oct 2, 2023
1 parent 4da5023 commit 673d2a7
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 14 deletions.
6 changes: 3 additions & 3 deletions rpcs3/Emu/Cell/Modules/cellSaveData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1854,17 +1854,17 @@ 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;
break;
}

// 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;
}
Expand Down
36 changes: 29 additions & 7 deletions rpcs3/Emu/Cell/lv2/sys_fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include <filesystem>
#include <span>
#include <shared_mutex>

LOG_CHANNEL(sys_fs);

Expand Down Expand Up @@ -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));
Expand All @@ -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;
Expand Down Expand Up @@ -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)
{
Expand All @@ -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

Expand Down
8 changes: 4 additions & 4 deletions rpcs3/Emu/Cell/lv2/sys_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 673d2a7

Please sign in to comment.