diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 4adcb96d67..136532bd7a 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -11,7 +11,7 @@ CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function thread_name) : m_state({ CPU_STATE_STOPPED }) - , m_id(idm::get_current_id()) + , m_id(idm::get_last_id()) , m_type(type) , m_name(name) { diff --git a/rpcs3/Emu/IdManager.cpp b/rpcs3/Emu/IdManager.cpp index 051e1ca979..46b597d9ea 100644 --- a/rpcs3/Emu/IdManager.cpp +++ b/rpcs3/Emu/IdManager.cpp @@ -5,16 +5,18 @@ namespace idm { std::mutex g_id_mutex; - std::unordered_map g_id_map; + std::unordered_map g_id_map; - u32 g_cur_id = 1; + thread_local u32 g_tls_last_id = 0xdeadbeef; + + u32 g_last_raw_id = 0; void clear() { std::lock_guard lock(g_id_mutex); g_id_map.clear(); - g_cur_id = 1; // first ID + g_last_raw_id = 0; } } diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index 6dfc4c8921..22a9918556 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -2,21 +2,34 @@ #define ID_MANAGER_INCLUDED -class ID_data_t final +// default specialization for all types +template struct id_traits +{ + // get next mapped id (may return 0 if out of IDs) + static u32 next_id(u32 raw_id) { return raw_id < 0x80000000 ? (raw_id + 1) & 0x7fffffff : 0; } + + // convert "public" id to mapped id (may return 0 if invalid) + static u32 in_id(u32 id) { return id; } + + // convert mapped id to "public" id + static u32 out_id(u32 raw_id) { return raw_id; } +}; + +class id_data_t final { public: const std::shared_ptr data; const std::type_info& info; const std::size_t hash; - template force_inline ID_data_t(std::shared_ptr data) + template force_inline id_data_t(std::shared_ptr data) : data(std::move(data)) , info(typeid(T)) , hash(typeid(T).hash_code()) { } - ID_data_t(ID_data_t&& right) + id_data_t(id_data_t&& right) : data(std::move(const_cast&>(right.data))) , info(right.info) , hash(right.hash) @@ -27,9 +40,17 @@ public: // ID Manager // 0 is invalid ID // 1..0x7fffffff : general purpose IDs -// 0x80000000+ : reserved +// 0x80000000+ : reserved (may be used through id_traits specializations) namespace idm { + // can be called from the constructor called through make() or make_ptr() to get the ID of currently created object + inline u32 get_last_id() + { + thread_local extern u32 g_tls_last_id; + + return g_tls_last_id; + } + // reinitialize ID manager void clear(); @@ -37,85 +58,81 @@ namespace idm template bool check(u32 id) { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; + extern std::unordered_map g_id_map; std::lock_guard lock(g_id_mutex); - const auto found = g_id_map.find(id); + const auto found = g_id_map.find(id_traits::in_id(id)); return found != g_id_map.end() && found->second.info == typeid(T); } // check if ID exists and return its type or nullptr - inline const std::type_info* get_type(u32 id) + inline const std::type_info* get_type(u32 raw_id) { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; + extern std::unordered_map g_id_map; std::lock_guard lock(g_id_mutex); - const auto found = g_id_map.find(id); + const auto found = g_id_map.find(raw_id); return found == g_id_map.end() ? nullptr : &found->second.info; } - // must be called from the constructor called through make() or make_ptr() to get further ID of current object - inline u32 get_current_id() - { - // contains the next ID or 0x80000000 | current_ID - extern u32 g_cur_id; - - if ((g_cur_id & 0x80000000) == 0) - { - throw EXCEPTION("Current ID is not available"); - } - - return g_cur_id & 0x7fffffff; - } - - // add new ID of specified type with specified constructor arguments (returns object) + // add new ID of specified type with specified constructor arguments (returns object or nullptr) template std::enable_if_t::value, std::shared_ptr> make_ptr(Args&&... args) { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; - extern u32 g_cur_id; + extern std::unordered_map g_id_map; + extern u32 g_last_raw_id; + thread_local extern u32 g_tls_last_id; std::lock_guard lock(g_id_mutex); - g_cur_id |= 0x80000000; + u32 raw_id = g_last_raw_id; - if (const u32 id = g_cur_id & 0x7fffffff) + while ((raw_id = id_traits::next_id(raw_id))) { + if (g_id_map.find(raw_id) != g_id_map.end()) continue; + + g_tls_last_id = id_traits::out_id(raw_id); + auto ptr = std::make_shared(std::forward(args)...); - g_id_map.emplace(id, ID_data_t(ptr)); + g_id_map.emplace(raw_id, id_data_t(ptr)); - g_cur_id = id + 1; + if (raw_id < 0x80000000) g_last_raw_id = raw_id; - return std::move(ptr); + return ptr; } - throw EXCEPTION("Out of IDs"); + return nullptr; } // add new ID of specified type with specified constructor arguments (returns id) template std::enable_if_t::value, u32> make(Args&&... args) { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; - extern u32 g_cur_id; + extern std::unordered_map g_id_map; + extern u32 g_last_raw_id; + thread_local extern u32 g_tls_last_id; std::lock_guard lock(g_id_mutex); - g_cur_id |= 0x80000000; + u32 raw_id = g_last_raw_id; - if (const u32 id = g_cur_id & 0x7fffffff) + while ((raw_id = id_traits::next_id(raw_id))) { - g_id_map.emplace(id, ID_data_t(std::make_shared(std::forward(args)...))); + if (g_id_map.find(raw_id) != g_id_map.end()) continue; - g_cur_id = id + 1; + g_tls_last_id = id_traits::out_id(raw_id); - return id; + g_id_map.emplace(raw_id, id_data_t(std::make_shared(std::forward(args)...))); + + if (raw_id < 0x80000000) g_last_raw_id = raw_id; + + return id_traits::out_id(raw_id); } throw EXCEPTION("Out of IDs"); @@ -125,18 +142,25 @@ namespace idm template u32 import(const std::shared_ptr& ptr) { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; - extern u32 g_cur_id; + extern std::unordered_map g_id_map; + extern u32 g_last_raw_id; + thread_local extern u32 g_tls_last_id; std::lock_guard lock(g_id_mutex); - if (const u32 id = g_cur_id & 0x7fffffff) + u32 raw_id = g_last_raw_id; + + while ((raw_id = id_traits::next_id(raw_id))) { - g_id_map.emplace(id, ID_data_t(ptr)); + if (g_id_map.find(raw_id) != g_id_map.end()) continue; - g_cur_id = id + 1; + g_tls_last_id = id_traits::out_id(raw_id); - return id; + g_id_map.emplace(raw_id, id_data_t(ptr)); + + if (raw_id < 0x80000000) g_last_raw_id = raw_id; + + return id_traits::out_id(raw_id); } throw EXCEPTION("Out of IDs"); @@ -146,11 +170,11 @@ namespace idm template std::shared_ptr get(u32 id) { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; + extern std::unordered_map g_id_map; std::lock_guard lock(g_id_mutex); - const auto found = g_id_map.find(id); + const auto found = g_id_map.find(id_traits::in_id(id)); if (found == g_id_map.end() || found->second.info != typeid(T)) { @@ -164,7 +188,7 @@ namespace idm template std::vector> get_all() { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; + extern std::unordered_map g_id_map; std::lock_guard lock(g_id_mutex); @@ -187,11 +211,11 @@ namespace idm template bool remove(u32 id) { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; + extern std::unordered_map g_id_map; std::lock_guard lock(g_id_mutex); - const auto found = g_id_map.find(id); + const auto found = g_id_map.find(id_traits::in_id(id)); if (found == g_id_map.end() || found->second.info != typeid(T)) { @@ -207,11 +231,11 @@ namespace idm template std::shared_ptr withdraw(u32 id) { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; + extern std::unordered_map g_id_map; std::lock_guard lock(g_id_mutex); - const auto found = g_id_map.find(id); + const auto found = g_id_map.find(id_traits::in_id(id)); if (found == g_id_map.end() || found->second.info != typeid(T)) { @@ -228,7 +252,7 @@ namespace idm template u32 get_count() { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; + extern std::unordered_map g_id_map; std::lock_guard lock(g_id_mutex); @@ -251,7 +275,7 @@ namespace idm template std::set get_set() { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; + extern std::unordered_map g_id_map; std::lock_guard lock(g_id_mutex); @@ -263,7 +287,7 @@ namespace idm { if (v.second.hash == hash && v.second.info == typeid(T)) { - result.insert(v.first); + result.insert(id_traits::out_id(v.first)); } } @@ -274,7 +298,7 @@ namespace idm template std::map> get_map() { extern std::mutex g_id_mutex; - extern std::unordered_map g_id_map; + extern std::unordered_map g_id_map; std::lock_guard lock(g_id_mutex); @@ -286,7 +310,7 @@ namespace idm { if (v.second.hash == hash && v.second.info == typeid(T)) { - result[v.first] = std::static_pointer_cast(v.second.data); + result[id_traits::out_id(v.first)] = std::static_pointer_cast(v.second.data); } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index cf967fcda4..490b1b5e2a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -80,7 +80,7 @@ PesHeader::PesHeader(DemuxerStream& stream) ElementaryStream::ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, vm::ptr cbFunc, u32 cbArg, u32 spec) : dmux(dmux) - , id(idm::get_current_id()) + , id(idm::get_last_id()) , memAddr(align(addr, 128)) , memSize(size - (addr - memAddr)) , fidMajor(fidMajor) diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp index 4330bdebd0..a86bf61f43 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp @@ -14,8 +14,6 @@ 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); @@ -211,7 +209,7 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr entries, u32 { 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 = idm::get(_fd_to_id(fd)); + const auto directory = idm::get(fd); if (!directory) { @@ -256,7 +254,7 @@ s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, // TODO: use single sys_fs_fcntl syscall - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file || file->flags & CELL_FS_O_WRONLY) { @@ -287,7 +285,7 @@ s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::cptr buf, u64 data_size, // TODO: use single sys_fs_fcntl syscall - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { @@ -331,7 +329,7 @@ s32 cellFsStReadInit(u32 fd, vm::cptr ringbuf) return CELL_FS_EINVAL; } - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -369,7 +367,7 @@ s32 cellFsStReadFinish(u32 fd) { cellFs.Warning("cellFsStReadFinish(fd=%d)", fd); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -392,7 +390,7 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) { cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, ringbuf=*0x%x)", fd, ringbuf); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -416,7 +414,7 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) { cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, status=*0x%x)", fd, status); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -450,7 +448,7 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) { cellFs.Warning("cellFsStReadGetRingBuf(fd=%d, regid=*0x%x)", fd, regid); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -471,7 +469,7 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) { cellFs.Warning("cellFsStReadStart(fd=%d, offset=0x%llx, size=0x%llx)", fd, offset, size); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -552,7 +550,7 @@ s32 cellFsStReadStop(u32 fd) { cellFs.Warning("cellFsStReadStop(fd=%d)", fd); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -583,7 +581,7 @@ s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) { cellFs.Warning("cellFsStRead(fd=%d, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -617,7 +615,7 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr addr, vm::ptr size) { cellFs.Warning("cellFsStReadGetCurrentAddr(fd=%d, addr=*0x%x, size=*0x%x)", fd, addr, size); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -650,7 +648,7 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr addr, u64 size) { cellFs.Warning("cellFsStReadPutCurrentAddr(fd=%d, addr=*0x%x, size=0x%llx)", fd, addr, size); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -677,7 +675,7 @@ s32 cellFsStReadWait(u32 fd, u64 size) { cellFs.Warning("cellFsStReadWait(fd=%d, size=0x%llx)", fd, size); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -706,7 +704,7 @@ s32 cellFsStReadWaitCallback(u32 fd, u64 size, fs_st_cb_t func) { cellFs.Warning("cellFsStReadWaitCallback(fd=%d, size=0x%llx, func=*0x%x)", fd, size, func); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -874,7 +872,7 @@ void fsAio(vm::ptr aio, bool write, s32 xid, fs_aio_cb_t func) s32 error = CELL_OK; u64 result = 0; - const auto file = idm::get(_fd_to_id(aio->fd)); + const auto file = idm::get(aio->fd); if (!file || (!write && file->flags & CELL_FS_O_WRONLY) || (write && !(file->flags & CELL_FS_O_ACCMODE))) { @@ -968,7 +966,7 @@ s32 cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 page_type { cellFs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=%d, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp index a41719a208..d84a8e1f12 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp @@ -18,26 +18,16 @@ extern Module sceNpTrophy; struct trophy_context_t { - const u32 id; + const u32 id = idm::get_last_id(); std::string trp_name; std::unique_ptr trp_stream; std::unique_ptr tropusr; - - trophy_context_t() - : id(idm::get_current_id()) - { - } }; struct trophy_handle_t { - const u32 id; - - trophy_handle_t() - : id(idm::get_current_id()) - { - } + const u32 id = idm::get_last_id(); }; // Functions diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp index 665648580a..8e0fb8da87 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp @@ -16,7 +16,7 @@ SysCallBase sys_event("sys_event"); extern u64 get_system_time(); lv2_event_queue_t::lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 key, s32 size) - : id(idm::get_current_id()) + : id(idm::get_last_id()) , protocol(protocol) , type(type) , name(name) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp index e1b63c2b81..fb55d88848 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp @@ -13,29 +13,6 @@ 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); @@ -137,28 +114,24 @@ s32 sys_fs_open(vm::cptr path, s32 flags, vm::ptr fd, s32 mode, vm::c return CELL_FS_ENOENT; } - for (u32 i = 3; i < g_fds.size(); i++) + const auto _file = idm::make_ptr(std::move(file), mode, flags); + + if (!_file) { - // try to reserve fd - if (g_fds[i].compare_and_swap_test(0, ~0)) - { - g_fds[i].store(idm::make(std::move(file), mode, flags)); - - *fd = i; - - return CELL_OK; - } + // out of file descriptors + return CELL_FS_EMFILE; } - // out of file descriptors - return CELL_FS_EMFILE; + *fd = idm::get_last_id(); + + return CELL_OK; } s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr 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 = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file || file->flags & CELL_FS_O_WRONLY) { @@ -176,7 +149,7 @@ s32 sys_fs_write(u32 fd, vm::cptr buf, u64 nbytes, vm::ptr 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 = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { @@ -196,7 +169,7 @@ s32 sys_fs_close(u32 fd) { sys_fs.Log("sys_fs_close(fd=%d)", fd); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -205,9 +178,7 @@ s32 sys_fs_close(u32 fd) // TODO: return CELL_FS_EBUSY if locked - idm::remove(_fd_to_id(fd)); - - g_fds[fd].store(0); + idm::remove(fd); return CELL_OK; } @@ -225,28 +196,24 @@ s32 sys_fs_opendir(vm::cptr path, vm::ptr fd) return CELL_FS_ENOENT; } - for (u32 i = 3; i < g_fds.size(); i++) + const auto _dir = idm::make_ptr(std::move(dir)); + + if (!_dir) { - // try to reserve fd - if (g_fds[i].compare_and_swap_test(0, ~0)) - { - g_fds[i].store(idm::make(std::move(dir))); - - *fd = i; - - return CELL_OK; - } + // out of file descriptors + return CELL_FS_EMFILE; } - // out of file descriptors - return CELL_FS_EMFILE; + *fd = idm::get_last_id(); + + return CELL_OK; } s32 sys_fs_readdir(u32 fd, vm::ptr dir, vm::ptr nread) { sys_fs.Warning("sys_fs_readdir(fd=%d, dir=*0x%x, nread=*0x%x)", fd, dir, nread); - const auto directory = idm::get(_fd_to_id(fd)); + const auto directory = idm::get(fd); if (!directory) { @@ -274,16 +241,14 @@ s32 sys_fs_closedir(u32 fd) { sys_fs.Log("sys_fs_closedir(fd=%d)", fd); - const auto directory = idm::get(_fd_to_id(fd)); + const auto directory = idm::get(fd); if (!directory) { return CELL_FS_EBADF; } - idm::remove(_fd_to_id(fd)); - - g_fds[fd].store(0); + idm::remove(fd); return CELL_OK; } @@ -325,7 +290,7 @@ s32 sys_fs_fstat(u32 fd, vm::ptr sb) { sys_fs.Warning("sys_fs_fstat(fd=%d, sb=*0x%x)", fd, sb); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -456,7 +421,7 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos) return CELL_FS_EINVAL; } - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -474,7 +439,7 @@ s32 sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr block_ { 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 = idm::get(_fd_to_id(fd)); + const auto file = idm::get(fd); if (!file) { @@ -522,7 +487,7 @@ s32 sys_fs_ftruncate(u32 fd, u64 size) { sys_fs.Warning("sys_fs_ftruncate(fd=%d, size=0x%llx)", fd, size); - const auto file = idm::get(_fd_to_id(fd)); + const auto file = idm::get(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 da94fa19c1..c615d12c05 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.h @@ -201,8 +201,28 @@ struct lv2_file_t , st_callback({}) { } +}; - ~lv2_file_t(); +template<> struct id_traits +{ + static const u32 base = 0xfddd0000, max = 255; + + static u32 next_id(u32 raw_id) + { + return + raw_id < 0x80000000 ? base + 3 : + raw_id - base < max ? raw_id + 1 : 0; + } + + static u32 in_id(u32 id) + { + return id + base; + } + + static u32 out_id(u32 raw_id) + { + return raw_id - base; + } }; class vfsDirBase; @@ -215,10 +235,10 @@ struct lv2_dir_t : dir(std::move(dir)) { } - - ~lv2_dir_t(); }; +template<> struct id_traits : public id_traits {}; + // SysCalls s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr arg3, u32 arg4, vm::ptr arg5, u32 arg6); s32 sys_fs_open(vm::cptr path, s32 flags, vm::ptr fd, s32 mode, vm::cptr arg, u64 size); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp index 53a47465b9..24d96e51b2 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp @@ -10,13 +10,13 @@ SysCallBase sys_interrupt("sys_interrupt"); lv2_int_tag_t::lv2_int_tag_t() - : id(idm::get_current_id()) + : id(idm::get_last_id()) { } lv2_int_serv_t::lv2_int_serv_t(const std::shared_ptr& thread) : thread(thread) - , id(idm::get_current_id()) + , id(idm::get_last_id()) { } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp b/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp index 1585f5d28c..81a2f9eefc 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp @@ -10,7 +10,7 @@ SysCallBase sys_memory("sys_memory"); lv2_memory_container_t::lv2_memory_container_t(u32 size) : size(size) - , id(idm::get_current_id()) + , id(idm::get_last_id()) { } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp index 5f0316d816..bd21fd9639 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp @@ -11,7 +11,7 @@ SysCallBase sys_mmapper("sys_mmapper"); lv2_memory_t::lv2_memory_t(u32 size, u32 align, u64 flags, const std::shared_ptr ct) : size(size) , align(align) - , id(idm::get_current_id()) + , id(idm::get_last_id()) , flags(flags) , ct(ct) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp index f0e1b60a3a..085e9816cb 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp @@ -17,7 +17,7 @@ SysCallBase sys_prx("sys_prx"); lv2_prx_t::lv2_prx_t() - : id(idm::get_current_id()) + : id(idm::get_last_id()) { } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp index da1ff8a09b..7dd48c3bcb 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp @@ -18,7 +18,7 @@ lv2_timer_t::lv2_timer_t() , period(0) , state(SYS_TIMER_STATE_STOP) { - auto name = fmt::format("Timer[0x%x] Thread", idm::get_current_id()); + auto name = fmt::format("Timer[0x%x] Thread", idm::get_last_id()); thread.start([name]{ return name; }, [this]() { diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index 9210dafc02..69d8849fd9 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -134,6 +134,8 @@ struct explicit_bool_t #define EXCEPTION(text, ...) fmt::exception(__FILE__, __LINE__, __FUNCTION__, text, ##__VA_ARGS__) #define VM_CAST(value) vm::impl_cast(value, __FILE__, __LINE__, __FUNCTION__) +template struct id_traits; + #define _PRGNAME_ "RPCS3" #define _PRGVER_ "0.0.0.5"