From a95a63a58abc8bbc0824eedee854a4a9d7631817 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 24 Apr 2017 23:30:15 +0300 Subject: [PATCH] sys_fs_lsn_lock implemented --- rpcs3/Emu/Cell/lv2/lv2.cpp | 4 +- rpcs3/Emu/Cell/lv2/sys_fs.cpp | 69 ++++++++++++++++++++++++++++++++--- rpcs3/Emu/Cell/lv2/sys_fs.h | 5 +++ 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index d02548b3b3..bdac695b88 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -746,8 +746,8 @@ std::array g_ppu_syscall_table null_func,//BIND_FUNC(sys_fs_acl_write), //824 (0x338) null_func,//BIND_FUNC(sys_fs_lsn_get_cda_size), //825 (0x339) null_func,//BIND_FUNC(sys_fs_lsn_get_cda), //826 (0x33A) - null_func,//BIND_FUNC(sys_fs_lsn_lock), //827 (0x33B) - null_func,//BIND_FUNC(sys_fs_lsn_unlock), //828 (0x33C) + BIND_FUNC(sys_fs_lsn_lock), //827 (0x33B) + BIND_FUNC(sys_fs_lsn_unlock), //828 (0x33C) null_func,//BIND_FUNC(sys_fs_lsn_read), //829 (0x33D) null_func,//BIND_FUNC(sys_fs_lsn_write), //830 (0x33E) BIND_FUNC(sys_fs_truncate), //831 (0x33F) diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index 9ab313b4c3..e93daf0931 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -377,10 +377,13 @@ error_code sys_fs_write(u32 fd, vm::cptr buf, u64 nbytes, vm::ptr nwr return CELL_EBADF; } - // TODO: return CELL_EBUSY if locked by stream - std::lock_guard lock(file->mp->mutex); + if (file->lock) + { + return CELL_EBUSY; + } + *nwrite = file->op_write(buf, nbytes); return CELL_OK; @@ -390,16 +393,25 @@ error_code sys_fs_close(u32 fd) { sys_fs.trace("sys_fs_close(fd=%d)", fd); - const auto file = idm::get(fd); + const auto file = idm::withdraw(fd, [](lv2_file& file) -> CellError + { + if (file.lock) + { + return CELL_EBUSY; + } + + return {}; + }); if (!file) { return CELL_EBADF; } - // TODO: return CELL_EBUSY if locked - - idm::remove(fd); + if (file.ret) + { + return file.ret; + } return CELL_OK; } @@ -651,6 +663,11 @@ error_code sys_fs_fcntl(u32 fd, u32 op, vm::ptr _arg, u32 _size) std::lock_guard lock(file->mp->mutex); + if (op == 0x8000000B && file->lock) + { + return CELL_EBUSY; + } + const u64 old_pos = file->file.pos(); const u64 new_pos = file->file.seek(arg->offset); @@ -929,3 +946,43 @@ error_code sys_fs_utime(vm::ps3::cptr path, vm::ps3::cptr t return CELL_OK; } + +error_code sys_fs_lsn_lock(u32 fd) +{ + sys_fs.trace("sys_fs_lsn_lock(fd=%d)", fd); + + const auto file = idm::get(fd); + + if (!file) + { + return CELL_EBADF; + } + + // TODO: research correct implementation + if (!file->lock.compare_and_swap_test(0, 1)) + { + return CELL_EBUSY; + } + + return CELL_OK; +} + +error_code sys_fs_lsn_unlock(u32 fd) +{ + sys_fs.trace("sys_fs_lsn_unlock(fd=%d)", fd); + + const auto file = idm::get(fd); + + if (!file) + { + return CELL_EBADF; + } + + // TODO: research correct implementation + if (!file->lock.compare_and_swap_test(1, 0)) + { + return CELL_EPERM; + } + + return CELL_OK; +} diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.h b/rpcs3/Emu/Cell/lv2/sys_fs.h index 6fea6b7d09..0f4114e2df 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.h +++ b/rpcs3/Emu/Cell/lv2/sys_fs.h @@ -166,6 +166,9 @@ struct lv2_file final : lv2_fs_object const s32 mode; const s32 flags; + // Stream lock + atomic_t lock{0}; + lv2_file(const char* filename, fs::file&& file, s32 mode, s32 flags) : lv2_fs_object(lv2_fs_object::get_mp(filename), filename) , file(std::move(file)) @@ -330,3 +333,5 @@ error_code sys_fs_truncate(vm::ps3::cptr path, u64 size); error_code sys_fs_ftruncate(u32 fd, u64 size); error_code sys_fs_chmod(vm::ps3::cptr path, s32 mode); error_code sys_fs_utime(vm::ps3::cptr path, vm::ps3::cptr timep); +error_code sys_fs_lsn_lock(u32 fd); +error_code sys_fs_lsn_unlock(u32 fd);