From 06ef95fbea3a2953ae29b671f7096aac3f6a4e48 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 29 Jul 2015 00:34:22 +0300 Subject: [PATCH] File/dir descriptors numbering experimental impl --- rpcs3/Emu/Memory/vm.h | 3 +- rpcs3/Emu/SysCalls/Modules/cellFs.cpp | 70 ++++++++-------- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 4 +- rpcs3/Emu/SysCalls/lv2/sys_fs.cpp | 103 ++++++++++++++++++------ rpcs3/Emu/SysCalls/lv2/sys_fs.h | 4 + 5 files changed, 121 insertions(+), 63 deletions(-) diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index e625265fbc..7b4fd197ed 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -407,7 +407,6 @@ namespace vm #include "vm_ref.h" #include "vm_ptr.h" -#include "vm_var.h" class CPUThread; @@ -449,3 +448,5 @@ namespace vm u32 stack_push(CPUThread& cpu, u32 size, u32 align, u32& old_pos); void stack_pop(CPUThread& cpu, u32 addr, u32 old_pos); } + +#include "vm_var.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp index 5fe9eeaf1a..478c7c80c6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp @@ -14,6 +14,8 @@ extern Module cellFs; +extern u32 _fd_to_id(u32 fd); + s32 cellFsOpen(vm::cptr path, s32 flags, vm::ptr fd, vm::cptr arg, u64 size) { cellFs.Warning("cellFsOpen(path=*0x%x, flags=%#o, fd=*0x%x, arg=*0x%x, size=0x%llx) -> sys_fs_open()", path, flags, fd, arg, size); @@ -207,9 +209,9 @@ s32 cellFsGetFreeSize(vm::cptr path, vm::ptr block_size, vm::ptr s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr entries, u32 entries_size, vm::ptr data_count) { - cellFs.Warning("cellFsGetDirectoryEntries(fd=0x%x, entries=*0x%x, entries_size=0x%x, data_count=*0x%x)", fd, entries, entries_size, data_count); + cellFs.Warning("cellFsGetDirectoryEntries(fd=%d, entries=*0x%x, entries_size=0x%x, data_count=*0x%x)", fd, entries, entries_size, data_count); - const auto directory = Emu.GetIdManager().get(fd); + const auto directory = Emu.GetIdManager().get(_fd_to_id(fd)); if (!directory) { @@ -250,11 +252,11 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr entries, u32 s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, vm::ptr nread) { - cellFs.Log("cellFsReadWithOffset(fd=0x%x, offset=0x%llx, buf=*0x%x, buffer_size=0x%llx, nread=*0x%x)", fd, offset, buf, buffer_size, nread); + cellFs.Log("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf=*0x%x, buffer_size=0x%llx, nread=*0x%x)", fd, offset, buf, buffer_size, nread); // TODO: use single sys_fs_fcntl syscall - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file || file->flags & CELL_FS_O_WRONLY) { @@ -281,11 +283,11 @@ s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::cptr buf, u64 data_size, vm::ptr nwrite) { - cellFs.Log("cellFsWriteWithOffset(fd=0x%x, offset=0x%llx, buf=*0x%x, data_size=0x%llx, nwrite=*0x%x)", fd, offset, buf, data_size, nwrite); + cellFs.Log("cellFsWriteWithOffset(fd=%d, offset=0x%llx, buf=*0x%x, data_size=0x%llx, nwrite=*0x%x)", fd, offset, buf, data_size, nwrite); // TODO: use single sys_fs_fcntl syscall - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { @@ -312,7 +314,7 @@ s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::cptr buf, u64 data_size, s32 cellFsStReadInit(u32 fd, vm::cptr ringbuf) { - cellFs.Warning("cellFsStReadInit(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf); + cellFs.Warning("cellFsStReadInit(fd=%d, ringbuf=*0x%x)", fd, ringbuf); if (ringbuf->copy & ~CELL_FS_ST_COPYLESS) { @@ -329,7 +331,7 @@ s32 cellFsStReadInit(u32 fd, vm::cptr ringbuf) return CELL_FS_EINVAL; } - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -365,9 +367,9 @@ s32 cellFsStReadInit(u32 fd, vm::cptr ringbuf) s32 cellFsStReadFinish(u32 fd) { - cellFs.Warning("cellFsStReadFinish(fd=0x%x)", fd); + cellFs.Warning("cellFsStReadFinish(fd=%d)", fd); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -388,9 +390,9 @@ s32 cellFsStReadFinish(u32 fd) s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) { - cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf); + cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, ringbuf=*0x%x)", fd, ringbuf); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -412,9 +414,9 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) { - cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, status=*0x%x)", fd, status); + cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, status=*0x%x)", fd, status); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -446,9 +448,9 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) { - cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=*0x%x)", fd, regid); + cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, regid=*0x%x)", fd, regid); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -467,9 +469,9 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) { - cellFs.Warning("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size); + cellFs.Warning("cellFsStReadStart(fd=%d, offset=0x%llx, size=0x%llx)", fd, offset, size); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -548,9 +550,9 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) s32 cellFsStReadStop(u32 fd) { - cellFs.Warning("cellFsStReadStop(fd=0x%x)", fd); + cellFs.Warning("cellFsStReadStop(fd=%d)", fd); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -579,9 +581,9 @@ s32 cellFsStReadStop(u32 fd) s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) { - cellFs.Warning("cellFsStRead(fd=0x%x, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize); + cellFs.Warning("cellFsStRead(fd=%d, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -613,9 +615,9 @@ s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr addr, vm::ptr size) { - cellFs.Warning("cellFsStReadGetCurrentAddr(fd=0x%x, addr=*0x%x, size=*0x%x)", fd, addr, size); + cellFs.Warning("cellFsStReadGetCurrentAddr(fd=%d, addr=*0x%x, size=*0x%x)", fd, addr, size); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -646,9 +648,9 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr addr, vm::ptr size) s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr addr, u64 size) { - cellFs.Warning("cellFsStReadPutCurrentAddr(fd=0x%x, addr=*0x%x, size=0x%llx)", fd, addr, size); + cellFs.Warning("cellFsStReadPutCurrentAddr(fd=%d, addr=*0x%x, size=0x%llx)", fd, addr, size); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -673,9 +675,9 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr addr, u64 size) s32 cellFsStReadWait(u32 fd, u64 size) { - cellFs.Warning("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size); + cellFs.Warning("cellFsStReadWait(fd=%d, size=0x%llx)", fd, size); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -702,9 +704,9 @@ s32 cellFsStReadWait(u32 fd, u64 size) s32 cellFsStReadWaitCallback(u32 fd, u64 size, fs_st_cb_t func) { - cellFs.Warning("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=*0x%x)", fd, size, func); + cellFs.Warning("cellFsStReadWaitCallback(fd=%d, size=0x%llx, func=*0x%x)", fd, size, func); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -867,12 +869,12 @@ using fs_aio_cb_t = vm::ptr xaio, s32 error, s32 xid, u6 void fsAio(vm::ptr aio, bool write, s32 xid, fs_aio_cb_t func) { - cellFs.Notice("FS AIO Request(%d): fd=0x%x, offset=0x%llx, buf=*0x%x, size=0x%llx, user_data=0x%llx", xid, aio->fd, aio->offset, aio->buf, aio->size, aio->user_data); + cellFs.Notice("FS AIO Request(%d): fd=%d, offset=0x%llx, buf=*0x%x, size=0x%llx, user_data=0x%llx", xid, aio->fd, aio->offset, aio->buf, aio->size, aio->user_data); s32 error = CELL_OK; u64 result = 0; - const auto file = Emu.GetIdManager().get(aio->fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(aio->fd)); if (!file || (!write && file->flags & CELL_FS_O_WRONLY) || (write && !(file->flags & CELL_FS_O_ACCMODE))) { @@ -964,9 +966,9 @@ s32 cellFsSetDefaultContainer(u32 id, u32 total_limit) s32 cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 page_type) { - cellFs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=0x%x, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type); + cellFs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=%d, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 65146445ce..048423451b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -1600,7 +1600,7 @@ Module cellSync("cellSync", []() cellSync.on_error = [](s64 value, ModuleFunc* func) { // get error name for CELL_SYNC errors - auto get_error = [](s32 code) -> const char* + auto get_error = [](u32 code) -> const char* { switch (code) { @@ -1625,7 +1625,7 @@ Module cellSync("cellSync", []() }; // analyse error code - if (s32 code = (value & 0xffffff00) == 0x80410100 ? static_cast(value) : 0) + if (u32 code = (value & 0xffffff00) == 0x80410100 ? static_cast(value) : 0) { cellSync.Error("%s() -> %s (0x%x)", func->name, get_error(code), code); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp index 76213f1c3d..6c2225528f 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp @@ -13,6 +13,29 @@ SysCallBase sys_fs("sys_fs"); +std::array, 256> g_fds = {}; // file descriptors 0..255 mapped to IDs + +u32 _fd_to_id(u32 fd) +{ + return fd < g_fds.size() ? g_fds[fd].load() : 0; +} + +lv2_file_t::~lv2_file_t() +{ + if (Emu.IsStopped()) + { + g_fds = {}; + } +} + +lv2_dir_t::~lv2_dir_t() +{ + if (Emu.IsStopped()) + { + g_fds = {}; + } +} + s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr arg3, u32 arg4, vm::ptr arg5, u32 arg6) { sys_fs.Todo("sys_fs_test(arg1=0x%x, arg2=0x%x, arg3=*0x%x, arg4=0x%x, arg5=*0x%x, arg6=0x%x) -> CELL_OK", arg1, arg2, arg3, arg4, arg5, arg6); @@ -113,17 +136,29 @@ s32 sys_fs_open(vm::cptr path, s32 flags, vm::ptr fd, s32 mode, vm::c return CELL_FS_ENOENT; } - - *fd = Emu.GetIdManager().make(std::move(file), mode, flags); - return CELL_OK; + for (u32 i = 3; i < g_fds.size(); i++) + { + // try to reserve fd + if (g_fds[i].compare_and_swap_test(0, ~0)) + { + g_fds[i].store(Emu.GetIdManager().make(std::move(file), mode, flags)); + + *fd = i; + + return CELL_OK; + } + } + + // out of file descriptors + return CELL_FS_EMFILE; } s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nread) { - sys_fs.Log("sys_fs_read(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread); + sys_fs.Log("sys_fs_read(fd=%d, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file || file->flags & CELL_FS_O_WRONLY) { @@ -139,9 +174,9 @@ s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nread) s32 sys_fs_write(u32 fd, vm::cptr buf, u64 nbytes, vm::ptr nwrite) { - sys_fs.Log("sys_fs_write(fd=0x%x, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite); + sys_fs.Log("sys_fs_write(fd=%d, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { @@ -159,9 +194,9 @@ s32 sys_fs_write(u32 fd, vm::cptr buf, u64 nbytes, vm::ptr nwrite) s32 sys_fs_close(u32 fd) { - sys_fs.Log("sys_fs_close(fd=0x%x)", fd); + sys_fs.Log("sys_fs_close(fd=%d)", fd); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -170,7 +205,9 @@ s32 sys_fs_close(u32 fd) // TODO: return CELL_FS_EBUSY if locked - Emu.GetIdManager().remove(fd); + Emu.GetIdManager().remove(_fd_to_id(fd)); + + g_fds[fd].store(0); return CELL_OK; } @@ -188,16 +225,28 @@ s32 sys_fs_opendir(vm::cptr path, vm::ptr fd) return CELL_FS_ENOENT; } - *fd = Emu.GetIdManager().make(std::move(dir)); + for (u32 i = 3; i < g_fds.size(); i++) + { + // try to reserve fd + if (g_fds[i].compare_and_swap_test(0, ~0)) + { + g_fds[i].store(Emu.GetIdManager().make(std::move(dir))); - return CELL_OK; + *fd = i; + + return CELL_OK; + } + } + + // out of file descriptors + return CELL_FS_EMFILE; } s32 sys_fs_readdir(u32 fd, vm::ptr dir, vm::ptr nread) { - sys_fs.Warning("sys_fs_readdir(fd=0x%x, dir=*0x%x, nread=*0x%x)", fd, dir, nread); + sys_fs.Warning("sys_fs_readdir(fd=%d, dir=*0x%x, nread=*0x%x)", fd, dir, nread); - const auto directory = Emu.GetIdManager().get(fd); + const auto directory = Emu.GetIdManager().get(_fd_to_id(fd)); if (!directory) { @@ -223,16 +272,18 @@ s32 sys_fs_readdir(u32 fd, vm::ptr dir, vm::ptr nread) s32 sys_fs_closedir(u32 fd) { - sys_fs.Log("sys_fs_closedir(fd=0x%x)", fd); + sys_fs.Log("sys_fs_closedir(fd=%d)", fd); - const auto directory = Emu.GetIdManager().get(fd); + const auto directory = Emu.GetIdManager().get(_fd_to_id(fd)); if (!directory) { return CELL_FS_EBADF; } - Emu.GetIdManager().remove(fd); + Emu.GetIdManager().remove(_fd_to_id(fd)); + + g_fds[fd].store(0); return CELL_OK; } @@ -272,9 +323,9 @@ s32 sys_fs_stat(vm::cptr path, vm::ptr sb) s32 sys_fs_fstat(u32 fd, vm::ptr sb) { - sys_fs.Warning("sys_fs_fstat(fd=0x%x, sb=*0x%x)", fd, sb); + sys_fs.Warning("sys_fs_fstat(fd=%d, sb=*0x%x)", fd, sb); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -415,15 +466,15 @@ s32 sys_fs_fcntl(u32 fd, s32 flags, u32 addr, u32 arg4, u32 arg5, u32 arg6) s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos) { - sys_fs.Log("sys_fs_lseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=*0x%x)", fd, offset, whence, pos); + sys_fs.Log("sys_fs_lseek(fd=%d, offset=0x%llx, whence=0x%x, pos=*0x%x)", fd, offset, whence, pos); if (whence >= 3) { - sys_fs.Error("sys_fs_lseek(fd=0x%x): unknown seek whence (%d)", fd, whence); + sys_fs.Error("sys_fs_lseek(): unknown seek whence (%d)", whence); return CELL_FS_EINVAL; } - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -439,9 +490,9 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos) s32 sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr block_size, vm::ptr arg4, vm::ptr arg5) { - sys_fs.Todo("sys_fs_fget_block_size(fd=0x%x, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5); + sys_fs.Todo("sys_fs_fget_block_size(fd=%d, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file) { @@ -487,9 +538,9 @@ s32 sys_fs_truncate(vm::cptr path, u64 size) s32 sys_fs_ftruncate(u32 fd, u64 size) { - sys_fs.Warning("sys_fs_ftruncate(fd=0x%x, size=0x%llx)", fd, size); + sys_fs.Warning("sys_fs_ftruncate(fd=%d, size=0x%llx)", fd, size); - const auto file = Emu.GetIdManager().get(fd); + const auto file = Emu.GetIdManager().get(_fd_to_id(fd)); if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.h b/rpcs3/Emu/SysCalls/lv2/sys_fs.h index 8d282f13e6..3f5f43ce79 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.h @@ -201,6 +201,8 @@ struct lv2_file_t , st_callback({}) { } + + ~lv2_file_t(); }; REG_ID_TYPE(lv2_file_t, 0x73); // SYS_FS_FD_OBJECT @@ -215,6 +217,8 @@ struct lv2_dir_t : dir(std::move(dir)) { } + + ~lv2_dir_t(); }; REG_ID_TYPE(lv2_dir_t, 0x73); // SYS_FS_FD_OBJECT