From 575a245f8d4bcd42039627533d1748c3af0f36a7 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Sun, 22 Dec 2024 20:59:48 +0200 Subject: [PATCH] IDM: Implement lock-free smart pointers (#16403) Replaces `std::shared_pointer` with `stx::atomic_ptr` and `stx::shared_ptr`. Notes to programmers: * This pr kills the use of `dynamic_cast`, `std::dynamic_pointer_cast` and `std::weak_ptr` on IDM objects, possible replacement is to save the object ID on the base object, then use idm::check/get_unlocked to the destination type via the saved ID which may be null. Null pointer check is how you can tell type mismatch (as dynamic cast) or object destruction (as weak_ptr locking). * Double-inheritance on IDM objects should be used with care, `stx::shared_ptr` does not support constant-evaluated pointer offsetting to parent/child type. * `idm::check/get_unlocked` can now be used anywhere. Misc fixes: * Fixes some segfaults with RPCN with interaction with IDM. * Fix deadlocks in access violation handler due locking recursion. * Fixes race condition in process exit-spawn on memory containers read. * Fix bug that theoretically can prevent RPCS3 from booting - fix `id_manager::typeinfo` comparison to compare members instead of `memcmp` which can fail spuriously on padding bytes. * Ensure all IDM inherited types of base, either has `id_base` or `id_type` defined locally, this allows to make getters such as `idm::get_unlocked()` which were broken before. (requires save-states invalidation) * Removes broken operator[] overload of `stx::shared_ptr` and `stx::single_ptr` for non-array types. --- Utilities/Thread.cpp | 6 +- Utilities/mutex.h | 2 +- rpcs3/Emu/CPU/CPUDisAsm.h | 5 +- rpcs3/Emu/CPU/CPUThread.cpp | 28 +- rpcs3/Emu/Cell/Modules/cellAudio.cpp | 2 +- rpcs3/Emu/Cell/Modules/cellAudio.h | 2 +- rpcs3/Emu/Cell/Modules/cellDmux.cpp | 26 +- rpcs3/Emu/Cell/Modules/cellFs.cpp | 28 +- rpcs3/Emu/Cell/Modules/cellGame.cpp | 2 +- rpcs3/Emu/Cell/Modules/cellGcmSys.cpp | 2 +- rpcs3/Emu/Cell/Modules/cellGifDec.cpp | 4 +- rpcs3/Emu/Cell/Modules/cellJpgDec.cpp | 12 +- rpcs3/Emu/Cell/Modules/cellPngDec.cpp | 2 +- rpcs3/Emu/Cell/Modules/cellSearch.cpp | 44 +- rpcs3/Emu/Cell/Modules/cellSpurs.cpp | 2 +- rpcs3/Emu/Cell/Modules/cellVdec.cpp | 26 +- rpcs3/Emu/Cell/Modules/cellVpost.cpp | 4 +- rpcs3/Emu/Cell/Modules/libmixer.cpp | 2 +- rpcs3/Emu/Cell/Modules/sceNp.cpp | 48 +-- rpcs3/Emu/Cell/Modules/sceNp.h | 2 +- rpcs3/Emu/Cell/Modules/sceNpSns.cpp | 10 +- rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp | 14 +- rpcs3/Emu/Cell/Modules/sceNpTus.cpp | 56 +-- rpcs3/Emu/Cell/Modules/sys_io_.cpp | 6 +- rpcs3/Emu/Cell/Modules/sys_mempool.cpp | 14 +- rpcs3/Emu/Cell/PPUAnalyser.cpp | 8 +- rpcs3/Emu/Cell/PPUAnalyser.h | 8 +- rpcs3/Emu/Cell/PPUModule.cpp | 59 +-- rpcs3/Emu/Cell/PPUThread.cpp | 50 +-- rpcs3/Emu/Cell/PPUTranslator.cpp | 5 +- rpcs3/Emu/Cell/PPUTranslator.h | 11 +- rpcs3/Emu/Cell/SPUThread.cpp | 20 +- rpcs3/Emu/Cell/SPUThread.h | 6 +- rpcs3/Emu/Cell/lv2/sys_cond.cpp | 26 +- rpcs3/Emu/Cell/lv2/sys_cond.h | 15 +- rpcs3/Emu/Cell/lv2/sys_config.cpp | 29 +- rpcs3/Emu/Cell/lv2/sys_config.h | 86 ++-- rpcs3/Emu/Cell/lv2/sys_event.cpp | 18 +- rpcs3/Emu/Cell/lv2/sys_event.h | 8 +- rpcs3/Emu/Cell/lv2/sys_event_flag.cpp | 11 +- rpcs3/Emu/Cell/lv2/sys_event_flag.h | 2 +- rpcs3/Emu/Cell/lv2/sys_fs.cpp | 68 +-- rpcs3/Emu/Cell/lv2/sys_fs.h | 2 +- rpcs3/Emu/Cell/lv2/sys_interrupt.cpp | 18 +- rpcs3/Emu/Cell/lv2/sys_interrupt.h | 6 +- rpcs3/Emu/Cell/lv2/sys_io.cpp | 4 +- rpcs3/Emu/Cell/lv2/sys_lwcond.cpp | 4 +- rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_memory.cpp | 11 +- rpcs3/Emu/Cell/lv2/sys_memory.h | 2 +- rpcs3/Emu/Cell/lv2/sys_mmapper.cpp | 16 +- rpcs3/Emu/Cell/lv2/sys_mmapper.h | 2 +- rpcs3/Emu/Cell/lv2/sys_mutex.cpp | 7 +- rpcs3/Emu/Cell/lv2/sys_mutex.h | 2 +- rpcs3/Emu/Cell/lv2/sys_net.cpp | 32 +- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket.h | 8 +- .../Cell/lv2/sys_net/lv2_socket_native.cpp | 6 +- .../Emu/Cell/lv2/sys_net/lv2_socket_native.h | 4 +- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.h | 2 +- .../Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp | 4 +- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h | 4 +- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.h | 4 +- .../Emu/Cell/lv2/sys_net/network_context.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp | 4 +- rpcs3/Emu/Cell/lv2/sys_overlay.cpp | 19 +- rpcs3/Emu/Cell/lv2/sys_overlay.h | 4 +- rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp | 24 +- rpcs3/Emu/Cell/lv2/sys_process.cpp | 22 +- rpcs3/Emu/Cell/lv2/sys_prx.cpp | 36 +- rpcs3/Emu/Cell/lv2/sys_prx.h | 4 +- rpcs3/Emu/Cell/lv2/sys_rsx.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp | 30 +- rpcs3/Emu/Cell/lv2/sys_rsxaudio.h | 4 +- rpcs3/Emu/Cell/lv2/sys_rwlock.cpp | 7 +- rpcs3/Emu/Cell/lv2/sys_rwlock.h | 2 +- rpcs3/Emu/Cell/lv2/sys_semaphore.cpp | 7 +- rpcs3/Emu/Cell/lv2/sys_semaphore.h | 2 +- rpcs3/Emu/Cell/lv2/sys_spu.cpp | 82 ++-- rpcs3/Emu/Cell/lv2/sys_spu.h | 10 +- rpcs3/Emu/Cell/lv2/sys_storage.cpp | 8 +- rpcs3/Emu/Cell/lv2/sys_sync.h | 25 +- rpcs3/Emu/Cell/lv2/sys_timer.cpp | 8 +- rpcs3/Emu/Cell/lv2/sys_timer.h | 4 +- rpcs3/Emu/Cell/lv2/sys_vm.cpp | 20 +- rpcs3/Emu/GDB.cpp | 83 ++-- rpcs3/Emu/GDB.h | 2 +- rpcs3/Emu/IPC.h | 14 +- rpcs3/Emu/IdManager.cpp | 27 +- rpcs3/Emu/IdManager.h | 402 ++++++++++-------- rpcs3/Emu/NP/np_contexts.cpp | 27 +- rpcs3/Emu/NP/np_contexts.h | 22 +- rpcs3/Emu/NP/np_handler.cpp | 8 +- rpcs3/Emu/NP/np_handler.h | 50 +-- rpcs3/Emu/NP/np_notifications.cpp | 2 +- rpcs3/Emu/NP/np_requests.cpp | 58 +-- rpcs3/Emu/NP/np_requests_gui.cpp | 6 +- rpcs3/Emu/NP/rpcn_client.cpp | 8 +- rpcs3/Emu/NP/rpcn_client.h | 8 +- rpcs3/Emu/RSX/GL/GLCompute.h | 2 +- rpcs3/Emu/RSX/GL/GLOverlays.h | 2 +- .../Network/overlay_recvmessage_dialog.cpp | 4 +- .../Network/overlay_recvmessage_dialog.h | 2 +- rpcs3/Emu/RSX/Overlays/overlay_manager.h | 6 +- rpcs3/Emu/RSX/RSXThread.h | 2 +- rpcs3/Emu/RSX/VK/VKCompute.h | 2 +- rpcs3/Emu/RSX/VK/VKOverlays.h | 2 +- rpcs3/Emu/System.cpp | 28 +- rpcs3/Emu/System.h | 2 +- rpcs3/Emu/VFS.cpp | 2 +- rpcs3/Emu/cache_utils.cpp | 3 +- rpcs3/Emu/perf_meter.cpp | 6 +- rpcs3/Emu/savestate_utils.cpp | 2 +- rpcs3/rpcs3qt/cheat_manager.cpp | 3 +- rpcs3/rpcs3qt/debugger_frame.cpp | 18 +- rpcs3/rpcs3qt/debugger_frame.h | 3 +- rpcs3/rpcs3qt/kernel_explorer.cpp | 4 +- rpcs3/rpcs3qt/memory_viewer_panel.cpp | 6 +- rpcs3/rpcs3qt/recvmessage_dialog_frame.cpp | 6 +- rpcs3/rpcs3qt/recvmessage_dialog_frame.h | 6 +- rpcs3/util/logs.cpp | 2 +- rpcs3/util/shared_ptr.hpp | 116 ++--- 124 files changed, 1145 insertions(+), 1052 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 000910848f..a7f7165163 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1360,7 +1360,7 @@ bool handle_access_violation(u32 addr, bool is_writing, ucontext_t* context) noe // check if address is RawSPU MMIO register do if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) { - auto thread = idm::get>(spu_thread::find_raw_spu((addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET)); + auto thread = idm::get_unlocked>(spu_thread::find_raw_spu((addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET)); if (!thread) { @@ -1548,7 +1548,7 @@ bool handle_access_violation(u32 addr, bool is_writing, ucontext_t* context) noe } } - if (auto pf_port = idm::get(pf_port_id); pf_port && pf_port->queue) + if (auto pf_port = idm::get_unlocked(pf_port_id); pf_port && pf_port->queue) { // We notify the game that a page fault occurred so it can rectify it. // Note, for data3, were the memory readable AND we got a page fault, it must be due to a write violation since reads are allowed. @@ -2602,7 +2602,7 @@ bool thread_base::join(bool dtor) const if (i >= 16 && !(i & (i - 1)) && timeout != atomic_wait_timeout::inf) { - sig_log.error(u8"Thread [%s] is too sleepy. Waiting for it %.3fµs already!", *m_tname.load(), (utils::get_tsc() - stamp0) / (utils::get_tsc_freq() / 1000000.)); + sig_log.error(u8"Thread [%s] is too sleepy. Waiting for it %.3fus already!", *m_tname.load(), (utils::get_tsc() - stamp0) / (utils::get_tsc_freq() / 1000000.)); } } diff --git a/Utilities/mutex.h b/Utilities/mutex.h index 0b7cba2248..4c09431096 100644 --- a/Utilities/mutex.h +++ b/Utilities/mutex.h @@ -121,7 +121,7 @@ public: void unlock_hle() { - const u32 value = atomic_storage::fetch_add_hle_rel(m_value.raw(), 0u - c_one); + const u32 value = atomic_storage::fetch_add_hle_rel(m_value.raw(), ~c_one + 1); if (value != c_one) [[unlikely]] { diff --git a/rpcs3/Emu/CPU/CPUDisAsm.h b/rpcs3/Emu/CPU/CPUDisAsm.h index 6aa6a1554e..1b4fc5515b 100644 --- a/rpcs3/Emu/CPU/CPUDisAsm.h +++ b/rpcs3/Emu/CPU/CPUDisAsm.h @@ -1,6 +1,7 @@ #pragma once #include +#include "Emu/CPU/CPUThread.h" #include "Utilities/StrFmt.h" enum class cpu_disasm_mode @@ -22,7 +23,7 @@ protected: const u8* m_offset{}; const u32 m_start_pc; std::add_pointer_t m_cpu{}; - std::shared_ptr m_cpu_handle; + shared_ptr m_cpu_handle; u32 m_op = 0; void format_by_mode() @@ -81,7 +82,7 @@ public: return const_cast(m_cpu); } - void set_cpu_handle(std::shared_ptr cpu) + void set_cpu_handle(shared_ptr cpu) { m_cpu_handle = std::move(cpu); diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index e78824c0b5..520446e991 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -87,7 +87,7 @@ void fmt_class_string::format(std::string& ou const u32 must_have_cpu_id = static_cast(arg); // Dump main_thread - const auto main_ppu = idm::get>(ppu_thread::id_base); + const auto main_ppu = idm::get_unlocked>(ppu_thread::id_base); if (main_ppu) { @@ -99,7 +99,7 @@ void fmt_class_string::format(std::string& ou { if (must_have_cpu_id != ppu_thread::id_base) { - const auto selected_ppu = idm::get>(must_have_cpu_id); + const auto selected_ppu = idm::get_unlocked>(must_have_cpu_id); if (selected_ppu) { @@ -110,7 +110,7 @@ void fmt_class_string::format(std::string& ou } else if (must_have_cpu_id >> 24 == spu_thread::id_base >> 24) { - const auto selected_spu = idm::get>(must_have_cpu_id); + const auto selected_spu = idm::get_unlocked>(must_have_cpu_id); if (selected_spu) { @@ -236,7 +236,7 @@ struct cpu_prof } // Print info - void print(const std::shared_ptr& ptr) + void print(const shared_ptr& ptr) { if (new_samples < min_print_samples || samples == idle) { @@ -263,7 +263,7 @@ struct cpu_prof new_samples = 0; } - static void print_all(std::unordered_map, sample_info>& threads, sample_info& all_info) + static void print_all(std::unordered_map, sample_info>& threads, sample_info& all_info) { u64 new_samples = 0; @@ -319,7 +319,7 @@ struct cpu_prof void operator()() { - std::unordered_map, sample_info> threads; + std::unordered_map, sample_info> threads; while (thread_ctrl::state() != thread_state::aborting) { @@ -335,15 +335,15 @@ struct cpu_prof continue; } - std::shared_ptr ptr; + shared_ptr ptr; if (id >> 24 == 1) { - ptr = idm::get>(id); + ptr = idm::get_unlocked>(id); } else if (id >> 24 == 2) { - ptr = idm::get>(id); + ptr = idm::get_unlocked>(id); } else { @@ -437,7 +437,7 @@ struct cpu_prof continue; } - // Wait, roughly for 20µs + // Wait, roughly for 20us thread_ctrl::wait_for(20, false); } @@ -1302,7 +1302,7 @@ cpu_thread* cpu_thread::get_next_cpu() return nullptr; } -std::shared_ptr make_disasm(const cpu_thread* cpu, std::shared_ptr handle); +std::shared_ptr make_disasm(const cpu_thread* cpu, shared_ptr handle); void cpu_thread::dump_all(std::string& ret) const { @@ -1318,7 +1318,7 @@ void cpu_thread::dump_all(std::string& ret) const if (u32 cur_pc = get_pc(); cur_pc != umax) { // Dump a snippet of currently executed code (may be unreliable with non-static-interpreter decoders) - auto disasm = make_disasm(this, nullptr); + auto disasm = make_disasm(this, null_ptr); const auto rsx = try_get(); @@ -1558,14 +1558,14 @@ u32 CPUDisAsm::DisAsmBranchTarget(s32 /*imm*/) return 0; } -extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool revert_lock, std::vector>, u32>>* out_list) +extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool revert_lock, std::vector>, u32>>* out_list) { if (out_list) { out_list->clear(); } - auto get_spus = [old_counter = u64{umax}, spu_list = std::vector>>()](bool can_collect, bool force_collect) mutable + auto get_spus = [old_counter = u64{umax}, spu_list = std::vector>>()](bool can_collect, bool force_collect) mutable { const u64 new_counter = cpu_thread::g_threads_created + cpu_thread::g_threads_deleted; diff --git a/rpcs3/Emu/Cell/Modules/cellAudio.cpp b/rpcs3/Emu/Cell/Modules/cellAudio.cpp index 8137e3b58f..2e31d37b6b 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudio.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAudio.cpp @@ -556,7 +556,7 @@ void cell_audio_thread::advance(u64 timestamp) m_dynamic_period = 0; // send aftermix event (normal audio event) - std::array, MAX_AUDIO_EVENT_QUEUES> queues; + std::array, MAX_AUDIO_EVENT_QUEUES> queues; u32 queue_count = 0; event_period++; diff --git a/rpcs3/Emu/Cell/Modules/cellAudio.h b/rpcs3/Emu/Cell/Modules/cellAudio.h index cab56aeef7..939b7f994c 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudio.h +++ b/rpcs3/Emu/Cell/Modules/cellAudio.h @@ -400,7 +400,7 @@ public: u32 flags = 0; // iFlags u64 source = 0; // Event source u64 ack_timestamp = 0; // timestamp of last call of cellAudioSendAck - std::shared_ptr port{}; // Underlying event port + shared_ptr port{}; // Underlying event port }; std::vector keys{}; diff --git a/rpcs3/Emu/Cell/Modules/cellDmux.cpp b/rpcs3/Emu/Cell/Modules/cellDmux.cpp index 7850961aa9..5c94463ea3 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmux.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmux.cpp @@ -1031,7 +1031,7 @@ error_code cellDmuxClose(u32 handle) { cellDmux.warning("cellDmuxClose(handle=0x%x)", handle); - const auto dmux = idm::get(handle); + const auto dmux = idm::get_unlocked(handle); if (!dmux) { @@ -1060,7 +1060,7 @@ error_code cellDmuxSetStream(u32 handle, u32 streamAddress, u32 streamSize, b8 d { cellDmux.trace("cellDmuxSetStream(handle=0x%x, streamAddress=0x%x, streamSize=%d, discontinuity=%d, userData=0x%llx)", handle, streamAddress, streamSize, discontinuity, userData); - const auto dmux = idm::get(handle); + const auto dmux = idm::get_unlocked(handle); if (!dmux) { @@ -1088,7 +1088,7 @@ error_code cellDmuxResetStream(u32 handle) { cellDmux.warning("cellDmuxResetStream(handle=0x%x)", handle); - const auto dmux = idm::get(handle); + const auto dmux = idm::get_unlocked(handle); if (!dmux) { @@ -1103,7 +1103,7 @@ error_code cellDmuxResetStreamAndWaitDone(u32 handle) { cellDmux.warning("cellDmuxResetStreamAndWaitDone(handle=0x%x)", handle); - const auto dmux = idm::get(handle); + const auto dmux = idm::get_unlocked(handle); if (!dmux) { @@ -1164,7 +1164,7 @@ error_code cellDmuxEnableEs(u32 handle, vm::cptr esFilterId { cellDmux.warning("cellDmuxEnableEs(handle=0x%x, esFilterId=*0x%x, esResourceInfo=*0x%x, esCb=*0x%x, esSpecificInfo=*0x%x, esHandle=*0x%x)", handle, esFilterId, esResourceInfo, esCb, esSpecificInfo, esHandle); - const auto dmux = idm::get(handle); + const auto dmux = idm::get_unlocked(handle); if (!dmux) { @@ -1194,7 +1194,7 @@ error_code cellDmuxDisableEs(u32 esHandle) { cellDmux.warning("cellDmuxDisableEs(esHandle=0x%x)", esHandle); - const auto es = idm::get(esHandle); + const auto es = idm::get_unlocked(esHandle); if (!es) { @@ -1213,7 +1213,7 @@ error_code cellDmuxResetEs(u32 esHandle) { cellDmux.trace("cellDmuxResetEs(esHandle=0x%x)", esHandle); - const auto es = idm::get(esHandle); + const auto es = idm::get_unlocked(esHandle); if (!es) { @@ -1232,7 +1232,7 @@ error_code cellDmuxGetAu(u32 esHandle, vm::ptr auInfo, vm::ptr auSpeci { cellDmux.trace("cellDmuxGetAu(esHandle=0x%x, auInfo=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfo, auSpecificInfo); - const auto es = idm::get(esHandle); + const auto es = idm::get_unlocked(esHandle); if (!es) { @@ -1255,7 +1255,7 @@ error_code cellDmuxPeekAu(u32 esHandle, vm::ptr auInfo, vm::ptr auSpec { cellDmux.trace("cellDmuxPeekAu(esHandle=0x%x, auInfo=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfo, auSpecificInfo); - const auto es = idm::get(esHandle); + const auto es = idm::get_unlocked(esHandle); if (!es) { @@ -1278,7 +1278,7 @@ error_code cellDmuxGetAuEx(u32 esHandle, vm::ptr auInfoEx, vm::ptr auS { cellDmux.trace("cellDmuxGetAuEx(esHandle=0x%x, auInfoEx=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfoEx, auSpecificInfo); - const auto es = idm::get(esHandle); + const auto es = idm::get_unlocked(esHandle); if (!es) { @@ -1301,7 +1301,7 @@ error_code cellDmuxPeekAuEx(u32 esHandle, vm::ptr auInfoEx, vm::ptr au { cellDmux.trace("cellDmuxPeekAuEx(esHandle=0x%x, auInfoEx=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfoEx, auSpecificInfo); - const auto es = idm::get(esHandle); + const auto es = idm::get_unlocked(esHandle); if (!es) { @@ -1324,7 +1324,7 @@ error_code cellDmuxReleaseAu(u32 esHandle) { cellDmux.trace("cellDmuxReleaseAu(esHandle=0x%x)", esHandle); - const auto es = idm::get(esHandle); + const auto es = idm::get_unlocked(esHandle); if (!es) { @@ -1342,7 +1342,7 @@ error_code cellDmuxFlushEs(u32 esHandle) { cellDmux.warning("cellDmuxFlushEs(esHandle=0x%x)", esHandle); - const auto es = idm::get(esHandle); + const auto es = idm::get_unlocked(esHandle); if (!es) { diff --git a/rpcs3/Emu/Cell/Modules/cellFs.cpp b/rpcs3/Emu/Cell/Modules/cellFs.cpp index fcc0810b3e..bff73f530b 100644 --- a/rpcs3/Emu/Cell/Modules/cellFs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFs.cpp @@ -598,7 +598,7 @@ error_code cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 pa { cellFs.todo("cellFsSetIoBufferFromDefaultContainer(fd=%d, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -695,7 +695,7 @@ s32 cellFsStReadInit(u32 fd, vm::cptr ringbuf) return CELL_EINVAL; } - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -716,7 +716,7 @@ s32 cellFsStReadFinish(u32 fd) { cellFs.todo("cellFsStReadFinish(fd=%d)", fd); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -732,7 +732,7 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) { cellFs.todo("cellFsStReadGetRingBuf(fd=%d, ringbuf=*0x%x)", fd, ringbuf); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -748,7 +748,7 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) { cellFs.todo("cellFsStReadGetRingBuf(fd=%d, status=*0x%x)", fd, status); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -764,7 +764,7 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) { cellFs.todo("cellFsStReadGetRingBuf(fd=%d, regid=*0x%x)", fd, regid); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -780,7 +780,7 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) { cellFs.todo("cellFsStReadStart(fd=%d, offset=0x%llx, size=0x%llx)", fd, offset, size); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -796,7 +796,7 @@ s32 cellFsStReadStop(u32 fd) { cellFs.todo("cellFsStReadStop(fd=%d)", fd); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -812,7 +812,7 @@ s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) { cellFs.todo("cellFsStRead(fd=%d, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -828,7 +828,7 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr addr, vm::ptr size) { cellFs.todo("cellFsStReadGetCurrentAddr(fd=%d, addr=*0x%x, size=*0x%x)", fd, addr, size); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -844,7 +844,7 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr addr, u64 size) { cellFs.todo("cellFsStReadPutCurrentAddr(fd=%d, addr=*0x%x, size=0x%llx)", fd, addr, size); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -860,7 +860,7 @@ s32 cellFsStReadWait(u32 fd, u64 size) { cellFs.todo("cellFsStReadWait(fd=%d, size=0x%llx)", fd, size); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -876,7 +876,7 @@ s32 cellFsStReadWaitCallback(u32 fd, u64 size, vm::ptr { cellFs.todo("cellFsStReadWaitCallback(fd=%d, size=0x%llx, func=*0x%x)", fd, size, func); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -908,7 +908,7 @@ struct fs_aio_thread : ppu_thread s32 error = CELL_EBADF; u64 result = 0; - const auto file = idm::get(aio->fd); + const auto file = idm::get_unlocked(aio->fd); if (!file || (type == 1 && file->flags & CELL_FS_O_WRONLY) || (type == 2 && !(file->flags & CELL_FS_O_ACCMODE))) { diff --git a/rpcs3/Emu/Cell/Modules/cellGame.cpp b/rpcs3/Emu/Cell/Modules/cellGame.cpp index 4ddc29d639..6534d07677 100644 --- a/rpcs3/Emu/Cell/Modules/cellGame.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGame.cpp @@ -961,7 +961,7 @@ error_code cellGameContentPermit(ppu_thread& ppu, vm::ptr> lv2_files; + std::vector> lv2_files; const std::string real_dir = vfs::get(dir) + "/"; diff --git a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp index 44606b7dd1..426d025950 100644 --- a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp @@ -455,7 +455,7 @@ error_code _cellGcmInitBody(ppu_thread& ppu, vm::pptr contex vm::var _tid; vm::var _name = vm::make_str("_gcm_intr_thread"); ppu_execute<&sys_ppu_thread_create>(ppu, +_tid, 0x10000, 0, 1, 0x4000, SYS_PPU_THREAD_CREATE_INTERRUPT, +_name); - render->intr_thread = idm::get>(static_cast(*_tid)); + render->intr_thread = idm::get_unlocked>(static_cast(*_tid)); render->intr_thread->state -= cpu_flag::stop; thread_ctrl::notify(*render->intr_thread); diff --git a/rpcs3/Emu/Cell/Modules/cellGifDec.cpp b/rpcs3/Emu/Cell/Modules/cellGifDec.cpp index 09d7edf8d2..448f86003a 100644 --- a/rpcs3/Emu/Cell/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGifDec.cpp @@ -288,7 +288,7 @@ error_code cellGifDecReadHeader(vm::ptr mainHandle, vm::ptr(fd); + auto file = idm::get_unlocked(fd); file->file.seek(0); file->file.read(buffer, sizeof(buffer)); break; @@ -500,7 +500,7 @@ error_code cellGifDecDecodeData(vm::ptr mainHandle, vm::cptr(fd); + auto file = idm::get_unlocked(fd); file->file.seek(0); file->file.read(gif.get(), fileSize); break; diff --git a/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp b/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp index d1a5ac002d..82ec56727a 100644 --- a/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp @@ -103,7 +103,7 @@ error_code cellJpgDecClose(u32 mainHandle, u32 subHandle) { cellJpgDec.warning("cellJpgDecOpen(mainHandle=0x%x, subHandle=0x%x)", mainHandle, subHandle); - const auto subHandle_data = idm::get(subHandle); + const auto subHandle_data = idm::get_unlocked(subHandle); if (!subHandle_data) { @@ -120,7 +120,7 @@ error_code cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr(subHandle); + const auto subHandle_data = idm::get_unlocked(subHandle); if (!subHandle_data) { @@ -142,7 +142,7 @@ error_code cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr(fd); + auto file = idm::get_unlocked(fd); file->file.seek(0); file->file.read(buffer.get(), fileSize); break; @@ -201,7 +201,7 @@ error_code cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, dataOutInfo->status = CELL_JPGDEC_DEC_STATUS_STOP; - const auto subHandle_data = idm::get(subHandle); + const auto subHandle_data = idm::get_unlocked(subHandle); if (!subHandle_data) { @@ -223,7 +223,7 @@ error_code cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, case CELL_JPGDEC_FILE: { - auto file = idm::get(fd); + auto file = idm::get_unlocked(fd); file->file.seek(0); file->file.read(jpg.get(), fileSize); break; @@ -340,7 +340,7 @@ error_code cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, vm::cptr(subHandle); + const auto subHandle_data = idm::get_unlocked(subHandle); if (!subHandle_data) { diff --git a/rpcs3/Emu/Cell/Modules/cellPngDec.cpp b/rpcs3/Emu/Cell/Modules/cellPngDec.cpp index d792987251..cfb75b611a 100644 --- a/rpcs3/Emu/Cell/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPngDec.cpp @@ -93,7 +93,7 @@ void pngDecReadBuffer(png_structp png_ptr, png_bytep out, png_size_t length) if (buffer.file) { // Get the file - auto file = idm::get(buffer.fd); + auto file = idm::get_unlocked(buffer.fd); // Read the data file->file.read(out, length); diff --git a/rpcs3/Emu/Cell/Modules/cellSearch.cpp b/rpcs3/Emu/Cell/Modules/cellSearch.cpp index 3e0e0abbbc..bcc0151764 100644 --- a/rpcs3/Emu/Cell/Modules/cellSearch.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSearch.cpp @@ -94,11 +94,11 @@ struct search_content_t ENABLE_BITWISE_SERIALIZATION; }; -using content_id_type = std::pair>; +using content_id_type = std::pair>; struct content_id_map { - std::unordered_map> map; + std::unordered_map> map; shared_mutex mutex; @@ -539,7 +539,7 @@ error_code cellSearchStartListSearch(CellSearchListSearchType type, CellSearchSo sysutil_register_cb([=, &content_map = g_fxo->get(), &search](ppu_thread& ppu) -> s32 { - auto curr_search = idm::get(id); + auto curr_search = idm::get_unlocked(id); vm::var resultParam; resultParam->searchId = id; resultParam->resultNum = 0; // Set again later @@ -613,7 +613,7 @@ error_code cellSearchStartListSearch(CellSearchListSearchType type, CellSearchSo auto found = content_map.map.find(hash); if (found == content_map.map.end()) // content isn't yet being tracked { - std::shared_ptr curr_find = std::make_shared(); + shared_ptr curr_find = make_shared(); if (item_path.length() > CELL_SEARCH_PATH_LEN_MAX) { // TODO: Create mapping which will be resolved to an actual hard link in VFS by cellSearchPrepareFile @@ -800,7 +800,7 @@ error_code cellSearchStartContentSearchInList(vm::cptr list sysutil_register_cb([=, list_path = std::string(content_info->infoPath.contentPath), &search, &content_map](ppu_thread& ppu) -> s32 { - auto curr_search = idm::get(id); + auto curr_search = idm::get_unlocked(id); vm::var resultParam; resultParam->searchId = id; resultParam->resultNum = 0; // Set again later @@ -855,7 +855,7 @@ error_code cellSearchStartContentSearchInList(vm::cptr list auto found = content_map.map.find(hash); if (found == content_map.map.end()) // content isn't yet being tracked { - std::shared_ptr curr_find = std::make_shared(); + shared_ptr curr_find = make_shared(); if (item_path.length() > CELL_SEARCH_PATH_LEN_MAX) { // Create mapping which will be resolved to an actual hard link in VFS by cellSearchPrepareFile @@ -1060,7 +1060,7 @@ error_code cellSearchStartContentSearch(CellSearchContentSearchType type, CellSe sysutil_register_cb([=, &content_map = g_fxo->get(), &search](ppu_thread& ppu) -> s32 { - auto curr_search = idm::get(id); + auto curr_search = idm::get_unlocked(id); vm::var resultParam; resultParam->searchId = id; resultParam->resultNum = 0; // Set again later @@ -1096,7 +1096,7 @@ error_code cellSearchStartContentSearch(CellSearchContentSearchType type, CellSe auto found = content_map.map.find(hash); if (found == content_map.map.end()) // content isn't yet being tracked { - std::shared_ptr curr_find = std::make_shared(); + shared_ptr curr_find = make_shared(); if (item_path.length() > CELL_SEARCH_PATH_LEN_MAX) { // Create mapping which will be resolved to an actual hard link in VFS by cellSearchPrepareFile @@ -1372,7 +1372,7 @@ error_code cellSearchGetContentInfoByOffset(CellSearchId searchId, s32 offset, v std::memset(outContentId->data + 4, -1, CELL_SEARCH_CONTENT_ID_SIZE - 4); } - const auto searchObject = idm::get(searchId); + const auto searchObject = idm::get_unlocked(searchId); if (!searchObject) { @@ -1518,7 +1518,7 @@ error_code cellSearchGetOffsetByContentId(CellSearchId searchId, vm::cptr(searchId); + const auto searchObject = idm::get_unlocked(searchId); if (!searchObject) { @@ -1568,7 +1568,7 @@ error_code cellSearchGetContentIdByOffset(CellSearchId searchId, s32 offset, vm: std::memset(outContentId->data + 4, -1, CELL_SEARCH_CONTENT_ID_SIZE - 4); } - const auto searchObject = idm::get(searchId); + const auto searchObject = idm::get_unlocked(searchId); if (!searchObject) { @@ -1663,7 +1663,7 @@ error_code cellSearchGetMusicSelectionContext(CellSearchId searchId, vm::cptrdata, 0, 4); - const auto searchObject = idm::get(searchId); + const auto searchObject = idm::get_unlocked(searchId); if (!searchObject) { @@ -1690,17 +1690,17 @@ error_code cellSearchGetMusicSelectionContext(CellSearchId searchId, vm::cptr std::shared_ptr + const auto get_random_content = [&searchObject, &first_content]() -> shared_ptr { if (searchObject->content_ids.size() == 1) { return first_content; } + std::vector result; std::sample(searchObject->content_ids.begin(), searchObject->content_ids.end(), std::back_inserter(result), 1, std::mt19937{std::random_device{}()}); ensure(result.size() == 1); - std::shared_ptr content = result[0].second; - ensure(!!content); + shared_ptr content = ensure(result[0].second); return content; }; @@ -1736,7 +1736,7 @@ error_code cellSearchGetMusicSelectionContext(CellSearchId searchId, vm::cptr content = get_random_content(); + shared_ptr content = get_random_content(); context.playlist.push_back(content->infoPath.contentPath); cellSearch.notice("cellSearchGetMusicSelectionContext(): Hash=%08X, Assigning random track: Type=0x%x, Path=%s", content_hash, +content->type, context.playlist.back()); } @@ -1757,7 +1757,7 @@ error_code cellSearchGetMusicSelectionContext(CellSearchId searchId, vm::cptr content = get_random_content(); + shared_ptr content = get_random_content(); context.playlist.push_back(content->infoPath.contentPath); cellSearch.notice("cellSearchGetMusicSelectionContext(): Assigning random track: Type=0x%x, Path=%s", +content->type, context.playlist.back()); } @@ -2044,7 +2044,7 @@ error_code cellSearchCancel(CellSearchId searchId) { cellSearch.todo("cellSearchCancel(searchId=0x%x)", searchId); - const auto searchObject = idm::get(searchId); + const auto searchObject = idm::get_unlocked(searchId); if (!searchObject) { @@ -2075,7 +2075,7 @@ error_code cellSearchEnd(CellSearchId searchId) return error; } - const auto searchObject = idm::get(searchId); + const auto searchObject = idm::get_unlocked(searchId); if (!searchObject) { @@ -2120,7 +2120,7 @@ error_code music_selection_context::find_content_id(vm::ptr // Search for the content that matches our current selection auto& content_map = g_fxo->get(); - std::shared_ptr found_content; + shared_ptr found_content; u64 hash = 0; for (const std::string& track : playlist) @@ -2187,7 +2187,7 @@ error_code music_selection_context::find_content_id(vm::ptr } // TODO: check for actual content inside the directory - std::shared_ptr curr_find = std::make_shared(); + shared_ptr curr_find = make_shared(); curr_find->type = CELL_SEARCH_CONTENTTYPE_MUSICLIST; curr_find->repeat_mode = repeat_mode; curr_find->context_option = context_option; @@ -2243,7 +2243,7 @@ error_code music_selection_context::find_content_id(vm::ptr continue; } - std::shared_ptr curr_find = std::make_shared(); + shared_ptr curr_find = make_shared(); curr_find->type = CELL_SEARCH_CONTENTTYPE_MUSIC; curr_find->repeat_mode = repeat_mode; curr_find->context_option = context_option; diff --git a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp index 3d5c535058..8f3469e031 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp @@ -1265,7 +1265,7 @@ s32 _spurs::initialize(ppu_thread& ppu, vm::ptr spurs, u32 revision, } // entry point cannot be initialized immediately because SPU LS will be rewritten by sys_spu_thread_group_start() - //idm::get>(spurs->spus[num])->custom_task = [entry = spurs->spuImg.entry_point](spu_thread& spu) + //idm::get_unlocked>(spurs->spus[num])->custom_task = [entry = spurs->spuImg.entry_point](spu_thread& spu) { // Disabled //spu.RegisterHleFunction(entry, spursKernelEntry); diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index 39d5cee45d..7ba9644d15 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -659,7 +659,7 @@ extern bool check_if_vdec_contexts_exist() extern void vdecEntry(ppu_thread& ppu, u32 vid) { - idm::get(vid)->exec(ppu, vid); + idm::get_unlocked(vid)->exec(ppu, vid); ppu.state += cpu_flag::exit; } @@ -886,7 +886,7 @@ static error_code vdecOpen(ppu_thread& ppu, T type, U res, vm::cptr } // Create decoder context - std::shared_ptr vdec; + shared_ptr vdec; if (std::unique_lock lock{g_fxo->get(), std::try_to_lock}) { @@ -909,7 +909,7 @@ static error_code vdecOpen(ppu_thread& ppu, T type, U res, vm::cptr ppu_execute<&sys_ppu_thread_create>(ppu, +_tid, 0x10000, vid, +res->ppuThreadPriority, +res->ppuThreadStackSize, SYS_PPU_THREAD_CREATE_INTERRUPT, +_name); *handle = vid; - const auto thrd = idm::get>(static_cast(*_tid)); + const auto thrd = idm::get_unlocked>(static_cast(*_tid)); thrd->cmd_list ({ @@ -949,7 +949,7 @@ error_code cellVdecClose(ppu_thread& ppu, u32 handle) return {}; } - auto vdec = idm::get(handle); + auto vdec = idm::get_unlocked(handle); if (!vdec) { @@ -1003,7 +1003,7 @@ error_code cellVdecStartSeq(ppu_thread& ppu, u32 handle) cellVdec.warning("cellVdecStartSeq(handle=0x%x)", handle); - const auto vdec = idm::get(handle); + const auto vdec = idm::get_unlocked(handle); if (!vdec) { @@ -1055,7 +1055,7 @@ error_code cellVdecEndSeq(ppu_thread& ppu, u32 handle) cellVdec.warning("cellVdecEndSeq(handle=0x%x)", handle); - const auto vdec = idm::get(handle); + const auto vdec = idm::get_unlocked(handle); if (!vdec) { @@ -1088,7 +1088,7 @@ error_code cellVdecDecodeAu(ppu_thread& ppu, u32 handle, CellVdecDecodeMode mode cellVdec.trace("cellVdecDecodeAu(handle=0x%x, mode=%d, auInfo=*0x%x)", handle, +mode, auInfo); - const auto vdec = idm::get(handle); + const auto vdec = idm::get_unlocked(handle); if (!vdec || !auInfo || !auInfo->size || !auInfo->startAddr) { @@ -1136,7 +1136,7 @@ error_code cellVdecDecodeAuEx2(ppu_thread& ppu, u32 handle, CellVdecDecodeMode m cellVdec.todo("cellVdecDecodeAuEx2(handle=0x%x, mode=%d, auInfo=*0x%x)", handle, +mode, auInfo); - const auto vdec = idm::get(handle); + const auto vdec = idm::get_unlocked(handle); if (!vdec || !auInfo || !auInfo->size || !auInfo->startAddr) { @@ -1192,7 +1192,7 @@ error_code cellVdecGetPictureExt(ppu_thread& ppu, u32 handle, vm::cptr(handle); + const auto vdec = idm::get_unlocked(handle); if (!vdec || !format) { @@ -1245,7 +1245,7 @@ error_code cellVdecGetPictureExt(ppu_thread& ppu, u32 handle, vm::cptr>(vdec->ppu_tid); + auto vdec_ppu = idm::get_unlocked>(vdec->ppu_tid); if (vdec_ppu) thread_ctrl::notify(*vdec_ppu); } @@ -1354,7 +1354,7 @@ error_code cellVdecGetPicItem(ppu_thread& ppu, u32 handle, vm::pptr(handle); + const auto vdec = idm::get_unlocked(handle); if (!vdec || !picItem) { @@ -1596,7 +1596,7 @@ error_code cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frameRateCode) { cellVdec.trace("cellVdecSetFrameRate(handle=0x%x, frameRateCode=0x%x)", handle, +frameRateCode); - const auto vdec = idm::get(handle); + const auto vdec = idm::get_unlocked(handle); // 0x80 seems like a common prefix if (!vdec || (frameRateCode & 0xf8) != 0x80) @@ -1659,7 +1659,7 @@ error_code cellVdecSetPts(u32 handle, vm::ptr unk) { cellVdec.error("cellVdecSetPts(handle=0x%x, unk=*0x%x)", handle, unk); - const auto vdec = idm::get(handle); + const auto vdec = idm::get_unlocked(handle); if (!vdec || !unk) { diff --git a/rpcs3/Emu/Cell/Modules/cellVpost.cpp b/rpcs3/Emu/Cell/Modules/cellVpost.cpp index 514aad9f7b..773bb96783 100644 --- a/rpcs3/Emu/Cell/Modules/cellVpost.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVpost.cpp @@ -205,7 +205,7 @@ error_code cellVpostClose(u32 handle) { cellVpost.warning("cellVpostClose(handle=0x%x)", handle); - const auto vpost = idm::get(handle); + const auto vpost = idm::get_unlocked(handle); if (!vpost) { @@ -220,7 +220,7 @@ error_code cellVpostExec(u32 handle, vm::cptr inPicBuff, vm::cptr(handle); + const auto vpost = idm::get_unlocked(handle); if (!vpost) { diff --git a/rpcs3/Emu/Cell/Modules/libmixer.cpp b/rpcs3/Emu/Cell/Modules/libmixer.cpp index c9a6f6dca9..e92b5c6cf4 100644 --- a/rpcs3/Emu/Cell/Modules/libmixer.cpp +++ b/rpcs3/Emu/Cell/Modules/libmixer.cpp @@ -510,7 +510,7 @@ s32 cellSurMixerCreate(vm::cptr config) libmixer.warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)", config->chStrips1, config->chStrips2, config->chStrips6, config->chStrips8); - //auto thread = idm::make_ptr("Surmixer Thread"); + //auto thread = idm::make_ptr>("Surmixer Thread"); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index cb1cd0aa29..55b8847934 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -652,7 +652,7 @@ error_code npDrmIsAvailable(vm::cptr k_licensee_addr, vm::cptr drm_pat std::string enc_drm_path; ensure(vm::read_string(drm_path.addr(), 0x100, enc_drm_path, true), "Secret access violation"); - sceNp.warning(u8"npDrmIsAvailable(): drm_path=“%s”", enc_drm_path); + sceNp.warning("npDrmIsAvailable(): drm_path=\"%s\"", enc_drm_path); auto& npdrmkeys = g_fxo->get(); @@ -5347,7 +5347,7 @@ error_code sceNpScoreCreateTransactionCtx(s32 titleCtxId) return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto score = idm::get(titleCtxId); + auto score = idm::get_unlocked(titleCtxId); if (!score) { @@ -5399,24 +5399,12 @@ error_code sceNpScoreSetTimeout(s32 ctxId, usecond_t timeout) return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; } - const u32 idm_id = static_cast(ctxId); - - if (idm_id >= score_transaction_ctx::id_base && idm_id < (score_transaction_ctx::id_base + score_transaction_ctx::id_count)) + if (auto trans = idm::get_unlocked(ctxId)) { - auto trans = idm::get(ctxId); - if (!trans) - { - return SCE_NP_COMMUNITY_ERROR_INVALID_ID; - } trans->timeout = timeout; } - else if (idm_id >= score_ctx::id_base && idm_id < (score_ctx::id_base + score_ctx::id_count)) + else if (auto score = idm::get_unlocked(ctxId)) { - auto score = idm::get(ctxId); - if (!ctxId) - { - return SCE_NP_COMMUNITY_ERROR_INVALID_ID; - } score->timeout = timeout; } else @@ -5443,23 +5431,17 @@ error_code sceNpScoreSetPlayerCharacterId(s32 ctxId, SceNpScorePcId pcId) return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; } - if (static_cast(ctxId) >= score_transaction_ctx::id_base) + if (auto trans = idm::get_unlocked(ctxId)) { - auto trans = idm::get(ctxId); - if (!trans) - { - return SCE_NP_COMMUNITY_ERROR_INVALID_ID; - } trans->pcId = pcId; } + else if (auto score = idm::get_unlocked(ctxId)) + { + score->pcId = pcId; + } else { - auto score = idm::get(ctxId); - if (!ctxId) - { - return SCE_NP_COMMUNITY_ERROR_INVALID_ID; - } - score->pcId = pcId; + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; } return CELL_OK; @@ -5476,7 +5458,7 @@ error_code sceNpScoreWaitAsync(s32 transId, vm::ptr result) return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; } - auto trans = idm::get(transId); + auto trans = idm::get_unlocked(transId); if (!trans) { return SCE_NP_COMMUNITY_ERROR_INVALID_ID; @@ -5498,7 +5480,7 @@ error_code sceNpScorePollAsync(s32 transId, vm::ptr result) return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; } - auto trans = idm::get(transId); + auto trans = idm::get_unlocked(transId); if (!trans) { return SCE_NP_COMMUNITY_ERROR_INVALID_ID; @@ -5515,9 +5497,9 @@ error_code sceNpScorePollAsync(s32 transId, vm::ptr result) return CELL_OK; } -std::pair, std::shared_ptr> get_score_transaction_context(s32 transId, bool reset_transaction = true) +std::pair, shared_ptr> get_score_transaction_context(s32 transId, bool reset_transaction = true) { - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -6217,7 +6199,7 @@ error_code sceNpScoreAbortTransaction(s32 transId) return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; } - auto trans = idm::get(transId); + auto trans = idm::get_unlocked(transId); if (!trans) { return SCE_NP_COMMUNITY_ERROR_INVALID_ID; diff --git a/rpcs3/Emu/Cell/Modules/sceNp.h b/rpcs3/Emu/Cell/Modules/sceNp.h index 1adffccc5f..e6a1bdc7ea 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.h +++ b/rpcs3/Emu/Cell/Modules/sceNp.h @@ -1837,7 +1837,7 @@ public: virtual ~RecvMessageDialogBase() = default; virtual error_code Exec(SceNpBasicMessageMainType type, SceNpBasicMessageRecvOptions options, SceNpBasicMessageRecvAction& recv_result, u64& chosen_msg_id) = 0; - virtual void callback_handler(const std::shared_ptr> new_msg, u64 msg_id) = 0; + virtual void callback_handler(const shared_ptr> new_msg, u64 msg_id) = 0; protected: std::shared_ptr m_rpcn; diff --git a/rpcs3/Emu/Cell/Modules/sceNpSns.cpp b/rpcs3/Emu/Cell/Modules/sceNpSns.cpp index 8de5e689c2..7a77d6c281 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpSns.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpSns.cpp @@ -139,7 +139,7 @@ error_code sceNpSnsFbAbortHandle(u32 handle) return SCE_NP_SNS_ERROR_INVALID_ARGUMENT; } - const auto sfh = idm::get(handle); + const auto sfh = idm::get_unlocked(handle); if (!sfh) { @@ -172,7 +172,7 @@ error_code sceNpSnsFbGetAccessToken(u32 handle, vm::cptr(handle); + const auto sfh = idm::get_unlocked(handle); if (!sfh) { @@ -200,7 +200,7 @@ s32 sceNpSnsFbStreamPublish(u32 handle) // add more arguments return SCE_NP_SNS_ERROR_INVALID_ARGUMENT; } - const auto sfh = idm::get(handle); + const auto sfh = idm::get_unlocked(handle); if (!sfh) { @@ -258,7 +258,7 @@ s32 sceNpSnsFbLoadThrottle(u32 handle) return SCE_NP_SNS_ERROR_INVALID_ARGUMENT; } - const auto sfh = idm::get(handle); + const auto sfh = idm::get_unlocked(handle); if (!sfh) { @@ -299,7 +299,7 @@ error_code sceNpSnsFbGetLongAccessToken(u32 handle, vm::cptr(handle); + const auto sfh = idm::get_unlocked(handle); if (!sfh) { diff --git a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp index 15a0cc6679..e7e9d308a0 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp @@ -123,7 +123,7 @@ struct sce_np_trophy_manager return res; } - ctxt = idm::check(context); + ctxt = idm::check_unlocked(context); if (!ctxt) { @@ -144,7 +144,7 @@ struct sce_np_trophy_manager return res; } - const auto hndl = idm::check(handle); + const auto hndl = idm::check_unlocked(handle); if (!hndl) { @@ -409,7 +409,7 @@ error_code sceNpTrophyAbortHandle(u32 handle) return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT; } - const auto hndl = idm::check(handle); + const auto hndl = idm::check_unlocked(handle); if (!hndl) { @@ -552,7 +552,7 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle, } const auto [ctxt, error] = trophy_manager.get_context_ex(context, handle, true); - const auto handle_ptr = idm::get(handle); + const auto handle_ptr = idm::get_unlocked(handle); if (error) { @@ -641,7 +641,7 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle, return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; } - if (handle_ptr.get() != idm::check(handle)) + if (handle_ptr.get() != idm::check_unlocked(handle)) { on_error(); return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE; @@ -716,7 +716,6 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle, // Create a counter which is destroyed after the function ends const auto queued = std::make_shared>(0); - std::weak_ptr> wkptr = queued; for (auto status : statuses) { @@ -724,12 +723,11 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle, *queued += status.second; for (s32 completed = 0; completed <= status.second; completed++) { - sysutil_register_cb([statusCb, status, context, completed, arg, wkptr](ppu_thread& cb_ppu) -> s32 + sysutil_register_cb([statusCb, status, context, completed, arg, queued](ppu_thread& cb_ppu) -> s32 { // TODO: it is possible that we need to check the return value here as well. statusCb(cb_ppu, context, status.first, completed, status.second, arg); - const auto queued = wkptr.lock(); if (queued && (*queued)-- == 1) { queued->notify_one(); diff --git a/rpcs3/Emu/Cell/Modules/sceNpTus.cpp b/rpcs3/Emu/Cell/Modules/sceNpTus.cpp index 77057a1ad7..ee82e1093e 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTus.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTus.cpp @@ -133,7 +133,7 @@ error_code sceNpTusCreateTransactionCtx(s32 titleCtxId) return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto tus = idm::get(titleCtxId); + auto tus = idm::get_unlocked(titleCtxId); if (!tus) { @@ -185,24 +185,12 @@ error_code sceNpTusSetTimeout(s32 ctxId, u32 timeout) return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; } - const u32 idm_id = static_cast(ctxId); - - if (idm_id >= tus_transaction_ctx::id_base && idm_id < (tus_transaction_ctx::id_base + tus_transaction_ctx::id_count)) + if (auto trans = idm::get_unlocked(ctxId)) { - auto trans = idm::get(ctxId); - if (!trans) - { - return SCE_NP_COMMUNITY_ERROR_INVALID_ID; - } trans->timeout = timeout; } - else if (idm_id >= tus_ctx::id_base && idm_id < (tus_ctx::id_base + tus_ctx::id_count)) + else if (auto tus = idm::get_unlocked(ctxId)) { - auto tus = idm::get(ctxId); - if (!ctxId) - { - return SCE_NP_COMMUNITY_ERROR_INVALID_ID; - } tus->timeout = timeout; } else @@ -224,7 +212,7 @@ error_code sceNpTusAbortTransaction(s32 transId) return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; } - auto trans = idm::get(transId); + auto trans = idm::get_unlocked(transId); if (!trans) { return SCE_NP_COMMUNITY_ERROR_INVALID_ID; @@ -246,7 +234,7 @@ error_code sceNpTusWaitAsync(s32 transId, vm::ptr result) return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; } - auto trans = idm::get(transId); + auto trans = idm::get_unlocked(transId); if (!trans) { return SCE_NP_COMMUNITY_ERROR_INVALID_ID; @@ -268,7 +256,7 @@ error_code sceNpTusPollAsync(s32 transId, vm::ptr result) return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; } - auto trans = idm::get(transId); + auto trans = idm::get_unlocked(transId); if (!trans) { return SCE_NP_COMMUNITY_ERROR_INVALID_ID; @@ -326,7 +314,7 @@ error_code scenp_tus_set_multislot_variable(s32 transId, T targetNpId, vm::cptr< return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -413,7 +401,7 @@ error_code scenp_tus_get_multislot_variable(s32 transId, T targetNpId, vm::cptr< return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -500,7 +488,7 @@ error_code scenp_tus_get_multiuser_variable(s32 transId, T targetNpIdArray, SceN return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -599,7 +587,7 @@ error_code scenp_tus_get_friends_variable(s32 transId, SceNpTusSlotId slotId, s3 return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -659,7 +647,7 @@ error_code scenp_tus_add_and_get_variable(s32 transId, T targetNpId, SceNpTusSlo return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -736,7 +724,7 @@ error_code scenp_tus_try_and_set_variable(s32 transId, T targetNpId, SceNpTusSlo return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -813,7 +801,7 @@ error_code scenp_tus_delete_multislot_variable(s32 transId, T targetNpId, vm::cp return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -885,7 +873,7 @@ error_code scenp_tus_set_data(s32 transId, T targetNpId, SceNpTusSlotId slotId, return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -957,7 +945,7 @@ error_code scenp_tus_get_data(s32 transId, T targetNpId, SceNpTusSlotId slotId, return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -1044,7 +1032,7 @@ error_code scenp_tus_get_multislot_data_status(s32 transId, T targetNpId, vm::cp return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -1131,7 +1119,7 @@ error_code scenp_tus_get_multiuser_data_status(s32 transId, T targetNpIdArray, S return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -1230,7 +1218,7 @@ error_code scenp_tus_get_friends_data_status(s32 transId, SceNpTusSlotId slotId, return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - auto trans_ctx = idm::get(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -1295,7 +1283,7 @@ error_code scenp_tus_delete_multislot_data(s32 transId, T targetNpId, vm::cptr(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -1337,7 +1325,7 @@ error_code sceNpTusDeleteMultiSlotDataVUserAsync(s32 transId, vm::cptr& trans, vm::ptr dataStatus) +void scenp_tss_no_file(const shared_ptr& trans, vm::ptr dataStatus) { // TSS are files stored on PSN by developers, no dumps available atm std::memset(dataStatus.get_ptr(), 0, sizeof(SceNpTssDataStatus)); @@ -1365,7 +1353,7 @@ error_code sceNpTssGetData(s32 transId, SceNpTssSlotId slotId, vm::ptr(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { @@ -1398,7 +1386,7 @@ error_code sceNpTssGetDataAsync(s32 transId, SceNpTssSlotId slotId, vm::ptr(transId); + auto trans_ctx = idm::get_unlocked(transId); if (!trans_ctx) { diff --git a/rpcs3/Emu/Cell/Modules/sys_io_.cpp b/rpcs3/Emu/Cell/Modules/sys_io_.cpp index e0505f4c41..5f767ebae4 100644 --- a/rpcs3/Emu/Cell/Modules/sys_io_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_io_.cpp @@ -51,7 +51,7 @@ void config_event_entry(ppu_thread& ppu) } const u32 queue_id = cfg.queue_id; - auto queue = idm::get(queue_id); + auto queue = idm::get_unlocked(queue_id); while (queue && sys_event_queue_receive(ppu, queue_id, vm::null, 0) == CELL_OK) { @@ -81,7 +81,7 @@ void config_event_entry(ppu_thread& ppu) if (!queue->exists) { // Exit condition - queue = nullptr; + queue = null_ptr; break; } @@ -134,7 +134,7 @@ extern void send_sys_io_connect_event(usz index, u32 state) if (cfg.init_ctr) { - if (auto port = idm::get(cfg.queue_id)) + if (auto port = idm::get_unlocked(cfg.queue_id)) { port->send(0, 1, index, state); } diff --git a/rpcs3/Emu/Cell/Modules/sys_mempool.cpp b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp index ad70cc173e..b7ffa72984 100644 --- a/rpcs3/Emu/Cell/Modules/sys_mempool.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp @@ -60,7 +60,7 @@ error_code sys_mempool_create(ppu_thread& ppu, vm::ptr mempool, v auto id = idm::make(); *mempool = id; - auto memory_pool = idm::get(id); + auto memory_pool = idm::get_unlocked(id); memory_pool->chunk = chunk; memory_pool->chunk_size = chunk_size; @@ -114,7 +114,7 @@ void sys_mempool_destroy(ppu_thread& ppu, sys_mempool_t mempool) { sysPrxForUser.warning("sys_mempool_destroy(mempool=%d)", mempool); - auto memory_pool = idm::get(mempool); + auto memory_pool = idm::get_unlocked(mempool); if (memory_pool) { u32 condid = memory_pool->condid; @@ -136,7 +136,7 @@ error_code sys_mempool_free_block(ppu_thread& ppu, sys_mempool_t mempool, vm::pt { sysPrxForUser.warning("sys_mempool_free_block(mempool=%d, block=*0x%x)", mempool, block); - auto memory_pool = idm::get(mempool); + auto memory_pool = idm::get_unlocked(mempool); if (!memory_pool) { return CELL_EINVAL; @@ -160,7 +160,7 @@ u64 sys_mempool_get_count(ppu_thread& ppu, sys_mempool_t mempool) { sysPrxForUser.warning("sys_mempool_get_count(mempool=%d)", mempool); - auto memory_pool = idm::get(mempool); + auto memory_pool = idm::get_unlocked(mempool); if (!memory_pool) { return CELL_EINVAL; @@ -175,7 +175,7 @@ vm::ptr sys_mempool_allocate_block(ppu_thread& ppu, sys_mempool_t mempool) { sysPrxForUser.warning("sys_mempool_allocate_block(mempool=%d)", mempool); - auto memory_pool = idm::get(mempool); + auto memory_pool = idm::get_unlocked(mempool); if (!memory_pool) { // if the memory pool gets deleted-- is null, clearly it's impossible to allocate memory. return vm::null; @@ -185,7 +185,7 @@ vm::ptr sys_mempool_allocate_block(ppu_thread& ppu, sys_mempool_t mempool) while (memory_pool->free_blocks.empty()) // while is to guard against spurious wakeups { sys_cond_wait(ppu, memory_pool->condid, 0); - memory_pool = idm::get(mempool); + memory_pool = idm::get_unlocked(mempool); if (!memory_pool) // in case spurious wake up was from delete, don't die by accessing a freed pool. { // No need to unlock as if the pool is freed, the lock was freed as well. return vm::null; @@ -202,7 +202,7 @@ vm::ptr sys_mempool_try_allocate_block(ppu_thread& ppu, sys_mempool_t memp { sysPrxForUser.warning("sys_mempool_try_allocate_block(mempool=%d)", mempool); - auto memory_pool = idm::get(mempool); + auto memory_pool = idm::get_unlocked(mempool); if (!memory_pool || memory_pool->free_blocks.empty()) { diff --git a/rpcs3/Emu/Cell/PPUAnalyser.cpp b/rpcs3/Emu/Cell/PPUAnalyser.cpp index 8d948cc972..1bab12a109 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.cpp +++ b/rpcs3/Emu/Cell/PPUAnalyser.cpp @@ -1,6 +1,8 @@ #include "stdafx.h" #include "PPUAnalyser.h" +#include "lv2/sys_sync.h" + #include "PPUOpcodes.h" #include "PPUThread.h" @@ -37,7 +39,8 @@ void fmt_class_string>::format(std::string& out, u64 arg) format_bitset(out, arg, "[", ",", "]", &fmt_class_string::format); } -void ppu_module::validate(u32 reloc) +template <> +void ppu_module::validate(u32 reloc) { // Load custom PRX configuration if available if (fs::file yml{path + ".yml"}) @@ -529,7 +532,8 @@ namespace ppu_patterns }; } -bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::vector& applied, const std::vector& exported_funcs, std::function check_aborted) +template <> +bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::vector& applied, const std::vector& exported_funcs, std::function check_aborted) { if (segs.empty()) { diff --git a/rpcs3/Emu/Cell/PPUAnalyser.h b/rpcs3/Emu/Cell/PPUAnalyser.h index 287418e802..87a6de04d7 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.h +++ b/rpcs3/Emu/Cell/PPUAnalyser.h @@ -72,8 +72,11 @@ struct ppu_segment }; // PPU Module Information -struct ppu_module +template +struct ppu_module : public Type { + using Type::Type; + ppu_module() noexcept = default; ppu_module(const ppu_module&) = delete; @@ -177,7 +180,8 @@ struct ppu_module } }; -struct main_ppu_module : public ppu_module +template +struct main_ppu_module : public ppu_module { u32 elf_entry{}; u32 seg0_code_end{}; diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index b82b6f5b29..d26f060b7d 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -576,7 +576,7 @@ extern const std::unordered_map& get_exported_function_na } // Resolve relocations for variable/function linkage. -static void ppu_patch_refs(const ppu_module& _module, std::vector* out_relocs, u32 fref, u32 faddr) +static void ppu_patch_refs(const ppu_module& _module, std::vector* out_relocs, u32 fref, u32 faddr) { struct ref_t { @@ -704,7 +704,7 @@ extern bool ppu_register_library_lock(std::string_view libname, bool lock_lib) } // Load and register exports; return special exports found (nameless module) -static auto ppu_load_exports(const ppu_module& _module, ppu_linkage_info* link, u32 exports_start, u32 exports_end, bool for_observing_callbacks = false, std::vector* funcs = nullptr, std::basic_string* loaded_flags = nullptr) +static auto ppu_load_exports(const ppu_module& _module, ppu_linkage_info* link, u32 exports_start, u32 exports_end, bool for_observing_callbacks = false, std::vector* funcs = nullptr, std::basic_string* loaded_flags = nullptr) { std::unordered_map result; @@ -803,7 +803,7 @@ static auto ppu_load_exports(const ppu_module& _module, ppu_linkage_info* link, const auto fnids = +lib.nids; const auto faddrs = +lib.addrs; - u32 previous_rtoc = umax; + u64 previous_rtoc = umax; // Get functions for (u32 i = 0, end = lib.num_func; i < end; i++) @@ -816,21 +816,22 @@ static auto ppu_load_exports(const ppu_module& _module, ppu_linkage_info* link, { if (previous_rtoc == fdata.rtoc) { - ppu_loader.notice("**** %s export: [%s] (0x%08x) at 0x%x [at:0x%x] rtoc=same", module_name, ppu_get_function_name(module_name, fnid), fnid, faddr, fdata.addr); + // Shortened printing, replacement string is 10 characters as 0x%08x + ppu_loader.notice("**** %s export: (0x%08x) at 0x%07x [at:0x%07x, rtoc:same-above]: %s", module_name, fnid, faddr, fdata.addr, ppu_get_function_name(module_name, fnid)); } else { previous_rtoc = fdata.rtoc; - ppu_loader.notice("**** %s export: [%s] (0x%08x) at 0x%x [at:0x%x] rtoc=0x%x", module_name, ppu_get_function_name(module_name, fnid), fnid, faddr, fdata.addr, fdata.rtoc); + ppu_loader.notice("**** %s export: (0x%08x) at 0x%07x [at:0x%07x, rtoc:0x%08x]: %s", module_name, fnid, faddr, fdata.addr, fdata.rtoc, ppu_get_function_name(module_name, fnid)); } } else if (fptr) { - ppu_loader.error("**** %s export: [%s] (0x%08x) at 0x%x [Invalid Function Address: 0x%x!]", module_name, ppu_get_function_name(module_name, fnid), fnid, faddr, fdata.addr); + ppu_loader.error("**** %s export: (0x%08x) at 0x%07x [Invalid Function Address: 0x%07x!]: '%s'", module_name, fnid, faddr, fdata.addr, ppu_get_function_name(module_name, fnid)); } else { - ppu_loader.warning("**** %s export: [%s] (0x%08x) at 0x%x [Illegal Descriptor Address!]", module_name, ppu_get_function_name(module_name, fnid), fnid, faddr); + ppu_loader.warning("**** %s export: (0x%08x) at 0x%07x [Illegal Descriptor Address!]: '%s'", module_name, fnid, faddr, ppu_get_function_name(module_name, fnid)); } if (funcs) @@ -938,7 +939,7 @@ static auto ppu_load_exports(const ppu_module& _module, ppu_linkage_info* link, return result; } -static auto ppu_load_imports(const ppu_module& _module, std::vector& relocs, ppu_linkage_info* link, u32 imports_start, u32 imports_end) +static auto ppu_load_imports(const ppu_module& _module, std::vector& relocs, ppu_linkage_info* link, u32 imports_start, u32 imports_end) { std::unordered_map result; @@ -1030,10 +1031,10 @@ static auto ppu_load_imports(const ppu_module& _module, std::vector& // For _sys_prx_register_module void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string& loaded_flags) { - auto& _main = g_fxo->get(); + auto& _main = g_fxo->get>(); auto& link = g_fxo->get(); - ppu_module vm_all_fake_module{}; + ppu_module vm_all_fake_module{}; vm_all_fake_module.segs.emplace_back(ppu_segment{0x10000, 0 - 0x10000u, 1 /*LOAD*/, 0, 0 - 0x1000u, vm::base(0x10000)}); vm_all_fake_module.addr_to_seg_index.emplace(0x10000, 0); @@ -1130,7 +1131,7 @@ void init_ppu_functions(utils::serial* ar, bool full = false) } } -static void ppu_check_patch_spu_images(const ppu_module& mod, const ppu_segment& seg) +static void ppu_check_patch_spu_images(const ppu_module& mod, const ppu_segment& seg) { if (!seg.size) { @@ -1139,7 +1140,7 @@ static void ppu_check_patch_spu_images(const ppu_module& mod, const ppu_segment& const bool is_firmware = mod.path.starts_with(vfs::get("/dev_flash/")); - const auto _main = g_fxo->try_get(); + const auto _main = g_fxo->try_get>(); const std::string_view seg_view{ensure(mod.get_ptr(seg.addr)), seg.size}; @@ -1430,10 +1431,10 @@ static void ppu_check_patch_spu_images(const ppu_module& mod, const ppu_segment& } } -void try_spawn_ppu_if_exclusive_program(const ppu_module& m) +void try_spawn_ppu_if_exclusive_program(const ppu_module& m) { // If only PRX/OVL has been loaded at Emu.BootGame(), launch a single PPU thread so its memory can be viewed - if (Emu.IsReady() && g_fxo->get().segs.empty() && !Emu.DeserialManager()) + if (Emu.IsReady() && g_fxo->get>().segs.empty() && !Emu.DeserialManager()) { ppu_thread_params p { @@ -1521,15 +1522,15 @@ const char* get_prx_name_by_cia(u32 addr) return nullptr; } -std::shared_ptr ppu_load_prx(const ppu_prx_object& elf, bool virtual_load, const std::string& path, s64 file_offset, utils::serial* ar) +shared_ptr ppu_load_prx(const ppu_prx_object& elf, bool virtual_load, const std::string& path, s64 file_offset, utils::serial* ar) { if (elf != elf_error::ok) { - return nullptr; + return null_ptr; } // Create new PRX object - const auto prx = !ar && !virtual_load ? idm::make_ptr() : std::make_shared(); + const auto prx = !ar && !virtual_load ? idm::make_ptr() : make_shared(); // Access linkage information object auto& link = g_fxo->get(); @@ -2054,7 +2055,7 @@ bool ppu_load_exec(const ppu_exec_object& elf, bool virtual_load, const std::str init_ppu_functions(ar, false); // Set for delayed initialization in ppu_initialize() - auto& _main = g_fxo->get(); + auto& _main = g_fxo->get>(); // Access linkage information object auto& link = g_fxo->get(); @@ -2080,7 +2081,7 @@ bool ppu_load_exec(const ppu_exec_object& elf, bool virtual_load, const std::str struct on_fatal_error { - ppu_module& _main; + ppu_module& _main; bool errored = true; ~on_fatal_error() @@ -2498,7 +2499,7 @@ bool ppu_load_exec(const ppu_exec_object& elf, bool virtual_load, const std::str } // Initialize process - std::vector> loaded_modules; + std::vector> loaded_modules; // Module list to load at startup std::set load_libs; @@ -2778,11 +2779,11 @@ bool ppu_load_exec(const ppu_exec_object& elf, bool virtual_load, const std::str return true; } -std::pair, CellError> ppu_load_overlay(const ppu_exec_object& elf, bool virtual_load, const std::string& path, s64 file_offset, utils::serial* ar) +std::pair, CellError> ppu_load_overlay(const ppu_exec_object& elf, bool virtual_load, const std::string& path, s64 file_offset, utils::serial* ar) { if (elf != elf_error::ok) { - return {nullptr, CELL_ENOENT}; + return {null_ptr, CELL_ENOENT}; } // Access linkage information object @@ -2804,12 +2805,12 @@ std::pair, CellError> ppu_load_overlay(const ppu_ex if (!r.valid() || !r.inside(addr_range::start_length(0x30000000, 0x10000000))) { // TODO: Check error and if there's a better way to error check - return {nullptr, CELL_ENOEXEC}; + return {null_ptr, CELL_ENOEXEC}; } } } - std::shared_ptr ovlm = std::make_shared(); + shared_ptr ovlm = make_shared(); // Set path (TODO) ovlm->name = path.substr(path.find_last_of('/') + 1); @@ -2859,7 +2860,7 @@ std::pair, CellError> ppu_load_overlay(const ppu_ex if (!vm::check_addr(addr, vm::page_readable, size)) { ppu_loader.error("ppu_load_overlay(): Archived PPU overlay memory has not been found! (addr=0x%x, memsz=0x%x)", addr, size); - return {nullptr, CELL_EABORT}; + return {null_ptr, CELL_EABORT}; } } else if (!vm::get(vm::any, 0x30000000)->falloc(addr, size)) @@ -2873,7 +2874,7 @@ std::pair, CellError> ppu_load_overlay(const ppu_ex } // TODO: Check error code, maybe disallow more than one overlay instance completely - return {nullptr, CELL_EBUSY}; + return {null_ptr, CELL_EBUSY}; } // Store only LOAD segments (TODO) @@ -3088,7 +3089,7 @@ std::pair, CellError> ppu_load_overlay(const ppu_ex return !!(cpu->state & cpu_flag::exit); })) { - return {nullptr, CellError{CELL_CANCEL + 0u}}; + return {null_ptr, CellError{CELL_CANCEL + 0u}}; } // Validate analyser results (not required) @@ -3105,11 +3106,11 @@ std::pair, CellError> ppu_load_overlay(const ppu_ex bool ppu_load_rel_exec(const ppu_rel_object& elf) { - ppu_module relm{}; + ppu_module relm{}; struct on_fatal_error { - ppu_module& relm; + ppu_module& relm; bool errored = true; ~on_fatal_error() diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 50fdca7643..8001b95ac4 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -174,13 +174,13 @@ bool serialize(utils::serial& ar, typename ppu_thread::cr_b } extern void ppu_initialize(); -extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false); -extern bool ppu_initialize(const ppu_module& info, bool check_only = false, u64 file_size = 0); -static void ppu_initialize2(class jit_compiler& jit, const ppu_module& module_part, const std::string& cache_path, const std::string& obj_name, const ppu_module& whole_module); +extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false); +extern bool ppu_initialize(const ppu_module& info, bool check_only = false, u64 file_size = 0); +static void ppu_initialize2(class jit_compiler& jit, const ppu_module& module_part, const std::string& cache_path, const std::string& obj_name, const ppu_module& whole_module); extern bool ppu_load_exec(const ppu_exec_object&, bool virtual_load, const std::string&, utils::serial* = nullptr); -extern std::pair, CellError> ppu_load_overlay(const ppu_exec_object&, bool virtual_load, const std::string& path, s64 file_offset, utils::serial* = nullptr); +extern std::pair, CellError> ppu_load_overlay(const ppu_exec_object&, bool virtual_load, const std::string& path, s64 file_offset, utils::serial* = nullptr); extern void ppu_unload_prx(const lv2_prx&); -extern std::shared_ptr ppu_load_prx(const ppu_prx_object&, bool virtual_load, const std::string&, s64 file_offset, utils::serial* = nullptr); +extern shared_ptr ppu_load_prx(const ppu_prx_object&, bool virtual_load, const std::string&, s64 file_offset, utils::serial* = nullptr); extern void ppu_execute_syscall(ppu_thread& ppu, u64 code); static void ppu_break(ppu_thread&, ppu_opcode_t, be_t*, ppu_intrp_func*); @@ -550,7 +550,7 @@ u32 ppu_read_mmio_aware_u32(u8* vm_base, u32 eal) if (eal >= RAW_SPU_BASE_ADDR) { // RawSPU MMIO - auto thread = idm::get>(spu_thread::find_raw_spu((eal - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET)); + auto thread = idm::get_unlocked>(spu_thread::find_raw_spu((eal - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET)); if (!thread) { @@ -578,7 +578,7 @@ void ppu_write_mmio_aware_u32(u8* vm_base, u32 eal, u32 value) if (eal >= RAW_SPU_BASE_ADDR) { // RawSPU MMIO - auto thread = idm::get>(spu_thread::find_raw_spu((eal - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET)); + auto thread = idm::get_unlocked>(spu_thread::find_raw_spu((eal - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET)); if (!thread) { @@ -3450,7 +3450,7 @@ static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value) { if (count > 20000 && g_cfg.core.perf_report) [[unlikely]] { - perf_log.warning(u8"STCX: took too long: %.3fµs (%u c)", count / (utils::get_tsc_freq() / 1000'000.), count); + perf_log.warning("STCX: took too long: %.3fus (%u c)", count / (utils::get_tsc_freq() / 1000'000.), count); } break; @@ -3837,7 +3837,7 @@ extern fs::file make_file_view(fs::file&& _file, u64 offset, u64 max_size = umax return file; } -extern void ppu_finalize(const ppu_module& info, bool force_mem_release) +extern void ppu_finalize(const ppu_module& info, bool force_mem_release) { if (info.segs.empty()) { @@ -3885,7 +3885,7 @@ extern void ppu_finalize(const ppu_module& info, bool force_mem_release) #endif } -extern void ppu_precompile(std::vector& dir_queue, std::vector* loaded_modules) +extern void ppu_precompile(std::vector& dir_queue, std::vector*>* loaded_modules) { if (g_cfg.core.ppu_decoder != ppu_decoder_type::llvm) { @@ -3978,7 +3978,7 @@ extern void ppu_precompile(std::vector& dir_queue, std::vectorbegin(), loaded_modules->end(), [&](ppu_module* obj) + if (std::any_of(loaded_modules->begin(), loaded_modules->end(), [&](ppu_module* obj) { return obj->name == entry.name; })) @@ -4311,7 +4311,7 @@ extern void ppu_precompile(std::vector& dir_queue, std::vectorget()); + auto main_module = std::move(g_fxo->get>()); for (; slice; slice.pop_front(), g_progr_fdone++) { @@ -4348,7 +4348,7 @@ extern void ppu_precompile(std::vector& dir_queue, std::vectorget(); + main_ppu_module& _main = g_fxo->get>(); _main = {}; auto current_cache = std::move(g_fxo->get()); @@ -4393,7 +4393,7 @@ extern void ppu_precompile(std::vector& dir_queue, std::vectorget() = std::move(main_module); + g_fxo->get>() = std::move(main_module); g_fxo->get().collect_funcs_to_precompile = true; Emu.ConfigurePPUCache(); }); @@ -4403,7 +4403,7 @@ extern void ppu_precompile(std::vector& dir_queue, std::vectoris_init()) + if (!g_fxo->is_init>()) { return; } @@ -4413,7 +4413,7 @@ extern void ppu_initialize() return; } - auto& _main = g_fxo->get(); + auto& _main = g_fxo->get>(); std::optional progress_dialog(std::in_place, get_localized_string(localized_string_id::PROGRESS_DIALOG_ANALYZING_PPU_EXECUTABLE)); @@ -4436,7 +4436,7 @@ extern void ppu_initialize() compile_main = ppu_initialize(_main, true); } - std::vector module_list; + std::vector*> module_list; const std::string firmware_sprx_path = vfs::get("/dev_flash/sys/external/"); @@ -4541,7 +4541,7 @@ extern void ppu_initialize() } } -bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size) +bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size) { if (g_cfg.core.ppu_decoder != ppu_decoder_type::llvm) { @@ -4668,7 +4668,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size) const u32 reloc = info.relocs.empty() ? 0 : ::at32(info.segs, 0).addr; // Info sent to threads - std::vector> workload; + std::vector>> workload; // Info to load to main JIT instance (true - compiled) std::vector> link_workload; @@ -4733,7 +4733,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size) } // Copy module information (TODO: optimize) - ppu_module part; + ppu_module part; part.copy_part(info); part.funcs.reserve(16000); @@ -5035,15 +5035,15 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size) struct thread_op { atomic_t& work_cv; - std::vector>& workload; - const ppu_module& main_module; + std::vector>>& workload; + const ppu_module& main_module; const std::string& cache_path; const cpu_thread* cpu; std::unique_lock core_lock; - thread_op(atomic_t& work_cv, std::vector>& workload - , const cpu_thread* cpu, const ppu_module& main_module, const std::string& cache_path, decltype(jit_core_allocator::sem)& sem) noexcept + thread_op(atomic_t& work_cv, std::vector>>& workload + , const cpu_thread* cpu, const ppu_module& main_module, const std::string& cache_path, decltype(jit_core_allocator::sem)& sem) noexcept : work_cv(work_cv) , workload(workload) @@ -5257,7 +5257,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size) #endif } -static void ppu_initialize2(jit_compiler& jit, const ppu_module& module_part, const std::string& cache_path, const std::string& obj_name, const ppu_module& whole_module) +static void ppu_initialize2(jit_compiler& jit, const ppu_module& module_part, const std::string& cache_path, const std::string& obj_name, const ppu_module& whole_module) { #ifdef LLVM_AVAILABLE using namespace llvm; diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index c2102af38f..edbb4f515a 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -3,6 +3,7 @@ #include "Emu/system_config.h" #include "Emu/Cell/Common.h" +#include "Emu/Cell/lv2/sys_sync.h" #include "PPUTranslator.h" #include "PPUThread.h" #include "SPUThread.h" @@ -28,7 +29,7 @@ const ppu_decoder s_ppu_decoder; extern const ppu_decoder g_ppu_itype; extern const ppu_decoder g_ppu_iname; -PPUTranslator::PPUTranslator(LLVMContext& context, Module* _module, const ppu_module& info, ExecutionEngine& engine) +PPUTranslator::PPUTranslator(LLVMContext& context, Module* _module, const ppu_module& info, ExecutionEngine& engine) : cpu_translator(_module, false) , m_info(info) , m_pure_attr() @@ -322,7 +323,7 @@ Function* PPUTranslator::Translate(const ppu_function& info) return m_function; } -Function* PPUTranslator::GetSymbolResolver(const ppu_module& info) +Function* PPUTranslator::GetSymbolResolver(const ppu_module& info) { m_function = cast(m_module->getOrInsertFunction("__resolve_symbols", FunctionType::get(get_type(), { get_type(), get_type() }, false)).getCallee()); diff --git a/rpcs3/Emu/Cell/PPUTranslator.h b/rpcs3/Emu/Cell/PPUTranslator.h index a71e42a033..010945656e 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.h +++ b/rpcs3/Emu/Cell/PPUTranslator.h @@ -8,10 +8,15 @@ #include "util/types.hpp" +template +struct ppu_module; + +struct lv2_obj; + class PPUTranslator final : public cpu_translator { // PPU Module - const ppu_module& m_info; + const ppu_module& m_info; // Relevant relocations std::map m_relocs; @@ -331,7 +336,7 @@ public: // Handle compilation errors void CompilationError(const std::string& error); - PPUTranslator(llvm::LLVMContext& context, llvm::Module* _module, const ppu_module& info, llvm::ExecutionEngine& engine); + PPUTranslator(llvm::LLVMContext& context, llvm::Module* _module, const ppu_module& info, llvm::ExecutionEngine& engine); ~PPUTranslator(); // Get thread context struct type @@ -339,7 +344,7 @@ public: // Parses PPU opcodes and translate them into LLVM IR llvm::Function* Translate(const ppu_function& info); - llvm::Function* GetSymbolResolver(const ppu_module& info); + llvm::Function* GetSymbolResolver(const ppu_module& info); void MFVSCR(ppu_opcode_t op); void MTVSCR(ppu_opcode_t op); diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 21a739664e..456c9894be 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -2415,7 +2415,7 @@ void spu_thread::do_dma_transfer(spu_thread* _this, const spu_mfc_cmd& args, u8* if (eal < SYS_SPU_THREAD_BASE_LOW) { // RawSPU MMIO - auto thread = idm::get>(find_raw_spu((eal - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET)); + auto thread = idm::get_unlocked>(find_raw_spu((eal - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET)); if (!thread) { @@ -3837,7 +3837,7 @@ bool spu_thread::do_putllc(const spu_mfc_cmd& args) if (count2 > 20000 && g_cfg.core.perf_report) [[unlikely]] { - perf_log.warning(u8"PUTLLC: took too long: %.3fµs (%u c) (addr=0x%x) (S)", count2 / (utils::get_tsc_freq() / 1000'000.), count2, addr); + perf_log.warning("PUTLLC: took too long: %.3fus (%u c) (addr=0x%x) (S)", count2 / (utils::get_tsc_freq() / 1000'000.), count2, addr); } if (ok) @@ -3872,7 +3872,7 @@ bool spu_thread::do_putllc(const spu_mfc_cmd& args) { if (count > 20000 && g_cfg.core.perf_report) [[unlikely]] { - perf_log.warning(u8"PUTLLC: took too long: %.3fµs (%u c) (addr = 0x%x)", count / (utils::get_tsc_freq() / 1000'000.), count, addr); + perf_log.warning("PUTLLC: took too long: %.3fus (%u c) (addr = 0x%x)", count / (utils::get_tsc_freq() / 1000'000.), count, addr); } break; @@ -4087,7 +4087,7 @@ void do_cell_atomic_128_store(u32 addr, const void* to_write) if (result > 20000 && g_cfg.core.perf_report) [[unlikely]] { - perf_log.warning(u8"STORE128: took too long: %.3fµs (%u c) (addr=0x%x)", result / (utils::get_tsc_freq() / 1000'000.), result, addr); + perf_log.warning("STORE128: took too long: %.3fus (%u c) (addr=0x%x)", result / (utils::get_tsc_freq() / 1000'000.), result, addr); } static_cast(cpu->test_stopped()); @@ -6007,7 +6007,7 @@ bool spu_thread::set_ch_value(u32 ch, u32 value) spu_function_logger logger(*this, "sys_spu_thread_send_event"); - std::shared_ptr queue; + shared_ptr queue; { std::lock_guard lock(group->mutex); @@ -6059,7 +6059,7 @@ bool spu_thread::set_ch_value(u32 ch, u32 value) spu_function_logger logger(*this, "sys_spu_thread_throw_event"); - std::shared_ptr queue; + shared_ptr queue; { std::lock_guard lock{group->mutex}; queue = this->spup[spup]; @@ -6447,7 +6447,7 @@ bool spu_thread::stop_and_signal(u32 code) return true; } - auto get_queue = [this](u32 spuq) -> const std::shared_ptr& + auto get_queue = [this](u32 spuq) -> const shared_ptr& { for (auto& v : this->spuq) { @@ -6460,7 +6460,7 @@ bool spu_thread::stop_and_signal(u32 code) } } - static const std::shared_ptr empty; + static const shared_ptr empty; return empty; }; @@ -6523,7 +6523,7 @@ bool spu_thread::stop_and_signal(u32 code) spu_function_logger logger(*this, "sys_spu_thread_receive_event"); - std::shared_ptr queue; + shared_ptr queue; while (true) { @@ -6665,7 +6665,7 @@ bool spu_thread::stop_and_signal(u32 code) spu_log.trace("sys_spu_thread_tryreceive_event(spuq=0x%x)", spuq); - std::shared_ptr queue; + shared_ptr queue; reader_lock{group->mutex}, queue = get_queue(spuq); diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 2d91563a14..c895e09211 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -453,7 +453,7 @@ struct spu_int_ctrl_t atomic_t mask; atomic_t stat; - std::shared_ptr tag; + shared_ptr tag; void set(u64 ints); @@ -755,8 +755,8 @@ public: atomic_t status_npc{}; std::array int_ctrl{}; // SPU Class 0, 1, 2 Interrupt Management - std::array>, 32> spuq{}; // Event Queue Keys for SPU Thread - std::shared_ptr spup[64]; // SPU Ports + std::array>, 32> spuq{}; // Event Queue Keys for SPU Thread + shared_ptr spup[64]; // SPU Ports spu_channel exit_status{}; // Threaded SPU exit status (not a channel, but the interface fits) atomic_t last_exit_status; // Value to be written in exit_status after checking group termination lv2_spu_group* const group; // SPU Thread Group (access by the spu threads in the group only! From other threads obtain a shared pointer to group using group ID) diff --git a/rpcs3/Emu/Cell/lv2/sys_cond.cpp b/rpcs3/Emu/Cell/lv2/sys_cond.cpp index 765948a908..840b1942b7 100644 --- a/rpcs3/Emu/Cell/lv2/sys_cond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_cond.cpp @@ -14,11 +14,21 @@ LOG_CHANNEL(sys_cond); -lv2_cond::lv2_cond(utils::serial& ar) +lv2_cond::lv2_cond(utils::serial& ar) noexcept : key(ar) , name(ar) , mtx_id(ar) - , mutex(idm::get_unlocked(mtx_id)) // May be nullptr + , mutex(idm::check_unlocked(mtx_id)) + , _mutex(idm::get_unlocked(mtx_id)) // May be nullptr +{ +} + +lv2_cond::lv2_cond(u64 key, u64 name, u32 mtx_id, shared_ptr mutex0) noexcept + : key(key) + , name(name) + , mtx_id(mtx_id) + , mutex(static_cast(mutex0.get())) + , _mutex(mutex0) { } @@ -49,7 +59,8 @@ CellError lv2_cond::on_id_create() { if (!mutex) { - mutex = ensure(idm::get_unlocked(mtx_id)); + _mutex = static_cast>(ensure(idm::get_unlocked(mtx_id))); + } // Defer function @@ -59,10 +70,9 @@ CellError lv2_cond::on_id_create() return {}; } -std::shared_ptr lv2_cond::load(utils::serial& ar) +std::function lv2_cond::load(utils::serial& ar) { - auto cond = std::make_shared(ar); - return lv2_obj::load(cond->key, cond); + return load_func(make_shared(ar)); } void lv2_cond::save(utils::serial& ar) @@ -76,7 +86,7 @@ error_code sys_cond_create(ppu_thread& ppu, vm::ptr cond_id, u32 mutex_id, sys_cond.trace("sys_cond_create(cond_id=*0x%x, mutex_id=0x%x, attr=*0x%x)", cond_id, mutex_id, attr); - auto mutex = idm::get(mutex_id); + auto mutex = idm::get_unlocked(mutex_id); if (!mutex) { @@ -94,7 +104,7 @@ error_code sys_cond_create(ppu_thread& ppu, vm::ptr cond_id, u32 mutex_id, if (const auto error = lv2_obj::create(_attr.pshared, ipc_key, _attr.flags, [&] { - return std::make_shared( + return make_single( ipc_key, _attr.name_u64, mutex_id, diff --git a/rpcs3/Emu/Cell/lv2/sys_cond.h b/rpcs3/Emu/Cell/lv2/sys_cond.h index 54613250ed..60e7c24e61 100644 --- a/rpcs3/Emu/Cell/lv2/sys_cond.h +++ b/rpcs3/Emu/Cell/lv2/sys_cond.h @@ -26,19 +26,14 @@ struct lv2_cond final : lv2_obj const u64 name; const u32 mtx_id; - std::shared_ptr mutex; // Associated Mutex + lv2_mutex* mutex; // Associated Mutex + shared_ptr _mutex; ppu_thread* sq{}; - lv2_cond(u64 key, u64 name, u32 mtx_id, std::shared_ptr mutex) - : key(key) - , name(name) - , mtx_id(mtx_id) - , mutex(std::move(mutex)) - { - } + lv2_cond(u64 key, u64 name, u32 mtx_id, shared_ptr mutex0) noexcept; - lv2_cond(utils::serial& ar); - static std::shared_ptr load(utils::serial& ar); + lv2_cond(utils::serial& ar) noexcept; + static std::function load(utils::serial& ar); void save(utils::serial& ar); CellError on_id_create(); diff --git a/rpcs3/Emu/Cell/lv2/sys_config.cpp b/rpcs3/Emu/Cell/lv2/sys_config.cpp index 629beb6d23..8194fb222b 100644 --- a/rpcs3/Emu/Cell/lv2/sys_config.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_config.cpp @@ -101,10 +101,10 @@ void lv2_config::initialize() lv2_config_service::create(SYS_CONFIG_SERVICE_PADMANAGER2, 0, 1, 0, hid_info, 0x1a)->notify(); } -void lv2_config::add_service_event(const std::shared_ptr& event) +void lv2_config::add_service_event(shared_ptr event) { std::lock_guard lock(m_mutex); - events.emplace(event->id, event); + events.emplace(event->id, std::move(event)); } void lv2_config::remove_service_event(u32 id) @@ -140,13 +140,13 @@ bool lv2_config_service_listener::check_service(const lv2_config_service& servic return true; } -bool lv2_config_service_listener::notify(const std::shared_ptr& event) +bool lv2_config_service_listener::notify(const shared_ptr& event) { service_events.emplace_back(event); return event->notify(); } -bool lv2_config_service_listener::notify(const std::shared_ptr& service) +bool lv2_config_service_listener::notify(const shared_ptr& service) { if (!check_service(*service)) return false; @@ -158,7 +158,7 @@ bool lv2_config_service_listener::notify(const std::shared_ptr> services; + std::vector> services; // Grab all events idm::select([&](u32 /*id*/, lv2_config_service& service) @@ -170,7 +170,7 @@ void lv2_config_service_listener::notify_all() }); // Sort services by timestamp - sort(services.begin(), services.end(), [](const std::shared_ptr& s1, const std::shared_ptr& s2) + sort(services.begin(), services.end(), [](const shared_ptr& s1, const shared_ptr& s2) { return s1->timestamp < s2->timestamp; }); @@ -198,9 +198,9 @@ void lv2_config_service::unregister() void lv2_config_service::notify() const { - std::vector> listeners; + std::vector> listeners; - auto sptr = wkptr.lock(); + const shared_ptr sptr = get_shared_ptr(); idm::select([&](u32 /*id*/, lv2_config_service_listener& listener) { @@ -210,13 +210,14 @@ void lv2_config_service::notify() const for (auto& listener : listeners) { - listener->notify(this->get_shared_ptr()); + listener->notify(sptr); } } bool lv2_config_service_event::notify() const { - const auto _handle = handle.lock(); + const auto _handle = handle; + if (!_handle) { return false; @@ -259,7 +260,7 @@ error_code sys_config_open(u32 equeue_hdl, vm::ptr out_config_hdl) sys_config.trace("sys_config_open(equeue_hdl=0x%x, out_config_hdl=*0x%x)", equeue_hdl, out_config_hdl); // Find queue with the given ID - const auto queue = idm::get(equeue_hdl); + const auto queue = idm::get_unlocked(equeue_hdl); if (!queue) { return CELL_ESRCH; @@ -303,7 +304,7 @@ error_code sys_config_get_service_event(u32 config_hdl, u32 event_id, vm::ptr(config_hdl); + const auto cfg = idm::get_unlocked(config_hdl); if (!cfg) { return CELL_ESRCH; @@ -335,7 +336,7 @@ error_code sys_config_add_service_listener(u32 config_hdl, sys_config_service_id sys_config.trace("sys_config_add_service_listener(config_hdl=0x%x, service_id=0x%llx, min_verbosity=0x%llx, in=*0x%x, size=%lld, type=0x%llx, out_listener_hdl=*0x%x)", config_hdl, service_id, min_verbosity, in, size, type, out_listener_hdl); // Find sys_config handle object with the given ID - auto cfg = idm::get(config_hdl); + auto cfg = idm::get_unlocked(config_hdl); if (!cfg) { return CELL_ESRCH; @@ -383,7 +384,7 @@ error_code sys_config_register_service(u32 config_hdl, sys_config_service_id ser sys_config.trace("sys_config_register_service(config_hdl=0x%x, service_id=0x%llx, user_id=0x%llx, verbosity=0x%llx, data_but=*0x%llx, size=%lld, out_service_hdl=*0x%llx)", config_hdl, service_id, user_id, verbosity, data_buf, size, out_service_hdl); // Find sys_config handle object with the given ID - const auto cfg = idm::get(config_hdl); + const auto cfg = idm::get_unlocked(config_hdl); if (!cfg) { return CELL_ESRCH; diff --git a/rpcs3/Emu/Cell/lv2/sys_config.h b/rpcs3/Emu/Cell/lv2/sys_config.h index 36a2b3993d..337ffbe74f 100644 --- a/rpcs3/Emu/Cell/lv2/sys_config.h +++ b/rpcs3/Emu/Cell/lv2/sys_config.h @@ -3,6 +3,9 @@ #include #include +#include "util/atomic.hpp" +#include "util/shared_ptr.hpp" + /* * sys_config is a "subscription-based data storage API" @@ -133,30 +136,30 @@ class lv2_config shared_mutex m_mutex; // Map of LV2 Service Events - std::unordered_map> events; + std::unordered_map> events; public: void initialize(); // Service Events - void add_service_event(const std::shared_ptr& event); + void add_service_event(shared_ptr event); void remove_service_event(u32 id); - std::shared_ptr find_event(u32 id) + shared_ptr find_event(u32 id) { reader_lock lock(m_mutex); const auto it = events.find(id); if (it == events.cend()) - return nullptr; + return null_ptr; - if (auto event = it->second.lock()) + if (it->second) { - return event; + return it->second; } - return nullptr; + return null_ptr; } }; @@ -175,33 +178,35 @@ private: u32 idm_id; // queue for service/io event notifications - const std::weak_ptr queue; + const shared_ptr queue; bool send_queue_event(u64 source, u64 d1, u64 d2, u64 d3) const { - if (auto sptr = queue.lock()) + if (auto sptr = queue) { return sptr->send(source, d1, d2, d3) == 0; } + return false; } public: // Constructors (should not be used directly) - lv2_config_handle(std::weak_ptr&& _queue) + lv2_config_handle(shared_ptr _queue) noexcept : queue(std::move(_queue)) - {} + { + } // Factory template - static std::shared_ptr create(Args&&... args) + static shared_ptr create(Args&&... args) { if (auto cfg = idm::make_ptr(std::forward(args)...)) { cfg->idm_id = idm::last_id(); return cfg; } - return nullptr; + return null_ptr; } // Notify event queue for this handle @@ -225,7 +230,6 @@ public: private: // IDM data u32 idm_id; - std::weak_ptr wkptr; // Whether this service is currently registered or not bool registered = true; @@ -240,27 +244,27 @@ public: const std::vector data; // Constructors (should not be used directly) - lv2_config_service(sys_config_service_id _id, u64 _user_id, u64 _verbosity, u32 _padding, const u8 _data[], usz size) + lv2_config_service(sys_config_service_id _id, u64 _user_id, u64 _verbosity, u32 _padding, const u8* _data, usz size) noexcept : timestamp(get_system_time()) , id(_id) , user_id(_user_id) , verbosity(_verbosity) , padding(_padding) , data(&_data[0], &_data[size]) - {} + { + } // Factory template - static std::shared_ptr create(Args&&... args) + static shared_ptr create(Args&&... args) { if (auto service = idm::make_ptr(std::forward(args)...)) { - service->wkptr = service; service->idm_id = idm::last_id(); return service; } - return nullptr; + return null_ptr; } // Registration @@ -272,7 +276,7 @@ public: // Utilities usz get_size() const { return sizeof(sys_config_service_event_t)-1 + data.size(); } - std::shared_ptr get_shared_ptr () const { return wkptr.lock(); } + shared_ptr get_shared_ptr () const { return idm::get_unlocked(idm_id); } u32 get_id() const { return idm_id; } }; @@ -290,14 +294,13 @@ public: private: // IDM data u32 idm_id; - std::weak_ptr wkptr; // The service listener owns the service events - service events will not be freed as long as their corresponding listener exists // This has been confirmed to be the case in realhw - std::vector> service_events; - std::weak_ptr handle; + std::vector> service_events; + shared_ptr handle; - bool notify(const std::shared_ptr& event); + bool notify(const shared_ptr& event); public: const sys_config_service_id service_id; @@ -307,8 +310,8 @@ public: const std::vector data; // Constructors (should not be used directly) - lv2_config_service_listener(std::shared_ptr& _handle, sys_config_service_id _service_id, u64 _min_verbosity, sys_config_service_listener_type _type, const u8 _data[], usz size) - : handle(_handle) + lv2_config_service_listener(shared_ptr _handle, sys_config_service_id _service_id, u64 _min_verbosity, sys_config_service_listener_type _type, const u8* _data, usz size) noexcept + : handle(std::move(_handle)) , service_id(_service_id) , min_verbosity(_min_verbosity) , type(_type) @@ -317,30 +320,29 @@ public: // Factory template - static std::shared_ptr create(Args&&... args) + static shared_ptr create(Args&&... args) { if (auto listener = idm::make_ptr(std::forward(args)...)) { - listener->wkptr = listener; listener->idm_id = idm::last_id(); return listener; } - return nullptr; + return null_ptr; } // Check whether service matches bool check_service(const lv2_config_service& service) const; // Register new event, and notify queue - bool notify(const std::shared_ptr& service); + bool notify(const shared_ptr& service); // (Re-)notify about all still-registered past events void notify_all(); // Utilities u32 get_id() const { return idm_id; } - std::shared_ptr get_shared_ptr() const { return wkptr.lock(); } + shared_ptr get_shared_ptr() const { return idm::get_unlocked(idm_id); } }; /* @@ -363,30 +365,24 @@ public: // Note: Events hold a shared_ptr to their corresponding service - services only get freed once there are no more pending service events // This has been confirmed to be the case in realhw - const std::weak_ptr handle; - const std::shared_ptr service; + const shared_ptr handle; + const shared_ptr service; const lv2_config_service_listener& listener; // Constructors (should not be used directly) - lv2_config_service_event(const std::weak_ptr& _handle, const std::shared_ptr& _service, const lv2_config_service_listener& _listener) - : id(get_next_id()) - , handle(_handle) - , service(_service) - , listener(_listener) - {} - - lv2_config_service_event(const std::weak_ptr&& _handle, const std::shared_ptr&& _service, const lv2_config_service_listener& _listener) + lv2_config_service_event(shared_ptr _handle, shared_ptr _service, const lv2_config_service_listener& _listener) noexcept : id(get_next_id()) , handle(std::move(_handle)) , service(std::move(_service)) , listener(_listener) - {} + { + } // Factory template - static std::shared_ptr create(Args&&... args) + static shared_ptr create(Args&&... args) { - auto ev = std::make_shared(std::forward(args)...); + auto ev = make_shared(std::forward(args)...); g_fxo->get().add_service_event(ev); @@ -394,7 +390,7 @@ public: } // Destructor - ~lv2_config_service_event() + ~lv2_config_service_event() noexcept { if (auto global = g_fxo->try_get()) { diff --git a/rpcs3/Emu/Cell/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp index 81f4ff65b0..0428fd0f11 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -35,10 +35,10 @@ lv2_event_queue::lv2_event_queue(utils::serial& ar) noexcept ar(events); } -std::shared_ptr lv2_event_queue::load(utils::serial& ar) +std::function lv2_event_queue::load(utils::serial& ar) { - auto queue = std::make_shared(ar); - return lv2_obj::load(queue->key, queue); + auto queue = make_shared(ar); + return [ptr = lv2_obj::load(queue->key, queue)](void* storage) { *static_cast*>(storage) = ptr; }; } void lv2_event_queue::save(utils::serial& ar) @@ -57,13 +57,13 @@ void lv2_event_queue::save_ptr(utils::serial& ar, lv2_event_queue* q) ar(q->id); } -std::shared_ptr lv2_event_queue::load_ptr(utils::serial& ar, std::shared_ptr& queue, std::string_view msg) +shared_ptr lv2_event_queue::load_ptr(utils::serial& ar, shared_ptr& queue, std::string_view msg) { const u32 id = ar.pop(); if (!id) { - return nullptr; + return {}; } if (auto q = idm::get_unlocked(id)) @@ -89,7 +89,7 @@ std::shared_ptr lv2_event_queue::load_ptr(utils::serial& ar, st }); // Null until resolved - return nullptr; + return {}; } lv2_event_port::lv2_event_port(utils::serial& ar) @@ -106,7 +106,7 @@ void lv2_event_port::save(utils::serial& ar) lv2_event_queue::save_ptr(ar, queue.get()); } -std::shared_ptr lv2_event_queue::find(u64 ipc_key) +shared_ptr lv2_event_queue::find(u64 ipc_key) { if (ipc_key == SYS_EVENT_QUEUE_LOCAL) { @@ -238,7 +238,7 @@ error_code sys_event_queue_create(cpu_thread& cpu, vm::ptr equeue_id, vm::p if (const auto error = lv2_obj::create(pshared, ipc_key, flags, [&]() { - return std::make_shared(protocol, type, size, name, ipc_key); + return make_shared(protocol, type, size, name, ipc_key); })) { return error; @@ -394,7 +394,7 @@ error_code sys_event_queue_tryreceive(ppu_thread& ppu, u32 equeue_id, vm::ptr(equeue_id); + const auto queue = idm::get_unlocked(equeue_id); if (!queue) { diff --git a/rpcs3/Emu/Cell/lv2/sys_event.h b/rpcs3/Emu/Cell/lv2/sys_event.h index 506a45e7a0..6c43798a30 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.h +++ b/rpcs3/Emu/Cell/lv2/sys_event.h @@ -100,10 +100,10 @@ struct lv2_event_queue final : public lv2_obj lv2_event_queue(u32 protocol, s32 type, s32 size, u64 name, u64 ipc_key) noexcept; lv2_event_queue(utils::serial& ar) noexcept; - static std::shared_ptr load(utils::serial& ar); + static std::function load(utils::serial& ar); void save(utils::serial& ar); static void save_ptr(utils::serial&, lv2_event_queue*); - static std::shared_ptr load_ptr(utils::serial& ar, std::shared_ptr& queue, std::string_view msg = {}); + static shared_ptr load_ptr(utils::serial& ar, shared_ptr& queue, std::string_view msg = {}); CellError send(lv2_event event, bool* notified_thread = nullptr, lv2_event_port* port = nullptr); @@ -113,7 +113,7 @@ struct lv2_event_queue final : public lv2_obj } // Get event queue by its global key - static std::shared_ptr find(u64 ipc_key); + static shared_ptr find(u64 ipc_key); }; struct lv2_event_port final : lv2_obj @@ -124,7 +124,7 @@ struct lv2_event_port final : lv2_obj const u64 name; // Event source (generated from id and process id if not set) atomic_t is_busy = 0; // Counts threads waiting on event sending - std::shared_ptr queue; // Event queue this port is connected to + shared_ptr queue; // Event queue this port is connected to lv2_event_port(s32 type, u64 name) : type(type) diff --git a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp index c5e3ee9781..6c630e9261 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp @@ -22,10 +22,9 @@ lv2_event_flag::lv2_event_flag(utils::serial& ar) ar(pattern); } -std::shared_ptr lv2_event_flag::load(utils::serial& ar) +std::function lv2_event_flag::load(utils::serial& ar) { - auto eflag = std::make_shared(ar); - return lv2_obj::load(eflag->key, eflag); + return load_func(make_shared(ar)); } void lv2_event_flag::save(utils::serial& ar) @@ -66,7 +65,7 @@ error_code sys_event_flag_create(ppu_thread& ppu, vm::ptr id, vm::ptr(_attr.pshared, ipc_key, _attr.flags, [&] { - return std::make_shared( + return make_shared( _attr.protocol, ipc_key, _attr.type, @@ -330,7 +329,7 @@ error_code sys_event_flag_set(cpu_thread& cpu, u32 id, u64 bitptn) // Warning: may be called from SPU thread. sys_event_flag.trace("sys_event_flag_set(id=0x%x, bitptn=0x%llx)", id, bitptn); - const auto flag = idm::get(id); + const auto flag = idm::get_unlocked(id); if (!flag) { @@ -502,7 +501,7 @@ error_code sys_event_flag_cancel(ppu_thread& ppu, u32 id, vm::ptr num) if (num) *num = 0; - const auto flag = idm::get(id); + const auto flag = idm::get_unlocked(id); if (!flag) { diff --git a/rpcs3/Emu/Cell/lv2/sys_event_flag.h b/rpcs3/Emu/Cell/lv2/sys_event_flag.h index 6af8887b99..652ae95947 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event_flag.h +++ b/rpcs3/Emu/Cell/lv2/sys_event_flag.h @@ -54,7 +54,7 @@ struct lv2_event_flag final : lv2_obj } lv2_event_flag(utils::serial& ar); - static std::shared_ptr load(utils::serial& ar); + static std::function load(utils::serial& ar); void save(utils::serial& ar); // Check mode arg diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index 29401b922b..23f932ae91 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -79,7 +79,7 @@ void fmt_class_string::format(std::string& out, u64 arg) const usz pos = file.file ? file.file.pos() : umax; const usz size = file.file ? file.file.size() : umax; - fmt::append(out, u8"%s, “%s”, Mode: 0x%x, Flags: 0x%x, Pos/Size: %s/%s (0x%x/0x%x)", file.type, file.name.data(), file.mode, file.flags, get_size(pos), get_size(size), pos, size); + fmt::append(out, u8"%s, “%s”, Mode: 0x%x, Flags: 0x%x, Pos/Size: %s/%s (0x%x/0x%x)", file.type, file.name.data(), file.mode, file.flags, get_size(pos), get_size(size), pos, size); } template<> @@ -87,7 +87,7 @@ void fmt_class_string::format(std::string& out, u64 arg) { const auto& dir = get_object(arg); - fmt::append(out, u8"Directory, “%s”, Entries: %u/%u", dir.name.data(), std::min(dir.pos, dir.entries.size()), dir.entries.size()); + fmt::append(out, u8"Directory, “%s”, Entries: %u/%u", dir.name.data(), std::min(dir.pos, dir.entries.size()), dir.entries.size()); } bool has_fs_write_rights(std::string_view vpath) @@ -615,11 +615,11 @@ void loaded_npdrm_keys::save(utils::serial& ar) struct lv2_file::file_view : fs::file_base { - const std::shared_ptr m_file; + const shared_ptr m_file; const u64 m_off; u64 m_pos; - explicit file_view(const std::shared_ptr& _file, u64 offset) + explicit file_view(const shared_ptr& _file, u64 offset) : m_file(_file) , m_off(offset) , m_pos(0) @@ -699,7 +699,7 @@ struct lv2_file::file_view : fs::file_base } }; -fs::file lv2_file::make_view(const std::shared_ptr& _file, u64 offset) +fs::file lv2_file::make_view(const shared_ptr& _file, u64 offset) { fs::file result; result.reset(std::make_unique(_file, offset)); @@ -745,7 +745,7 @@ error_code sys_fs_test(ppu_thread&, u32 arg1, u32 arg2, vm::ptr arg3, u32 a return CELL_EFAULT; } - const auto file = idm::get(*arg3); + const auto file = idm::get_unlocked(*arg3); if (!file) { @@ -1059,16 +1059,16 @@ error_code sys_fs_open(ppu_thread& ppu, vm::cptr path, s32 flags, vm::ptr< return {g_fxo->get().lookup(vpath) == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, error, path}; } - if (const u32 id = idm::import([&ppath = ppath, &file = file, mode, flags, &real = real, &type = type]() -> std::shared_ptr + if (const u32 id = idm::import([&ppath = ppath, &file = file, mode, flags, &real = real, &type = type]() -> shared_ptr { - std::shared_ptr result; + shared_ptr result; if (type >= lv2_file_type::sdata && !g_fxo->get().npdrm_fds.try_inc(16)) { return result; } - result = std::make_shared(ppath, std::move(file), mode, flags, real, type); + result = stx::make_shared(ppath, std::move(file), mode, flags, real, type); sys_fs.warning("sys_fs_open(): fd=%u, %s", idm::last_id(), *result); return result; })) @@ -1100,7 +1100,7 @@ error_code sys_fs_read(ppu_thread& ppu, u32 fd, vm::ptr buf, u64 nbytes, v return CELL_EFAULT; } - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file || (nbytes && file->flags & CELL_FS_O_WRONLY)) { @@ -1169,7 +1169,7 @@ error_code sys_fs_write(ppu_thread& ppu, u32 fd, vm::cptr buf, u64 nbytes, return CELL_EFAULT; } - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file || (nbytes && !(file->flags & CELL_FS_O_ACCMODE))) { @@ -1239,7 +1239,7 @@ error_code sys_fs_close(ppu_thread& ppu, u32 fd) ppu.state += cpu_flag::wait; lv2_obj::sleep(ppu); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -1279,7 +1279,7 @@ error_code sys_fs_close(ppu_thread& ppu, u32 fd) auto& default_container = g_fxo->get(); std::lock_guard lock(default_container.mutex); - if (auto ct = idm::get(file->ct_id)) + if (auto ct = idm::get_unlocked(file->ct_id)) { ct->free(file->ct_used); if (default_container.id == file->ct_id) @@ -1442,7 +1442,7 @@ error_code sys_fs_readdir(ppu_thread& ppu, u32 fd, vm::ptr dir, vm return CELL_EFAULT; } - const auto directory = idm::get(fd); + const auto directory = idm::get_unlocked(fd); if (!directory) { @@ -1614,7 +1614,7 @@ error_code sys_fs_fstat(ppu_thread& ppu, u32 fd, vm::ptr sb) sys_fs.warning("sys_fs_fstat(fd=%d, sb=*0x%x)", fd, sb); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -1960,7 +1960,7 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr _arg, u32 return CELL_EINVAL; } - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -2056,7 +2056,7 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr _arg, u32 return CELL_EINVAL; } - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -2081,14 +2081,14 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr _arg, u32 fs::file stream; stream.reset(std::move(sdata_file)); - if (const u32 id = idm::import([&file = *file, &stream = stream]() -> std::shared_ptr + if (const u32 id = idm::import([&file = *file, &stream = stream]() -> shared_ptr { if (!g_fxo->get().npdrm_fds.try_inc(16)) { - return nullptr; + return null_ptr; } - return std::make_shared(file, std::move(stream), file.mode, CELL_FS_O_RDONLY, file.real_path, lv2_file_type::sdata); + return stx::make_shared(file, std::move(stream), file.mode, CELL_FS_O_RDONLY, file.real_path, lv2_file_type::sdata); })) { arg->out_code = CELL_OK; @@ -2198,13 +2198,13 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr _arg, u32 return CELL_OK; } - auto file = idm::get(fd); + auto file = idm::get_unlocked(fd); if (!file) { return CELL_EBADF; } - if (auto ct = idm::get(file->ct_id)) + if (auto ct = idm::get_unlocked(file->ct_id)) { ct->free(file->ct_used); if (default_container.id == file->ct_id) @@ -2427,7 +2427,7 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr _arg, u32 return CELL_EINVAL; } - const auto directory = idm::get(fd); + const auto directory = idm::get_unlocked(fd); if (!directory) { @@ -2566,14 +2566,14 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr _arg, u32 return result.error; } - if (const u32 id = idm::import([&]() -> std::shared_ptr + if (const u32 id = idm::import([&]() -> shared_ptr { if (!g_fxo->get().npdrm_fds.try_inc(16)) { - return nullptr; + return null_ptr; } - return std::make_shared(result.ppath, std::move(result.file), 0, 0, std::move(result.real_path), lv2_file_type::sdata); + return stx::make_shared(result.ppath, std::move(result.file), 0, 0, std::move(result.real_path), lv2_file_type::sdata); })) { arg->out_code = CELL_OK; @@ -2597,7 +2597,7 @@ error_code sys_fs_lseek(ppu_thread& ppu, u32 fd, s64 offset, s32 whence, vm::ptr sys_fs.trace("sys_fs_lseek(fd=%d, offset=0x%llx, whence=0x%x, pos=*0x%x)", fd, offset, whence, pos); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -2643,7 +2643,7 @@ error_code sys_fs_fdatasync(ppu_thread& ppu, u32 fd) sys_fs.trace("sys_fs_fdadasync(fd=%d)", fd); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { @@ -2668,7 +2668,7 @@ error_code sys_fs_fsync(ppu_thread& ppu, u32 fd) sys_fs.trace("sys_fs_fsync(fd=%d)", fd); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { @@ -2692,7 +2692,7 @@ error_code sys_fs_fget_block_size(ppu_thread& ppu, u32 fd, vm::ptr sector_s sys_fs.warning("sys_fs_fget_block_size(fd=%d, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, out_flags=*0x%x)", fd, sector_size, block_size, arg4, out_flags); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -2819,7 +2819,7 @@ error_code sys_fs_ftruncate(ppu_thread& ppu, u32 fd, u64 size) sys_fs.warning("sys_fs_ftruncate(fd=%d, size=0x%llx)", fd, size); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { @@ -3089,7 +3089,7 @@ error_code sys_fs_lsn_get_cda_size(ppu_thread&, u32 fd, vm::ptr ptr) { sys_fs.warning("sys_fs_lsn_get_cda_size(fd=%d, ptr=*0x%x)", fd, ptr); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -3112,7 +3112,7 @@ error_code sys_fs_lsn_lock(ppu_thread&, u32 fd) { sys_fs.trace("sys_fs_lsn_lock(fd=%d)", fd); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -3134,7 +3134,7 @@ error_code sys_fs_lsn_unlock(ppu_thread&, u32 fd) { sys_fs.trace("sys_fs_lsn_unlock(fd=%d)", fd); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.h b/rpcs3/Emu/Cell/lv2/sys_fs.h index d6acb6361b..825140d7ab 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.h +++ b/rpcs3/Emu/Cell/lv2/sys_fs.h @@ -360,7 +360,7 @@ struct lv2_file final : lv2_fs_object struct file_view; // Make file view from lv2_file object (for MSELF support) - static fs::file make_view(const std::shared_ptr& _file, u64 offset); + static fs::file make_view(const shared_ptr& _file, u64 offset); }; struct lv2_dir final : lv2_fs_object diff --git a/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp index 800f2f85b9..3109f042f9 100644 --- a/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp @@ -12,13 +12,13 @@ LOG_CHANNEL(sys_interrupt); lv2_int_tag::lv2_int_tag() noexcept - : lv2_obj{1} + : lv2_obj(1) , id(idm::last_id()) { } lv2_int_tag::lv2_int_tag(utils::serial& ar) noexcept - : lv2_obj{1} + : lv2_obj(1) , id(idm::last_id()) , handler([&]() { @@ -44,8 +44,8 @@ void lv2_int_tag::save(utils::serial& ar) ar(lv2_obj::check(handler) ? handler->id : 0); } -lv2_int_serv::lv2_int_serv(const std::shared_ptr>& thread, u64 arg1, u64 arg2) noexcept - : lv2_obj{1} +lv2_int_serv::lv2_int_serv(shared_ptr> thread, u64 arg1, u64 arg2) noexcept + : lv2_obj(1) , id(idm::last_id()) , thread(thread) , arg1(arg1) @@ -54,7 +54,7 @@ lv2_int_serv::lv2_int_serv(const std::shared_ptr>& thre } lv2_int_serv::lv2_int_serv(utils::serial& ar) noexcept - : lv2_obj{1} + : lv2_obj(1) , id(idm::last_id()) , thread(idm::get_unlocked>(ar)) , arg1(ar) @@ -96,7 +96,7 @@ void lv2_int_serv::join() const thread->cmd_notify.notify_one(); (*thread)(); - idm::remove_verify>(thread->id, static_cast>>(thread)); + idm::remove_verify>(thread->id, thread); } error_code sys_interrupt_tag_destroy(ppu_thread& ppu, u32 intrtag) @@ -139,7 +139,7 @@ error_code _sys_interrupt_thread_establish(ppu_thread& ppu, vm::ptr ih, u32 const u32 id = idm::import([&]() { - std::shared_ptr result; + shared_ptr result; // Get interrupt tag const auto tag = idm::check_unlocked(intrtag); @@ -173,7 +173,7 @@ error_code _sys_interrupt_thread_establish(ppu_thread& ppu, vm::ptr ih, u32 return result; } - result = std::make_shared(it, arg1, arg2); + result = make_shared(it, arg1, arg2); tag->handler = result; it->cmd_list @@ -251,7 +251,7 @@ void ppu_interrupt_thread_entry(ppu_thread& ppu, ppu_opcode_t, be_t*, struc { while (true) { - std::shared_ptr serv = nullptr; + shared_ptr serv = null_ptr; // Loop endlessly trying to invoke an interrupt if required idm::select>([&](u32, spu_thread& spu) diff --git a/rpcs3/Emu/Cell/lv2/sys_interrupt.h b/rpcs3/Emu/Cell/lv2/sys_interrupt.h index 9fe4dc9d39..f32517e9a4 100644 --- a/rpcs3/Emu/Cell/lv2/sys_interrupt.h +++ b/rpcs3/Emu/Cell/lv2/sys_interrupt.h @@ -11,7 +11,7 @@ struct lv2_int_tag final : public lv2_obj static const u32 id_base = 0x0a000000; const u32 id; - std::shared_ptr handler; + shared_ptr handler; lv2_int_tag() noexcept; lv2_int_tag(utils::serial& ar) noexcept; @@ -23,11 +23,11 @@ struct lv2_int_serv final : public lv2_obj static const u32 id_base = 0x0b000000; const u32 id; - const std::shared_ptr> thread; + const shared_ptr> thread; const u64 arg1; const u64 arg2; - lv2_int_serv(const std::shared_ptr>& thread, u64 arg1, u64 arg2) noexcept; + lv2_int_serv(shared_ptr> thread, u64 arg1, u64 arg2) noexcept; lv2_int_serv(utils::serial& ar) noexcept; void save(utils::serial& ar); diff --git a/rpcs3/Emu/Cell/lv2/sys_io.cpp b/rpcs3/Emu/Cell/lv2/sys_io.cpp index 5a11bb261f..b1cec87a47 100644 --- a/rpcs3/Emu/Cell/lv2/sys_io.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_io.cpp @@ -43,7 +43,7 @@ error_code sys_io_buffer_allocate(u32 handle, vm::ptr block) return CELL_EFAULT; } - if (auto io = idm::get(handle)) + if (auto io = idm::get_unlocked(handle)) { // no idea what we actually need to allocate if (u32 addr = vm::alloc(io->block_count * io->block_size, vm::main)) @@ -62,7 +62,7 @@ error_code sys_io_buffer_free(u32 handle, u32 block) { sys_io.todo("sys_io_buffer_free(handle=0x%x, block=0x%x)", handle, block); - const auto io = idm::get(handle); + const auto io = idm::get_unlocked(handle); if (!io) { diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp index 6ffd9b29e6..75835ffa24 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp @@ -64,7 +64,7 @@ error_code _sys_lwcond_destroy(ppu_thread& ppu, u32 lwcond_id) sys_lwcond.trace("_sys_lwcond_destroy(lwcond_id=0x%x)", lwcond_id); - std::shared_ptr _cond; + shared_ptr _cond; while (true) { @@ -440,7 +440,7 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id ppu.gpr[3] = CELL_OK; - std::shared_ptr mutex; + shared_ptr mutex; auto& sstate = *ppu.optional_savestate_state; diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp index 7df939b738..a56bffedca 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp @@ -56,7 +56,7 @@ error_code _sys_lwmutex_destroy(ppu_thread& ppu, u32 lwmutex_id) sys_lwmutex.trace("_sys_lwmutex_destroy(lwmutex_id=0x%x)", lwmutex_id); - std::shared_ptr _mutex; + shared_ptr _mutex; while (true) { diff --git a/rpcs3/Emu/Cell/lv2/sys_memory.cpp b/rpcs3/Emu/Cell/lv2/sys_memory.cpp index 41b24d79f8..de5590426e 100644 --- a/rpcs3/Emu/Cell/lv2/sys_memory.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_memory.cpp @@ -28,10 +28,13 @@ lv2_memory_container::lv2_memory_container(utils::serial& ar, bool from_idm) noe { } -std::shared_ptr lv2_memory_container::load(utils::serial& ar) +std::function lv2_memory_container::load(utils::serial& ar) { // Use idm::last_id() only for the instances at IDM - return std::make_shared(stx::exact_t(ar), true); + return [ptr = make_shared(stx::exact_t(ar), true)](void* storage) + { + *static_cast*>(storage) = ptr; + }; } void lv2_memory_container::save(utils::serial& ar) @@ -43,7 +46,7 @@ lv2_memory_container* lv2_memory_container::search(u32 id) { if (id != SYS_MEMORY_CONTAINER_ID_INVALID) { - return idm::check(id); + return idm::check_unlocked(id); } return &g_fxo->get(); @@ -397,7 +400,7 @@ error_code sys_memory_container_get_size(cpu_thread& cpu, vm::ptr(cid); + const auto ct = idm::get_unlocked(cid); if (!ct) { diff --git a/rpcs3/Emu/Cell/lv2/sys_memory.h b/rpcs3/Emu/Cell/lv2/sys_memory.h index 5184aeed43..c2ca046bcc 100644 --- a/rpcs3/Emu/Cell/lv2/sys_memory.h +++ b/rpcs3/Emu/Cell/lv2/sys_memory.h @@ -74,7 +74,7 @@ struct lv2_memory_container lv2_memory_container(u32 size, bool from_idm = false) noexcept; lv2_memory_container(utils::serial& ar, bool from_idm = false) noexcept; - static std::shared_ptr load(utils::serial& ar); + static std::function load(utils::serial& ar); void save(utils::serial& ar); static lv2_memory_container* search(u32 id); diff --git a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp index 6a7058267b..d134102a73 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp @@ -82,13 +82,13 @@ CellError lv2_memory::on_id_create() return {}; } -std::shared_ptr lv2_memory::load(utils::serial& ar) +std::function lv2_memory::load(utils::serial& ar) { - auto mem = std::make_shared(ar); + auto mem = make_shared(ar); mem->exists++; // Disable on_id_create() - std::shared_ptr ptr = lv2_obj::load(mem->key, mem, +mem->pshared); + auto func = load_func(mem, +mem->pshared); mem->exists--; - return ptr; + return func; } void lv2_memory::save(utils::serial& ar) @@ -128,7 +128,7 @@ error_code create_lv2_shm(bool pshared, u64 ipc_key, u64 size, u32 align, u64 fl if (auto error = lv2_obj::create(_pshared, ipc_key, exclusive ? SYS_SYNC_NEWLY_CREATED : SYS_SYNC_NOT_CARE, [&]() { - return std::make_shared( + return make_shared( static_cast(size), align, flags, @@ -294,7 +294,7 @@ error_code sys_mmapper_allocate_shared_memory_from_container(ppu_thread& ppu, u6 } } - const auto ct = idm::get(cid); + const auto ct = idm::get_unlocked(cid); if (!ct) { @@ -491,7 +491,7 @@ error_code sys_mmapper_allocate_shared_memory_from_container_ext(ppu_thread& ppu } } - const auto ct = idm::get(cid); + const auto ct = idm::get_unlocked(cid); if (!ct) { @@ -797,7 +797,7 @@ error_code sys_mmapper_enable_page_fault_notification(ppu_thread& ppu, u32 start // TODO: Check memory region's flags to make sure the memory can be used for page faults. - auto queue = idm::get(event_queue_id); + auto queue = idm::get_unlocked(event_queue_id); if (!queue) { // Can't connect the queue if it doesn't exist. diff --git a/rpcs3/Emu/Cell/lv2/sys_mmapper.h b/rpcs3/Emu/Cell/lv2/sys_mmapper.h index 3a1211ea58..544ff91ee8 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mmapper.h +++ b/rpcs3/Emu/Cell/lv2/sys_mmapper.h @@ -31,7 +31,7 @@ struct lv2_memory : lv2_obj lv2_memory(u32 size, u32 align, u64 flags, u64 key, bool pshared, lv2_memory_container* ct); lv2_memory(utils::serial& ar); - static std::shared_ptr load(utils::serial& ar); + static std::function load(utils::serial& ar); void save(utils::serial& ar); CellError on_id_create(); diff --git a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp index efd0f1c374..c8ac190c25 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp @@ -25,10 +25,9 @@ lv2_mutex::lv2_mutex(utils::serial& ar) control.raw().owner >>= 1; } -std::shared_ptr lv2_mutex::load(utils::serial& ar) +std::function lv2_mutex::load(utils::serial& ar) { - auto mtx = std::make_shared(ar); - return lv2_obj::load(mtx->key, mtx); + return load_func(make_shared(ar)); } void lv2_mutex::save(utils::serial& ar) @@ -88,7 +87,7 @@ error_code sys_mutex_create(ppu_thread& ppu, vm::ptr mutex_id, vm::ptr(_attr.pshared, _attr.ipc_key, _attr.flags, [&]() { - return std::make_shared( + return make_shared( _attr.protocol, _attr.recursive, _attr.adaptive, diff --git a/rpcs3/Emu/Cell/lv2/sys_mutex.h b/rpcs3/Emu/Cell/lv2/sys_mutex.h index 75f43514e6..f82f913399 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mutex.h +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.h @@ -58,7 +58,7 @@ struct lv2_mutex final : lv2_obj } lv2_mutex(utils::serial& ar); - static std::shared_ptr load(utils::serial& ar); + static std::function load(utils::serial& ar); void save(utils::serial& ar); template diff --git a/rpcs3/Emu/Cell/lv2/sys_net.cpp b/rpcs3/Emu/Cell/lv2/sys_net.cpp index efac7556d1..97d40d6d47 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net.cpp @@ -266,25 +266,25 @@ lv2_socket::lv2_socket(utils::serial& ar, lv2_socket_type _type) ar(last_bound_addr); } -std::shared_ptr lv2_socket::load(utils::serial& ar) +std::function lv2_socket::load(utils::serial& ar) { const lv2_socket_type type{ar}; - std::shared_ptr sock_lv2; + shared_ptr sock_lv2; switch (type) { case SYS_NET_SOCK_STREAM: case SYS_NET_SOCK_DGRAM: { - auto lv2_native = std::make_shared(ar, type); + auto lv2_native = make_shared(ar, type); ensure(lv2_native->create_socket() >= 0); sock_lv2 = std::move(lv2_native); break; } - case SYS_NET_SOCK_RAW: sock_lv2 = std::make_shared(ar, type); break; - case SYS_NET_SOCK_DGRAM_P2P: sock_lv2 = std::make_shared(ar, type); break; - case SYS_NET_SOCK_STREAM_P2P: sock_lv2 = std::make_shared(ar, type); break; + case SYS_NET_SOCK_RAW: sock_lv2 = make_shared(ar, type); break; + case SYS_NET_SOCK_DGRAM_P2P: sock_lv2 = make_shared(ar, type); break; + case SYS_NET_SOCK_STREAM_P2P: sock_lv2 = make_shared(ar, type); break; } if (std::memcmp(&sock_lv2->last_bound_addr, std::array{}.data(), 16)) @@ -293,7 +293,7 @@ std::shared_ptr lv2_socket::load(utils::serial& ar) sock_lv2->bind(sock_lv2->last_bound_addr); } - return sock_lv2; + return [ptr = sock_lv2](void* storage) { *static_cast*>(storage) = ptr; };; } void lv2_socket::save(utils::serial& ar, bool save_only_this_class) @@ -352,7 +352,7 @@ error_code sys_net_bnet_accept(ppu_thread& ppu, s32 s, vm::ptr s32 result = 0; sys_net_sockaddr sn_addr{}; - std::shared_ptr new_socket{}; + shared_ptr new_socket{}; const auto sock = idm::check(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock) { @@ -465,7 +465,7 @@ error_code sys_net_bnet_bind(ppu_thread& ppu, s32 s, vm::cptr return -SYS_NET_EINVAL; } - if (!idm::check(s)) + if (!idm::check_unlocked(s)) { return -SYS_NET_EBADF; } @@ -514,7 +514,7 @@ error_code sys_net_bnet_connect(ppu_thread& ppu, s32 s, vm::ptr(s)) + if (!idm::check_unlocked(s)) { return -SYS_NET_EBADF; } @@ -1194,14 +1194,14 @@ error_code sys_net_bnet_socket(ppu_thread& ppu, lv2_socket_family family, lv2_so return -SYS_NET_EPROTONOSUPPORT; } - std::shared_ptr sock_lv2; + shared_ptr sock_lv2; switch (type) { case SYS_NET_SOCK_STREAM: case SYS_NET_SOCK_DGRAM: { - auto lv2_native = std::make_shared(family, type, protocol); + auto lv2_native = make_shared(family, type, protocol); if (s32 result = lv2_native->create_socket(); result < 0) { return sys_net_error{result}; @@ -1210,9 +1210,9 @@ error_code sys_net_bnet_socket(ppu_thread& ppu, lv2_socket_family family, lv2_so sock_lv2 = std::move(lv2_native); break; } - case SYS_NET_SOCK_RAW: sock_lv2 = std::make_shared(family, type, protocol); break; - case SYS_NET_SOCK_DGRAM_P2P: sock_lv2 = std::make_shared(family, type, protocol); break; - case SYS_NET_SOCK_STREAM_P2P: sock_lv2 = std::make_shared(family, type, protocol); break; + case SYS_NET_SOCK_RAW: sock_lv2 = make_shared(family, type, protocol); break; + case SYS_NET_SOCK_DGRAM_P2P: sock_lv2 = make_shared(family, type, protocol); break; + case SYS_NET_SOCK_STREAM_P2P: sock_lv2 = make_shared(family, type, protocol); break; } const s32 s = idm::import_existing(sock_lv2); @@ -1775,7 +1775,7 @@ error_code sys_net_abort(ppu_thread& ppu, s32 type, u64 arg, s32 flags) { std::lock_guard nw_lock(g_fxo->get().mutex_thread_loop); - const auto sock = idm::get(static_cast(arg)); + const auto sock = idm::get_unlocked(static_cast(arg)); if (!sock) { diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket.cpp index 02f5b2c697..011bc4e8f8 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket.cpp @@ -64,7 +64,7 @@ void lv2_socket::set_poll_event(bs_t event) events += event; } -void lv2_socket::poll_queue(std::shared_ptr ppu, bs_t event, std::function)> poll_cb) +void lv2_socket::poll_queue(shared_ptr ppu, bs_t event, std::function)> poll_cb) { set_poll_event(event); queue.emplace_back(std::move(ppu), poll_cb); diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket.h b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket.h index 8cc84b729a..4cbab143dc 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket.h @@ -60,7 +60,7 @@ public: lv2_socket(lv2_socket_family family, lv2_socket_type type, lv2_ip_protocol protocol); lv2_socket(utils::serial&) {} lv2_socket(utils::serial&, lv2_socket_type type); - static std::shared_ptr load(utils::serial& ar); + static std::function load(utils::serial& ar); void save(utils::serial&, bool save_only_this_class = false); virtual ~lv2_socket() = default; @@ -69,7 +69,7 @@ public: void set_lv2_id(u32 id); bs_t get_events() const; void set_poll_event(bs_t event); - void poll_queue(std::shared_ptr ppu, bs_t event, std::function)> poll_cb); + void poll_queue(shared_ptr ppu, bs_t event, std::function)> poll_cb); u32 clear_queue(ppu_thread*); void handle_events(const pollfd& native_fd, bool unset_connecting = false); void queue_wake(ppu_thread* ppu); @@ -85,7 +85,7 @@ public: #endif public: - virtual std::tuple, sys_net_sockaddr> accept(bool is_lock = true) = 0; + virtual std::tuple, sys_net_sockaddr> accept(bool is_lock = true) = 0; virtual s32 bind(const sys_net_sockaddr& addr) = 0; virtual std::optional connect(const sys_net_sockaddr& addr) = 0; @@ -133,7 +133,7 @@ protected: atomic_bs_t events{}; // Event processing workload (pair of thread id and the processing function) - std::vector, std::function)>>> queue; + std::vector, std::function)>>> queue; // Socket options value keepers // Non-blocking IO option diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp index a6abc1d055..b8398480cb 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.cpp @@ -106,7 +106,7 @@ void lv2_socket_native::set_socket(socket_type socket, lv2_socket_family family, set_non_blocking(); } -std::tuple, sys_net_sockaddr> lv2_socket_native::accept(bool is_lock) +std::tuple, sys_net_sockaddr> lv2_socket_native::accept(bool is_lock) { std::unique_lock lock(mutex, std::defer_lock); @@ -127,7 +127,7 @@ std::tuple, sys_net_sockaddr> lv2_socket_ if (native_socket != invalid_socket) { - auto newsock = std::make_shared(family, type, protocol); + auto newsock = make_single(family, type, protocol); newsock->set_socket(native_socket, family, type, protocol); // Sockets inherit non blocking behaviour from their parent @@ -274,7 +274,7 @@ std::optional lv2_socket_native::connect(const sys_net_sockaddr& addr) #ifdef _WIN32 connecting = true; #endif - this->poll_queue(nullptr, lv2_socket::poll_t::write, [this](bs_t events) -> bool + this->poll_queue(null_ptr, lv2_socket::poll_t::write, [this](bs_t events) -> bool { if (events & lv2_socket::poll_t::write) { diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h index 0ecfdf7278..08a1f4575a 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_native.h @@ -30,13 +30,15 @@ class lv2_socket_native final : public lv2_socket { public: + static constexpr u32 id_type = 1; + lv2_socket_native(lv2_socket_family family, lv2_socket_type type, lv2_ip_protocol protocol); lv2_socket_native(utils::serial& ar, lv2_socket_type type); void save(utils::serial& ar); ~lv2_socket_native(); s32 create_socket(); - std::tuple, sys_net_sockaddr> accept(bool is_lock = true) override; + std::tuple, sys_net_sockaddr> accept(bool is_lock = true) override; s32 bind(const sys_net_sockaddr& addr) override; std::optional connect(const sys_net_sockaddr& addr) override; diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp index c86487042c..a4228a0322 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp @@ -72,7 +72,7 @@ void lv2_socket_p2p::handle_new_data(sys_net_sockaddr_in_p2p p2p_addr, std::vect } } -std::tuple, sys_net_sockaddr> lv2_socket_p2p::accept([[maybe_unused]] bool is_lock) +std::tuple, sys_net_sockaddr> lv2_socket_p2p::accept([[maybe_unused]] bool is_lock) { sys_net.fatal("[P2P] accept() called on a P2P socket"); return {}; diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.h b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.h index 110c3404e0..b8fadb3d53 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.h @@ -9,7 +9,7 @@ public: lv2_socket_p2p(utils::serial& ar, lv2_socket_type type); void save(utils::serial& ar); - std::tuple, sys_net_sockaddr> accept(bool is_lock = true) override; + std::tuple, sys_net_sockaddr> accept(bool is_lock = true) override; s32 bind(const sys_net_sockaddr& addr) override; std::optional connect(const sys_net_sockaddr& addr) override; diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp index e692dea8dd..a363301dc2 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp @@ -467,7 +467,7 @@ bool lv2_socket_p2ps::handle_listening(p2ps_encapsulated_tcp* tcp_header, [[mayb const u16 new_op_vport = tcp_header->src_port; const u64 new_cur_seq = send_hdr.seq + 1; const u64 new_data_beg_seq = send_hdr.ack; - auto sock_lv2 = std::make_shared(socket, port, vport, new_op_addr, new_op_port, new_op_vport, new_cur_seq, new_data_beg_seq, so_nbio); + auto sock_lv2 = make_shared(socket, port, vport, new_op_addr, new_op_port, new_op_vport, new_cur_seq, new_data_beg_seq, so_nbio); const s32 new_sock_id = idm::import_existing(sock_lv2); sock_lv2->set_lv2_id(new_sock_id); const u64 key_connected = (reinterpret_cast(op_addr)->sin_addr.s_addr) | (static_cast(tcp_header->src_port) << 48) | (static_cast(tcp_header->dst_port) << 32); @@ -600,7 +600,7 @@ std::pair lv2_socket_p2ps::getpeername() return {CELL_OK, res}; } -std::tuple, sys_net_sockaddr> lv2_socket_p2ps::accept(bool is_lock) +std::tuple, sys_net_sockaddr> lv2_socket_p2ps::accept(bool is_lock) { std::unique_lock lock(mutex, std::defer_lock); diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h index 6d1333eb58..8158138936 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h @@ -58,6 +58,8 @@ std::vector generate_u2s_packet(const p2ps_encapsulated_tcp& header, const u class lv2_socket_p2ps final : public lv2_socket_p2p { public: + static constexpr u32 id_type = 2; + lv2_socket_p2ps(lv2_socket_family family, lv2_socket_type type, lv2_ip_protocol protocol); lv2_socket_p2ps(socket_type socket, u16 port, u16 vport, u32 op_addr, u16 op_port, u16 op_vport, u64 cur_seq, u64 data_beg_seq, s32 so_nbio); lv2_socket_p2ps(utils::serial& ar, lv2_socket_type type); @@ -70,7 +72,7 @@ public: void send_u2s_packet(std::vector data, const ::sockaddr_in* dst, u64 seq, bool require_ack); void close_stream(); - std::tuple, sys_net_sockaddr> accept(bool is_lock = true) override; + std::tuple, sys_net_sockaddr> accept(bool is_lock = true) override; s32 bind(const sys_net_sockaddr& addr) override; std::optional connect(const sys_net_sockaddr& addr) override; diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.cpp index 2d9bfcff85..6e74bd512f 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.cpp @@ -36,7 +36,7 @@ void lv2_socket_raw::save(utils::serial& ar) lv2_socket::save(ar, true); } -std::tuple, sys_net_sockaddr> lv2_socket_raw::accept([[maybe_unused]] bool is_lock) +std::tuple, sys_net_sockaddr> lv2_socket_raw::accept([[maybe_unused]] bool is_lock) { sys_net.fatal("[RAW] accept() called on a RAW socket"); return {}; diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.h b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.h index 2071fe3155..01b7255884 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.h @@ -5,11 +5,13 @@ class lv2_socket_raw final : public lv2_socket { public: + static constexpr u32 id_type = 1; + lv2_socket_raw(lv2_socket_family family, lv2_socket_type type, lv2_ip_protocol protocol); lv2_socket_raw(utils::serial& ar, lv2_socket_type type); void save(utils::serial& ar); - std::tuple, sys_net_sockaddr> accept(bool is_lock = true) override; + std::tuple, sys_net_sockaddr> accept(bool is_lock = true) override; s32 bind(const sys_net_sockaddr& addr) override; std::optional connect(const sys_net_sockaddr& addr) override; diff --git a/rpcs3/Emu/Cell/lv2/sys_net/network_context.cpp b/rpcs3/Emu/Cell/lv2/sys_net/network_context.cpp index aaf79d4f41..84e90e53fe 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/network_context.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/network_context.cpp @@ -138,7 +138,7 @@ void p2p_thread::bind_sce_np_port() void network_thread::operator()() { - std::vector> socklist; + std::vector> socklist; socklist.reserve(lv2_socket::id_count); { diff --git a/rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp b/rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp index 78970bee2c..574d670978 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp @@ -135,11 +135,11 @@ bool nt_p2p_port::handle_connected(s32 sock_id, p2ps_encapsulated_tcp* tcp_heade bool nt_p2p_port::handle_listening(s32 sock_id, p2ps_encapsulated_tcp* tcp_header, u8* data, ::sockaddr_storage* op_addr) { - auto sock = idm::get(sock_id); + auto sock = idm::get_unlocked(sock_id); if (!sock) return false; - auto& sock_p2ps = reinterpret_cast(*sock.get()); + auto& sock_p2ps = reinterpret_cast(*sock); return sock_p2ps.handle_listening(tcp_header, data, op_addr); } diff --git a/rpcs3/Emu/Cell/lv2/sys_overlay.cpp b/rpcs3/Emu/Cell/lv2/sys_overlay.cpp index 7a9cb08bf4..99b5981795 100644 --- a/rpcs3/Emu/Cell/lv2/sys_overlay.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_overlay.cpp @@ -13,10 +13,10 @@ #include "sys_overlay.h" #include "sys_fs.h" -extern std::pair, CellError> ppu_load_overlay(const ppu_exec_object&, bool virtual_load, const std::string& path, s64 file_offset, utils::serial* ar = nullptr); +extern std::pair, CellError> ppu_load_overlay(const ppu_exec_object&, bool virtual_load, const std::string& path, s64 file_offset, utils::serial* ar = nullptr); -extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0); -extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false); +extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0); +extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false); LOG_CHANNEL(sys_overlay); @@ -68,7 +68,7 @@ static error_code overlay_load_module(vm::ptr ovlmid, const std::string& vp ppu_initialize(*ovlm); - sys_overlay.success(u8"Loaded overlay: “%s” (id=0x%x)", vpath, idm::last_id()); + sys_overlay.success("Loaded overlay: \"%s\" (id=0x%x)", vpath, idm::last_id()); *ovlmid = idm::last_id(); *entry = ovlm->entry; @@ -78,7 +78,7 @@ static error_code overlay_load_module(vm::ptr ovlmid, const std::string& vp fs::file make_file_view(fs::file&& file, u64 offset, u64 size); -std::shared_ptr lv2_overlay::load(utils::serial& ar) +std::function lv2_overlay::load(utils::serial& ar) { const std::string vpath = ar.pop(); const std::string path = vfs::get(vpath); @@ -86,7 +86,7 @@ std::shared_ptr lv2_overlay::load(utils::serial& ar) sys_overlay.success("lv2_overlay::load(): vpath='%s', path='%s', offset=0x%x", vpath, path, offset); - std::shared_ptr ovlm; + shared_ptr ovlm; fs::file file{path.substr(0, path.size() - (offset ? fmt::format("_x%x", offset).size() : 0))}; @@ -110,7 +110,10 @@ std::shared_ptr lv2_overlay::load(utils::serial& ar) sys_overlay.error("lv2_overlay::load(): Failed to find file. (vpath='%s', offset=0x%x)", vpath, offset); } - return ovlm; + return [ovlm](void* storage) + { + *static_cast*>(storage) = ovlm; + }; } void lv2_overlay::save(utils::serial& ar) @@ -156,7 +159,7 @@ error_code sys_overlay_load_module_by_fd(vm::ptr ovlmid, u32 fd, u64 offset return CELL_EINVAL; } - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { diff --git a/rpcs3/Emu/Cell/lv2/sys_overlay.h b/rpcs3/Emu/Cell/lv2/sys_overlay.h index 1636ac38e0..ef1c1ffbd7 100644 --- a/rpcs3/Emu/Cell/lv2/sys_overlay.h +++ b/rpcs3/Emu/Cell/lv2/sys_overlay.h @@ -5,7 +5,7 @@ #include "sys_sync.h" #include -struct lv2_overlay final : lv2_obj, ppu_module +struct lv2_overlay final : ppu_module { static const u32 id_base = 0x25000000; @@ -15,7 +15,7 @@ struct lv2_overlay final : lv2_obj, ppu_module lv2_overlay() = default; lv2_overlay(utils::serial&){} - static std::shared_ptr load(utils::serial& ar); + static std::function load(utils::serial& ar); void save(utils::serial& ar); }; diff --git a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp index 064cceb728..94153404fe 100644 --- a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp @@ -22,9 +22,9 @@ LOG_CHANNEL(sys_ppu_thread); // Simple structure to cleanup previous thread, because can't remove its own thread struct ppu_thread_cleaner { - std::shared_ptr old; + shared_ptr> old; - std::shared_ptr clean(std::shared_ptr ptr) + shared_ptr> clean(shared_ptr> ptr) { return std::exchange(old, std::move(ptr)); } @@ -86,7 +86,7 @@ void _sys_ppu_thread_exit(ppu_thread& ppu, u64 errorcode) ppu_join_status old_status; // Avoid cases where cleaning causes the destructor to be called inside IDM lock scope (for performance) - std::shared_ptr old_ppu; + shared_ptr> old_ppu; { lv2_obj::notify_all_t notify; lv2_obj::prepare_for_sleep(ppu); @@ -115,7 +115,7 @@ void _sys_ppu_thread_exit(ppu_thread& ppu, u64 errorcode) if (old_status != ppu_join_status::joinable) { // Remove self ID from IDM, move owning ptr - old_ppu = g_fxo->get().clean(std::move(idm::find_unlocked>(ppu.id)->second)); + old_ppu = g_fxo->get().clean(idm::withdraw>(ppu.id, 0, std::false_type{})); } // Get writers mask (wait for all current writers to quit) @@ -147,7 +147,7 @@ void _sys_ppu_thread_exit(ppu_thread& ppu, u64 errorcode) if (old_ppu) { // It is detached from IDM now so join must be done explicitly now - *static_cast*>(old_ppu.get()) = thread_state::finished; + *old_ppu = thread_state::finished; } // Need to wait until the current writers finish @@ -435,7 +435,7 @@ error_code sys_ppu_thread_stop(ppu_thread& ppu, u32 thread_id) return CELL_ENOSYS; } - const auto thread = idm::check>(thread_id); + const auto thread = idm::check>(thread_id, [](named_thread&) {}); if (!thread) { @@ -529,7 +529,7 @@ error_code _sys_ppu_thread_create(ppu_thread& ppu, vm::ptr thread_id, vm::p p.arg0 = arg; p.arg1 = unk; - return std::make_shared>(p, ppu_name, prio, 1 - static_cast(flags & 3)); + return stx::make_shared>(p, ppu_name, prio, 1 - static_cast(flags & 3)); }); if (!tid) @@ -539,7 +539,7 @@ error_code _sys_ppu_thread_create(ppu_thread& ppu, vm::ptr thread_id, vm::p return CELL_EAGAIN; } - sys_ppu_thread.warning(u8"_sys_ppu_thread_create(): Thread “%s” created (id=0x%x, func=*0x%x, rtoc=0x%x, user-tls=0x%x)", ppu_name, tid, entry.addr, entry.rtoc, tls); + sys_ppu_thread.warning("_sys_ppu_thread_create(): Thread \"%s\" created (id=0x%x, func=*0x%x, rtoc=0x%x, user-tls=0x%x)", ppu_name, tid, entry.addr, entry.rtoc, tls); ppu.check_state(); *thread_id = tid; @@ -594,7 +594,7 @@ error_code sys_ppu_thread_rename(ppu_thread& ppu, u32 thread_id, vm::cptr sys_ppu_thread.warning("sys_ppu_thread_rename(thread_id=0x%x, name=*0x%x)", thread_id, name); - const auto thread = idm::get>(thread_id); + const auto thread = idm::get_unlocked>(thread_id); if (!thread) { @@ -618,7 +618,7 @@ error_code sys_ppu_thread_rename(ppu_thread& ppu, u32 thread_id, vm::cptr auto _name = make_single(std::move(out_str)); // thread_ctrl name is not changed (TODO) - sys_ppu_thread.warning(u8"sys_ppu_thread_rename(): Thread renamed to “%s”", *_name); + sys_ppu_thread.warning("sys_ppu_thread_rename(): Thread renamed to \"%s\"", *_name); thread->ppu_tname.store(std::move(_name)); thread_ctrl::set_name(*thread, thread->thread_name); // TODO: Currently sets debugger thread name only for local thread @@ -631,7 +631,7 @@ error_code sys_ppu_thread_recover_page_fault(ppu_thread& ppu, u32 thread_id) sys_ppu_thread.warning("sys_ppu_thread_recover_page_fault(thread_id=0x%x)", thread_id); - const auto thread = idm::get>(thread_id); + const auto thread = idm::get_unlocked>(thread_id); if (!thread) { @@ -647,7 +647,7 @@ error_code sys_ppu_thread_get_page_fault_context(ppu_thread& ppu, u32 thread_id, sys_ppu_thread.todo("sys_ppu_thread_get_page_fault_context(thread_id=0x%x, ctxt=*0x%x)", thread_id, ctxt); - const auto thread = idm::get>(thread_id); + const auto thread = idm::get_unlocked>(thread_id); if (!thread) { diff --git a/rpcs3/Emu/Cell/lv2/sys_process.cpp b/rpcs3/Emu/Cell/lv2/sys_process.cpp index 57b0241b70..cfe0859569 100644 --- a/rpcs3/Emu/Cell/lv2/sys_process.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_process.cpp @@ -231,7 +231,7 @@ CellError process_is_spu_lock_line_reservation_address(u32 addr, u64 flags) return CELL_EPERM; default: { - if (auto vm0 = idm::get(sys_vm_t::find_id(addr))) + if (auto vm0 = idm::get_unlocked(sys_vm_t::find_id(addr))) { // sys_vm area was not covering the address specified but made a reservation on the entire 256mb region if (vm0->addr + vm0->size - 1 < addr) @@ -433,16 +433,26 @@ void lv2_exitspawn(ppu_thread& ppu, std::vector& argv, std::vector< using namespace id_manager; - auto func = [is_real_reboot, old_size = g_fxo->get().size, vec = (reader_lock{g_mutex}, g_fxo->get>().vec)](u32 sdk_suggested_mem) mutable + shared_ptr idm_capture = make_shared(); + { + reader_lock rlock{g_mutex}; + g_fxo->get>().save(*idm_capture); + } + + idm_capture->set_reading_state(); + + auto func = [is_real_reboot, old_size = g_fxo->get().size, idm_capture](u32 sdk_suggested_mem) mutable { if (is_real_reboot) { // Do not save containers on actual reboot - vec.clear(); + ensure(g_fxo->init>()); + } + else + { + // Save LV2 memory containers + ensure(g_fxo->init>(*idm_capture)); } - - // Save LV2 memory containers - ensure(g_fxo->init>())->vec = std::move(vec); // Empty the containers, accumulate their total size u32 total_size = 0; diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp index da24edbedb..42903d7454 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -17,12 +17,12 @@ #include "sys_memory.h" #include -extern void dump_executable(std::span data, const ppu_module* _module, std::string_view title_id); +extern void dump_executable(std::span data, const ppu_module* _module, std::string_view title_id); -extern std::shared_ptr ppu_load_prx(const ppu_prx_object&, bool virtual_load, const std::string&, s64, utils::serial* = nullptr); +extern shared_ptr ppu_load_prx(const ppu_prx_object&, bool virtual_load, const std::string&, s64, utils::serial* = nullptr); extern void ppu_unload_prx(const lv2_prx& prx); -extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0); -extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false); +extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0); +extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false); extern void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string& loaded_flags); LOG_CHANNEL(sys_prx); @@ -235,7 +235,7 @@ static error_code prx_load_module(const std::string& vpath, u64 flags, vm::ptrname = std::move(name); prx->path = std::move(path); - sys_prx.warning(u8"Ignored module: “%s” (id=0x%x)", vpath, idm::last_id()); + sys_prx.warning("Ignored module: \"%s\" (id=0x%x)", vpath, idm::last_id()); return not_an_error(idm::last_id()); }; @@ -253,7 +253,7 @@ static error_code prx_load_module(const std::string& vpath, u64 flags, vm::ptr lv2_prx::load(utils::serial& ar) +std::function lv2_prx::load(utils::serial& ar) { [[maybe_unused]] const s32 version = GET_SERIALIZATION_VERSION(lv2_prx_overlay); @@ -316,11 +316,11 @@ std::shared_ptr lv2_prx::load(utils::serial& ar) usz seg_count = 0; ar.deserialize_vle(seg_count); - std::shared_ptr prx; + shared_ptr prx; auto hle_load = [&]() { - prx = std::make_shared(); + prx = make_shared(); prx->path = path; prx->name = path.substr(path.find_last_of(fs::delim) + 1); }; @@ -337,7 +337,7 @@ std::shared_ptr lv2_prx::load(utils::serial& ar) { u128 klic = g_fxo->get().last_key(); file = make_file_view(std::move(file), offset, umax); - prx = ppu_load_prx(ppu_prx_object{ decrypt_self(std::move(file), reinterpret_cast(&klic)) }, false, path, 0, &ar); + prx = ppu_load_prx(ppu_prx_object{decrypt_self(std::move(file), reinterpret_cast(&klic))}, false, path, 0, &ar); prx->m_loaded_flags = std::move(loaded_flags); prx->m_external_loaded_flags = std::move(external_flags); @@ -369,7 +369,11 @@ std::shared_ptr lv2_prx::load(utils::serial& ar) } prx->state = state; - return prx; + + return [prx](void* storage) + { + *static_cast*>(storage) = prx; + }; } void lv2_prx::save(utils::serial& ar) @@ -407,7 +411,7 @@ error_code _sys_prx_load_module_by_fd(ppu_thread& ppu, s32 fd, u64 offset, u64 f sys_prx.warning("_sys_prx_load_module_by_fd(fd=%d, offset=0x%x, flags=0x%x, pOpt=*0x%x)", fd, offset, flags, pOpt); - const auto file = idm::get(fd); + const auto file = idm::get_unlocked(fd); if (!file) { @@ -519,7 +523,7 @@ error_code _sys_prx_start_module(ppu_thread& ppu, u32 id, u64 flags, vm::ptr(id); + const auto prx = idm::get_unlocked(id); if (!prx) { @@ -600,7 +604,7 @@ error_code _sys_prx_stop_module(ppu_thread& ppu, u32 id, u64 flags, vm::ptr(id); + const auto prx = idm::get_unlocked(id); if (!prx) { @@ -1013,7 +1017,7 @@ error_code _sys_prx_get_module_info(ppu_thread& ppu, u32 id, u64 flags, vm::ptr< sys_prx.warning("_sys_prx_get_module_info(id=0x%x, flags=%d, pOpt=*0x%x)", id, flags, pOpt); - const auto prx = idm::get(id); + const auto prx = idm::get_unlocked(id); if (!pOpt) { diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.h b/rpcs3/Emu/Cell/lv2/sys_prx.h index 328d67cc6e..af0539ecc0 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.h +++ b/rpcs3/Emu/Cell/lv2/sys_prx.h @@ -172,7 +172,7 @@ enum : u32 PRX_STATE_DESTROYED, // Last state, the module cannot be restarted }; -struct lv2_prx final : lv2_obj, ppu_module +struct lv2_prx final : ppu_module { static const u32 id_base = 0x23000000; @@ -204,7 +204,7 @@ struct lv2_prx final : lv2_obj, ppu_module lv2_prx() noexcept = default; lv2_prx(utils::serial&) {} - static std::shared_ptr load(utils::serial&); + static std::function load(utils::serial&); void save(utils::serial& ar); }; diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp index f2d1b33815..896dd0b00c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp @@ -425,7 +425,7 @@ error_code sys_rsx_context_iomap(cpu_thread& cpu, u32 context_id, u32 io, u32 ea return CELL_EINVAL; } - if ((addr == ea || !(addr % 0x1000'0000)) && idm::check(sys_vm_t::find_id(addr))) + if ((addr == ea || !(addr % 0x1000'0000)) && idm::check_unlocked(sys_vm_t::find_id(addr))) { // Virtual memory is disallowed return CELL_EINVAL; diff --git a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp index 197a9027bb..c391602bc3 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp @@ -164,7 +164,7 @@ error_code sys_rsxaudio_initialize(vm::ptr handle) return CELL_ENOMEM; } - const auto rsxaudio_obj = idm::get(id); + const auto rsxaudio_obj = idm::get_unlocked(id); std::lock_guard lock(rsxaudio_obj->mutex); rsxaudio_obj->shmem = vm::addr_t{vm::alloc(sizeof(rsxaudio_shmem), vm::main)}; @@ -201,7 +201,7 @@ error_code sys_rsxaudio_finalize(u32 handle) { sys_rsxaudio.trace("sys_rsxaudio_finalize(handle=0x%x)", handle); - const auto rsxaudio_obj = idm::get(handle); + const auto rsxaudio_obj = idm::get_unlocked(handle); if (!rsxaudio_obj) { @@ -219,7 +219,7 @@ error_code sys_rsxaudio_finalize(u32 handle) { std::lock_guard ra_obj_lock{rsxaudio_thread.rsxaudio_obj_upd_m}; - rsxaudio_thread.rsxaudio_obj_ptr = {}; + rsxaudio_thread.rsxaudio_obj_ptr = null_ptr; } rsxaudio_obj->init = false; @@ -235,7 +235,7 @@ error_code sys_rsxaudio_import_shared_memory(u32 handle, vm::ptr addr) { sys_rsxaudio.trace("sys_rsxaudio_import_shared_memory(handle=0x%x, addr=*0x%x)", handle, addr); - const auto rsxaudio_obj = idm::get(handle); + const auto rsxaudio_obj = idm::get_unlocked(handle); if (!rsxaudio_obj) { @@ -264,7 +264,7 @@ error_code sys_rsxaudio_unimport_shared_memory(u32 handle, vm::ptr addr /* { sys_rsxaudio.trace("sys_rsxaudio_unimport_shared_memory(handle=0x%x, addr=*0x%x)", handle, addr); - const auto rsxaudio_obj = idm::get(handle); + const auto rsxaudio_obj = idm::get_unlocked(handle); if (!rsxaudio_obj) { @@ -287,7 +287,7 @@ error_code sys_rsxaudio_create_connection(u32 handle) { sys_rsxaudio.trace("sys_rsxaudio_create_connection(handle=0x%x)", handle); - const auto rsxaudio_obj = idm::get(handle); + const auto rsxaudio_obj = idm::get_unlocked(handle); if (!rsxaudio_obj) { @@ -305,15 +305,15 @@ error_code sys_rsxaudio_create_connection(u32 handle) const error_code port_create_status = [&]() -> error_code { - if (auto queue1 = idm::get(sh_page->ctrl.event_queue_1_id)) + if (auto queue1 = idm::get_unlocked(sh_page->ctrl.event_queue_1_id)) { rsxaudio_obj->event_queue[0] = queue1; - if (auto queue2 = idm::get(sh_page->ctrl.event_queue_2_id)) + if (auto queue2 = idm::get_unlocked(sh_page->ctrl.event_queue_2_id)) { rsxaudio_obj->event_queue[1] = queue2; - if (auto queue3 = idm::get(sh_page->ctrl.event_queue_3_id)) + if (auto queue3 = idm::get_unlocked(sh_page->ctrl.event_queue_3_id)) { rsxaudio_obj->event_queue[2] = queue3; @@ -350,7 +350,7 @@ error_code sys_rsxaudio_close_connection(u32 handle) { sys_rsxaudio.trace("sys_rsxaudio_close_connection(handle=0x%x)", handle); - const auto rsxaudio_obj = idm::get(handle); + const auto rsxaudio_obj = idm::get_unlocked(handle); if (!rsxaudio_obj) { @@ -367,7 +367,7 @@ error_code sys_rsxaudio_close_connection(u32 handle) { auto& rsxaudio_thread = g_fxo->get(); std::lock_guard ra_obj_lock{rsxaudio_thread.rsxaudio_obj_upd_m}; - rsxaudio_thread.rsxaudio_obj_ptr = {}; + rsxaudio_thread.rsxaudio_obj_ptr = null_ptr; } for (u32 q_idx = 0; q_idx < SYS_RSXAUDIO_PORT_CNT; q_idx++) @@ -382,7 +382,7 @@ error_code sys_rsxaudio_prepare_process(u32 handle) { sys_rsxaudio.trace("sys_rsxaudio_prepare_process(handle=0x%x)", handle); - const auto rsxaudio_obj = idm::get(handle); + const auto rsxaudio_obj = idm::get_unlocked(handle); if (!rsxaudio_obj) { @@ -413,7 +413,7 @@ error_code sys_rsxaudio_start_process(u32 handle) { sys_rsxaudio.trace("sys_rsxaudio_start_process(handle=0x%x)", handle); - const auto rsxaudio_obj = idm::get(handle); + const auto rsxaudio_obj = idm::get_unlocked(handle); if (!rsxaudio_obj) { @@ -463,7 +463,7 @@ error_code sys_rsxaudio_stop_process(u32 handle) { sys_rsxaudio.trace("sys_rsxaudio_stop_process(handle=0x%x)", handle); - const auto rsxaudio_obj = idm::get(handle); + const auto rsxaudio_obj = idm::get_unlocked(handle); if (!rsxaudio_obj) { @@ -511,7 +511,7 @@ error_code sys_rsxaudio_get_dma_param(u32 handle, u32 flag, vm::ptr out) { sys_rsxaudio.trace("sys_rsxaudio_get_dma_param(handle=0x%x, flag=0x%x, out=0x%x)", handle, flag, out); - const auto rsxaudio_obj = idm::get(handle); + const auto rsxaudio_obj = idm::get_unlocked(handle); if (!rsxaudio_obj) { diff --git a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.h b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.h index 609215fbe4..e13b33816d 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.h +++ b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.h @@ -161,7 +161,7 @@ struct lv2_rsxaudio final : lv2_obj vm::addr_t shmem{}; - std::array, SYS_RSXAUDIO_PORT_CNT> event_queue{}; + std::array, SYS_RSXAUDIO_PORT_CNT> event_queue{}; // lv2 uses port memory addresses for their names static constexpr std::array event_port_name{ 0x8000000000400100, 0x8000000000400200, 0x8000000000400300 }; @@ -583,7 +583,7 @@ public: atomic_t rsxaudio_ctx_allocated = false; shared_mutex rsxaudio_obj_upd_m{}; - std::shared_ptr rsxaudio_obj_ptr{}; + shared_ptr rsxaudio_obj_ptr{}; void operator()(); rsxaudio_data_thread& operator=(thread_state state); diff --git a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp index fe77f6b421..173fe68a79 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp @@ -19,10 +19,9 @@ lv2_rwlock::lv2_rwlock(utils::serial& ar) ar(owner); } -std::shared_ptr lv2_rwlock::load(utils::serial& ar) +std::function lv2_rwlock::load(utils::serial& ar) { - auto rwlock = std::make_shared(ar); - return lv2_obj::load(rwlock->key, rwlock); + return load_func(make_shared(stx::exact_t(ar))); } void lv2_rwlock::save(utils::serial& ar) @@ -56,7 +55,7 @@ error_code sys_rwlock_create(ppu_thread& ppu, vm::ptr rw_lock_id, vm::ptr(_attr.pshared, ipc_key, _attr.flags, [&] { - return std::make_shared(protocol, ipc_key, _attr.name_u64); + return make_shared(protocol, ipc_key, _attr.name_u64); })) { return error; diff --git a/rpcs3/Emu/Cell/lv2/sys_rwlock.h b/rpcs3/Emu/Cell/lv2/sys_rwlock.h index c3016af5ea..9bfcac0008 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rwlock.h +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.h @@ -40,7 +40,7 @@ struct lv2_rwlock final : lv2_obj } lv2_rwlock(utils::serial& ar); - static std::shared_ptr load(utils::serial& ar); + static std::function load(utils::serial& ar); void save(utils::serial& ar); }; diff --git a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp index 7cf7ffd03d..02e40522e2 100644 --- a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp @@ -20,10 +20,9 @@ lv2_sema::lv2_sema(utils::serial& ar) ar(val); } -std::shared_ptr lv2_sema::load(utils::serial& ar) +std::function lv2_sema::load(utils::serial& ar) { - auto sema = std::make_shared(ar); - return lv2_obj::load(sema->key, sema); + return load_func(make_shared(stx::exact_t(ar))); } void lv2_sema::save(utils::serial& ar) @@ -68,7 +67,7 @@ error_code sys_semaphore_create(ppu_thread& ppu, vm::ptr sem_id, vm::ptr(_attr.pshared, ipc_key, _attr.flags, [&] { - return std::make_shared(protocol, ipc_key, _attr.name_u64, max_val, initial_val); + return make_shared(protocol, ipc_key, _attr.name_u64, max_val, initial_val); })) { return error; diff --git a/rpcs3/Emu/Cell/lv2/sys_semaphore.h b/rpcs3/Emu/Cell/lv2/sys_semaphore.h index 9267c633c4..737d2b0e69 100644 --- a/rpcs3/Emu/Cell/lv2/sys_semaphore.h +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.h @@ -42,7 +42,7 @@ struct lv2_sema final : lv2_obj } lv2_sema(utils::serial& ar); - static std::shared_ptr load(utils::serial& ar); + static std::function load(utils::serial& ar); void save(utils::serial& ar); }; diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index 0de03fcbaa..61a5ee80d1 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -228,7 +228,7 @@ lv2_spu_group::lv2_spu_group(utils::serial& ar) noexcept if (ar.pop()) { ar(id_manager::g_id); - thread = std::make_shared>(stx::launch_retainer{}, ar, this); + thread = stx::make_shared>(stx::launch_retainer{}, ar, this); ensure(idm::import_existing>(thread, idm::last_id())); running += !thread->stop_flag_removal_protection; } @@ -340,7 +340,7 @@ void lv2_spu_image::save(utils::serial& ar) } // Get spu thread ptr, returns group ptr as well for refcounting -std::pair*, std::shared_ptr> lv2_spu_group::get_thread(u32 id) +std::pair*, shared_ptr> lv2_spu_group::get_thread(u32 id) { if (id >= 0x06000000) { @@ -349,7 +349,7 @@ std::pair*, std::shared_ptr> lv2_spu_gro } // Bits 0-23 contain group id (without id base) - decltype(get_thread(0)) res{nullptr, idm::get((id & 0xFFFFFF) | (lv2_spu_group::id_base & ~0xFFFFFF))}; + decltype(get_thread(0)) res{nullptr, idm::get_unlocked((id & 0xFFFFFF) | (lv2_spu_group::id_base & ~0xFFFFFF))}; // Bits 24-31 contain thread index within the group const u32 index = id >> 24; @@ -461,7 +461,7 @@ error_code _sys_spu_image_get_information(ppu_thread& ppu, vm::ptr(img->entry_point); + const auto image = idm::get_unlocked(img->entry_point); if (!image) { @@ -544,7 +544,7 @@ error_code _sys_spu_image_get_segments(ppu_thread& ppu, vm::ptr i return CELL_EINVAL; } - const auto handle = idm::get(img->entry_point); + const auto handle = idm::get_unlocked(img->entry_point); if (!handle) { @@ -604,7 +604,7 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr thread, u32 g { case SYS_SPU_IMAGE_TYPE_KERNEL: { - const auto handle = idm::get(image.entry_point); + const auto handle = idm::get_unlocked(image.entry_point); if (!handle) { @@ -702,7 +702,7 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr thread, u32 g // Read thread name const std::string thread_name(attr_data.name.get_ptr(), std::max(attr_data.name_len, 1) - 1); - const auto group = idm::get(group_id); + const auto group = idm::get_unlocked(group_id); if (!group) { @@ -737,7 +737,7 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr thread, u32 g ensure(idm::import>([&]() { - const auto spu = std::make_shared>(group.get(), spu_num, thread_name, tid, false, option); + const auto spu = stx::make_shared>(group.get(), spu_num, thread_name, tid, false, option); group->threads[inited] = spu; group->threads_map[spu_num] = static_cast(inited); return spu; @@ -763,7 +763,7 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr thread, u32 g } lock.unlock(); - sys_spu.warning(u8"sys_spu_thread_initialize(): Thread “%s” created (id=0x%x)", thread_name, tid); + sys_spu.warning("sys_spu_thread_initialize(): Thread \"%s\" created (id=0x%x)", thread_name, tid); ppu.check_state(); *thread = tid; @@ -927,7 +927,7 @@ error_code sys_spu_thread_group_create(ppu_thread& ppu, vm::ptr id, u32 num if (use_memct && mem_size) { - const auto sct = idm::get(attr_data.ct); + const auto sct = idm::get_unlocked(attr_data.ct); if (!sct) { @@ -970,7 +970,7 @@ error_code sys_spu_thread_group_create(ppu_thread& ppu, vm::ptr id, u32 num } lock.unlock(); - sys_spu.warning(u8"sys_spu_thread_group_create(): Thread group “%s” created (id=0x%x)", group->name, idm::last_id()); + sys_spu.warning("sys_spu_thread_group_create(): Thread group \"%s\" created (id=0x%x)", group->name, idm::last_id()); ppu.check_state(); *id = idm::last_id(); @@ -1040,7 +1040,7 @@ error_code sys_spu_thread_group_start(ppu_thread& ppu, u32 id) sys_spu.trace("sys_spu_thread_group_start(id=0x%x)", id); - const auto group = idm::get(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1126,7 +1126,7 @@ error_code sys_spu_thread_group_suspend(ppu_thread& ppu, u32 id) sys_spu.trace("sys_spu_thread_group_suspend(id=0x%x)", id); - const auto group = idm::get(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1209,7 +1209,7 @@ error_code sys_spu_thread_group_resume(ppu_thread& ppu, u32 id) sys_spu.trace("sys_spu_thread_group_resume(id=0x%x)", id); - const auto group = idm::get(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1297,7 +1297,7 @@ error_code sys_spu_thread_group_yield(ppu_thread& ppu, u32 id) sys_spu.trace("sys_spu_thread_group_yield(id=0x%x)", id); - const auto group = idm::get(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1331,7 +1331,7 @@ error_code sys_spu_thread_group_terminate(ppu_thread& ppu, u32 id, s32 value) sys_spu.trace("sys_spu_thread_group_terminate(id=0x%x, value=0x%x)", id, value); - const auto group = idm::get(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1450,7 +1450,7 @@ error_code sys_spu_thread_group_join(ppu_thread& ppu, u32 id, vm::ptr cause sys_spu.trace("sys_spu_thread_group_join(id=0x%x, cause=*0x%x, status=*0x%x)", id, cause, status); - const auto group = idm::get(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1556,7 +1556,7 @@ error_code sys_spu_thread_group_set_priority(ppu_thread& ppu, u32 id, s32 priori sys_spu.trace("sys_spu_thread_group_set_priority(id=0x%x, priority=%d)", id, priority); - const auto group = idm::get(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1582,7 +1582,7 @@ error_code sys_spu_thread_group_get_priority(ppu_thread& ppu, u32 id, vm::ptr(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1609,7 +1609,7 @@ error_code sys_spu_thread_group_set_cooperative_victims(ppu_thread& ppu, u32 id, sys_spu.warning("sys_spu_thread_group_set_cooperative_victims(id=0x%x, threads_mask=0x%x)", id, threads_mask); - const auto group = idm::get(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1637,7 +1637,7 @@ error_code sys_spu_thread_group_syscall_253(ppu_thread& ppu, u32 id, vm::ptr(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1855,7 +1855,7 @@ error_code sys_spu_thread_group_connect_event(ppu_thread& ppu, u32 id, u32 eq, u sys_spu.warning("sys_spu_thread_group_connect_event(id=0x%x, eq=0x%x, et=%d)", id, eq, et); - const auto group = idm::get(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1879,7 +1879,7 @@ error_code sys_spu_thread_group_connect_event(ppu_thread& ppu, u32 id, u32 eq, u return CELL_EINVAL; } - auto queue = idm::get(eq); + auto queue = idm::get_unlocked(eq); std::lock_guard lock(group->mutex); @@ -1904,7 +1904,7 @@ error_code sys_spu_thread_group_disconnect_event(ppu_thread& ppu, u32 id, u32 et sys_spu.warning("sys_spu_thread_group_disconnect_event(id=0x%x, et=%d)", id, et); - const auto group = idm::get(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -1939,7 +1939,7 @@ error_code sys_spu_thread_connect_event(ppu_thread& ppu, u32 id, u32 eq, u32 et, sys_spu.warning("sys_spu_thread_connect_event(id=0x%x, eq=0x%x, et=%d, spup=%d)", id, eq, et, spup); const auto [thread, group] = lv2_spu_group::get_thread(id); - auto queue = idm::get(eq); + auto queue = idm::get_unlocked(eq); if (!queue || !thread) [[unlikely]] { @@ -2006,7 +2006,7 @@ error_code sys_spu_thread_bind_queue(ppu_thread& ppu, u32 id, u32 spuq, u32 spuq sys_spu.warning("sys_spu_thread_bind_queue(id=0x%x, spuq=0x%x, spuq_num=0x%x)", id, spuq, spuq_num); const auto [thread, group] = lv2_spu_group::get_thread(id); - auto queue = idm::get(spuq); + auto queue = idm::get_unlocked(spuq);; if (!queue || !thread) [[unlikely]] { @@ -2096,8 +2096,8 @@ error_code sys_spu_thread_group_connect_event_all_threads(ppu_thread& ppu, u32 i return CELL_EINVAL; } - const auto group = idm::get(id); - const auto queue = idm::get(eq); + const auto group = idm::get_unlocked(id); + const auto queue = idm::get_unlocked(eq); if (!group || !queue) { @@ -2178,7 +2178,7 @@ error_code sys_spu_thread_group_disconnect_event_all_threads(ppu_thread& ppu, u3 return CELL_EINVAL; } - const auto group = idm::get(id); + const auto group = idm::get_unlocked(id); if (!group) { @@ -2258,7 +2258,7 @@ error_code sys_raw_spu_recover_page_fault(ppu_thread& ppu, u32 id) sys_spu.warning("sys_raw_spu_recover_page_fault(id=0x%x)", id); - const auto thread = idm::get>(spu_thread::find_raw_spu(id)); + const auto thread = idm::get_unlocked>(spu_thread::find_raw_spu(id)); if (!thread) [[unlikely]] { @@ -2367,7 +2367,7 @@ error_code sys_isolated_spu_create(ppu_thread& ppu, vm::ptr id, vm::ptr(img.entry_point); + auto image_info = idm::get_unlocked(img.entry_point); img.deploy(thread->ls, std::span(image_info->segs.get_ptr(), image_info->nsegs)); thread->write_reg(ls_addr + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, image_info->e_entry); @@ -2402,7 +2402,7 @@ error_code raw_spu_destroy(ppu_thread& ppu, u32 id) // TODO: CELL_EBUSY is not returned // Kernel objects which must be removed - std::vector, u32>> to_remove; + std::vector, u32>> to_remove; // Clear interrupt handlers for (auto& intr : thread->int_ctrl) @@ -2484,7 +2484,7 @@ error_code raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 /*hwthread*/, const auto tag = idm::import([&]() { - std::shared_ptr result; + shared_ptr result; auto thread = idm::check_unlocked>(spu_thread::find_raw_spu(id)); @@ -2502,7 +2502,7 @@ error_code raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 /*hwthread*/, return result; } - result = std::make_shared(); + result = make_single(); int_ctrl.tag = result; return result; }); @@ -2543,7 +2543,7 @@ error_code raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask) return CELL_EINVAL; } - const auto thread = idm::get>(spu_thread::find_raw_spu(id)); + const auto thread = idm::get_unlocked>(spu_thread::find_raw_spu(id)); if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]] { @@ -2582,7 +2582,7 @@ error_code raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat) return CELL_EINVAL; } - const auto thread = idm::get>(spu_thread::find_raw_spu(id)); + const auto thread = idm::get_unlocked>(spu_thread::find_raw_spu(id)); if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]] { @@ -2620,7 +2620,7 @@ error_code raw_spu_get_int_control(u32 id, u32 class_id, vm::ptr value, ato return CELL_EINVAL; } - const auto thread = idm::get>(spu_thread::find_raw_spu(id)); + const auto thread = idm::get_unlocked>(spu_thread::find_raw_spu(id)); if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]] { @@ -2672,7 +2672,7 @@ error_code sys_isolated_spu_get_int_stat(ppu_thread& ppu, u32 id, u32 class_id, template error_code raw_spu_read_puint_mb(u32 id, vm::ptr value) { - const auto thread = idm::get>(spu_thread::find_raw_spu(id)); + const auto thread = idm::get_unlocked>(spu_thread::find_raw_spu(id)); if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]] { @@ -2711,7 +2711,7 @@ error_code raw_spu_set_spu_cfg(u32 id, u32 value) fmt::throw_exception("Unexpected value (0x%x)", value); } - const auto thread = idm::get>(spu_thread::find_raw_spu(id)); + const auto thread = idm::get_unlocked>(spu_thread::find_raw_spu(id)); if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]] { @@ -2744,7 +2744,7 @@ error_code sys_isolated_spu_set_spu_cfg(ppu_thread& ppu, u32 id, u32 value) template error_code raw_spu_get_spu_cfg(u32 id, vm::ptr value) { - const auto thread = idm::get>(spu_thread::find_raw_spu(id)); + const auto thread = idm::get_unlocked>(spu_thread::find_raw_spu(id)); if (!thread || thread->get_type() != (isolated ? spu_type::isolated : spu_type::raw)) [[unlikely]] { @@ -2781,7 +2781,7 @@ error_code sys_isolated_spu_start(ppu_thread& ppu, u32 id) sys_spu.todo("sys_isolated_spu_start(id=%d)", id); - const auto thread = idm::get>(spu_thread::find_raw_spu(id)); + const auto thread = idm::get_unlocked>(spu_thread::find_raw_spu(id)); if (!thread) [[unlikely]] { diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.h b/rpcs3/Emu/Cell/lv2/sys_spu.h index 7ce2c8b2ef..c1f6c31bb5 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.h +++ b/rpcs3/Emu/Cell/lv2/sys_spu.h @@ -296,14 +296,14 @@ struct lv2_spu_group class ppu_thread* waiter = nullptr; bool set_terminate = false; - std::array>, 8> threads; // SPU Threads + std::array>, 8> threads; // SPU Threads std::array threads_map; // SPU Threads map based number std::array>, 8> imgs; // Entry points, SPU image segments std::array, 8> args; // SPU Thread Arguments - std::shared_ptr ep_run; // port for SYS_SPU_THREAD_GROUP_EVENT_RUN events - std::shared_ptr ep_exception; // TODO: SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION - std::shared_ptr ep_sysmodule; // TODO: SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE + shared_ptr ep_run; // port for SYS_SPU_THREAD_GROUP_EVENT_RUN events + shared_ptr ep_exception; // TODO: SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION + shared_ptr ep_sysmodule; // TODO: SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE lv2_spu_group(std::string name, u32 num, s32 _prio, s32 type, lv2_memory_container* ct, bool uses_scheduler, u32 mem_size) noexcept : name(std::move(name)) @@ -344,7 +344,7 @@ struct lv2_spu_group return ep_sysmodule ? ep_sysmodule->send(SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE_KEY, data1, data2, data3) : CELL_ENOTCONN; } - static std::pair*, std::shared_ptr> get_thread(u32 id); + static std::pair*, shared_ptr> get_thread(u32 id); }; class ppu_thread; diff --git a/rpcs3/Emu/Cell/lv2/sys_storage.cpp b/rpcs3/Emu/Cell/lv2/sys_storage.cpp index e5e1aec24e..07e2956d31 100644 --- a/rpcs3/Emu/Cell/lv2/sys_storage.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_storage.cpp @@ -16,7 +16,7 @@ namespace struct storage_manager { // This is probably wrong and should be assigned per fd or something - atomic_ptr> asyncequeue; + atomic_ptr> asyncequeue; }; } @@ -65,7 +65,7 @@ error_code sys_storage_read(u32 fd, u32 mode, u32 start_sector, u32 num_sectors, } std::memset(bounce_buf.get_ptr(), 0, num_sectors * 0x200ull); - const auto handle = idm::get(fd); + const auto handle = idm::get_unlocked(fd); if (!handle) { @@ -94,7 +94,7 @@ error_code sys_storage_write(u32 fd, u32 mode, u32 start_sector, u32 num_sectors return CELL_EFAULT; } - const auto handle = idm::get(fd); + const auto handle = idm::get_unlocked(fd); if (!handle) { @@ -119,7 +119,7 @@ error_code sys_storage_async_configure(u32 fd, u32 io_buf, u32 equeue_id, u32 un auto& manager = g_fxo->get(); - if (auto queue = idm::get(equeue_id)) + if (auto queue = idm::get_unlocked(equeue_id)) { manager.asyncequeue.store(queue); } diff --git a/rpcs3/Emu/Cell/lv2/sys_sync.h b/rpcs3/Emu/Cell/lv2/sys_sync.h index ba3b074e66..c8c6096a01 100644 --- a/rpcs3/Emu/Cell/lv2/sys_sync.h +++ b/rpcs3/Emu/Cell/lv2/sys_sync.h @@ -9,6 +9,8 @@ #include "Emu/IdManager.h" #include "Emu/IPC.h" +#include "util/shared_ptr.hpp" + #include // attr_protocol (waiting scheduling policy) @@ -97,7 +99,9 @@ public: lv2_obj() noexcept = default; lv2_obj(u32 i) noexcept : exists{ i } {} + lv2_obj(lv2_obj&& rhs) noexcept : exists{ +rhs.exists } {} lv2_obj(utils::serial&) noexcept {} + lv2_obj& operator=(lv2_obj&& rhs) noexcept { exists = +rhs.exists; return *this; } void save(utils::serial&) {} // Existence validation (workaround for shared-ptr ref-counting) @@ -348,11 +352,11 @@ public: // EAGAIN for IDM IDs shortage CellError error = CELL_EAGAIN; - if (!idm::import([&]() -> std::shared_ptr + if (!idm::import([&]() -> shared_ptr { - std::shared_ptr result = make(); + shared_ptr result = make(); - auto finalize_construct = [&]() -> std::shared_ptr + auto finalize_construct = [&]() -> shared_ptr { if ((error = result->on_id_create())) { @@ -413,7 +417,7 @@ public: } template - static void on_id_destroy(T& obj, u64 ipc_key, u64 pshared = -1) + static void on_id_destroy(T& obj, u64 ipc_key, u64 pshared = umax) { if (pshared == umax) { @@ -428,16 +432,16 @@ public: } template - static std::shared_ptr load(u64 ipc_key, std::shared_ptr make, u64 pshared = -1) + static shared_ptr load(u64 ipc_key, shared_ptr make, u64 pshared = umax) { if (pshared == umax ? ipc_key != 0 : pshared != 0) { g_fxo->need>(); - make = g_fxo->get>().add(ipc_key, [&]() + g_fxo->get>().add(ipc_key, [&]() { return make; - }, true).second; + }); } // Ensure no error @@ -445,6 +449,13 @@ public: return make; } + template + static std::function load_func(shared_ptr make, u64 pshared = umax) + { + const u64 key = make->key; + return [ptr = load(key, make, pshared)](void* storage) { *static_cast*>(storage) = ptr; }; + } + static bool wait_timeout(u64 usec, ppu_thread* cpu = {}, bool scale = true, bool is_usleep = false); static inline void notify_all() diff --git a/rpcs3/Emu/Cell/lv2/sys_timer.cpp b/rpcs3/Emu/Cell/lv2/sys_timer.cpp index ec0d3cd7e2..b4b3b780f2 100644 --- a/rpcs3/Emu/Cell/lv2/sys_timer.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_timer.cpp @@ -20,7 +20,7 @@ LOG_CHANNEL(sys_timer); struct lv2_timer_thread { shared_mutex mutex; - std::deque> timers; + std::deque> timers; lv2_timer_thread(); void operator()(); @@ -31,7 +31,7 @@ struct lv2_timer_thread }; lv2_timer::lv2_timer(utils::serial& ar) - : lv2_obj{1} + : lv2_obj(1) , state(ar) , port(lv2_event_queue::load_ptr(ar, port, "timer")) , source(ar) @@ -368,7 +368,7 @@ error_code sys_timer_connect_event_queue(ppu_thread& ppu, u32 timer_id, u32 queu const auto timer = idm::check(timer_id, [&](lv2_timer& timer) -> CellError { - const auto found = idm::find_unlocked(queue_id); + auto found = idm::get_unlocked(queue_id); if (!found) { @@ -383,7 +383,7 @@ error_code sys_timer_connect_event_queue(ppu_thread& ppu, u32 timer_id, u32 queu } // Connect event queue - timer.port = std::static_pointer_cast(found->second); + timer.port = found; timer.source = name ? name : (u64{process_getpid() + 0u} << 32) | u64{timer_id}; timer.data1 = data1; timer.data2 = data2; diff --git a/rpcs3/Emu/Cell/lv2/sys_timer.h b/rpcs3/Emu/Cell/lv2/sys_timer.h index b88bc5c390..14e1f31f8d 100644 --- a/rpcs3/Emu/Cell/lv2/sys_timer.h +++ b/rpcs3/Emu/Cell/lv2/sys_timer.h @@ -28,7 +28,7 @@ struct lv2_timer : lv2_obj shared_mutex mutex; atomic_t state{SYS_TIMER_STATE_STOP}; - std::shared_ptr port; + shared_ptr port; u64 source; u64 data1; u64 data2; @@ -40,7 +40,7 @@ struct lv2_timer : lv2_obj u64 check_unlocked(u64 _now) noexcept; lv2_timer() noexcept - : lv2_obj{1} + : lv2_obj(1) { } diff --git a/rpcs3/Emu/Cell/lv2/sys_vm.cpp b/rpcs3/Emu/Cell/lv2/sys_vm.cpp index 273787e6c2..2591824b1d 100644 --- a/rpcs3/Emu/Cell/lv2/sys_vm.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_vm.cpp @@ -64,7 +64,7 @@ error_code sys_vm_memory_map(ppu_thread& ppu, u64 vsize, u64 psize, u32 cid, u64 return CELL_EINVAL; } - const auto idm_ct = idm::get(cid); + const auto idm_ct = idm::get_unlocked(cid); const auto ct = cid == SYS_MEMORY_CONTAINER_ID_INVALID ? &g_fxo->get() : idm_ct.get(); @@ -260,7 +260,7 @@ error_code sys_vm_lock(ppu_thread& ppu, u32 addr, u32 size) return CELL_EINVAL; } - const auto block = idm::get(sys_vm_t::find_id(addr)); + const auto block = idm::get_unlocked(sys_vm_t::find_id(addr)); if (!block || u64{addr} + size > u64{block->addr} + block->size) { @@ -281,7 +281,7 @@ error_code sys_vm_unlock(ppu_thread& ppu, u32 addr, u32 size) return CELL_EINVAL; } - const auto block = idm::get(sys_vm_t::find_id(addr)); + const auto block = idm::get_unlocked(sys_vm_t::find_id(addr)); if (!block || u64{addr} + size > u64{block->addr} + block->size) { @@ -302,7 +302,7 @@ error_code sys_vm_touch(ppu_thread& ppu, u32 addr, u32 size) return CELL_EINVAL; } - const auto block = idm::get(sys_vm_t::find_id(addr)); + const auto block = idm::get_unlocked(sys_vm_t::find_id(addr)); if (!block || u64{addr} + size > u64{block->addr} + block->size) { @@ -323,7 +323,7 @@ error_code sys_vm_flush(ppu_thread& ppu, u32 addr, u32 size) return CELL_EINVAL; } - const auto block = idm::get(sys_vm_t::find_id(addr)); + const auto block = idm::get_unlocked(sys_vm_t::find_id(addr)); if (!block || u64{addr} + size > u64{block->addr} + block->size) { @@ -344,7 +344,7 @@ error_code sys_vm_invalidate(ppu_thread& ppu, u32 addr, u32 size) return CELL_EINVAL; } - const auto block = idm::get(sys_vm_t::find_id(addr)); + const auto block = idm::get_unlocked(sys_vm_t::find_id(addr)); if (!block || u64{addr} + size > u64{block->addr} + block->size) { @@ -365,7 +365,7 @@ error_code sys_vm_store(ppu_thread& ppu, u32 addr, u32 size) return CELL_EINVAL; } - const auto block = idm::get(sys_vm_t::find_id(addr)); + const auto block = idm::get_unlocked(sys_vm_t::find_id(addr)); if (!block || u64{addr} + size > u64{block->addr} + block->size) { @@ -386,7 +386,7 @@ error_code sys_vm_sync(ppu_thread& ppu, u32 addr, u32 size) return CELL_EINVAL; } - const auto block = idm::get(sys_vm_t::find_id(addr)); + const auto block = idm::get_unlocked(sys_vm_t::find_id(addr)); if (!block || u64{addr} + size > u64{block->addr} + block->size) { @@ -402,7 +402,7 @@ error_code sys_vm_test(ppu_thread& ppu, u32 addr, u32 size, vm::ptr result) sys_vm.warning("sys_vm_test(addr=0x%x, size=0x%x, result=*0x%x)", addr, size, result); - const auto block = idm::get(sys_vm_t::find_id(addr)); + const auto block = idm::get_unlocked(sys_vm_t::find_id(addr)); if (!block || u64{addr} + size > u64{block->addr} + block->size) { @@ -421,7 +421,7 @@ error_code sys_vm_get_statistics(ppu_thread& ppu, u32 addr, vm::ptr(sys_vm_t::find_id(addr)); + const auto block = idm::get_unlocked(sys_vm_t::find_id(addr)); if (!block || block->addr != addr) { diff --git a/rpcs3/Emu/GDB.cpp b/rpcs3/Emu/GDB.cpp index 2b0d197eda..d61f558cb6 100644 --- a/rpcs3/Emu/GDB.cpp +++ b/rpcs3/Emu/GDB.cpp @@ -587,7 +587,7 @@ bool gdb_thread::cmd_thread_info(gdb_cmd&) bool gdb_thread::cmd_current_thread(gdb_cmd&) { - return send_cmd_ack(selected_thread.expired() ? "" : ("QC" + u64_to_padded_hex(selected_thread.lock()->id))); + return send_cmd_ack(selected_thread && selected_thread->state.none_of(cpu_flag::exit) ? "" : ("QC" + u64_to_padded_hex(selected_thread->id))); } bool gdb_thread::cmd_read_register(gdb_cmd& cmd) @@ -596,8 +596,13 @@ bool gdb_thread::cmd_read_register(gdb_cmd& cmd) { return send_cmd_ack("E02"); } - auto th = selected_thread.lock(); - if (auto ppu = th->try_get>()) + + if (!selected_thread || selected_thread->state & cpu_flag::exit) + { + return send_cmd_ack(""); + } + + if (auto ppu = selected_thread->try_get>()) { u32 rid = hex_to_u32(cmd.data); std::string result = get_reg(ppu, rid); @@ -608,7 +613,8 @@ bool gdb_thread::cmd_read_register(gdb_cmd& cmd) } return send_cmd_ack(result); } - GDB.warning("Unimplemented thread type %d.", th->id_type()); + + GDB.warning("Unimplemented thread type %d.", selected_thread->id_type()); return send_cmd_ack(""); } @@ -618,10 +624,14 @@ bool gdb_thread::cmd_write_register(gdb_cmd& cmd) { return send_cmd_ack("E02"); } - auto th = selected_thread.lock(); - if (th->get_class() == thread_class::ppu) + + if (!selected_thread || selected_thread->state & cpu_flag::exit) + { + return send_cmd_ack(""); + } + + if (auto ppu = selected_thread->try_get>()) { - auto ppu = static_cast*>(th.get()); usz eq_pos = cmd.data.find('='); if (eq_pos == umax) { @@ -637,7 +647,7 @@ bool gdb_thread::cmd_write_register(gdb_cmd& cmd) } return send_cmd_ack("OK"); } - GDB.warning("Unimplemented thread type %d.", th->id_type()); + GDB.warning("Unimplemented thread type %d.", selected_thread->id_type()); return send_cmd_ack(""); } @@ -707,10 +717,13 @@ bool gdb_thread::cmd_read_all_registers(gdb_cmd&) std::string result; select_thread(general_ops_thread_id); - auto th = selected_thread.lock(); - if (th->get_class() == thread_class::ppu) + if (!selected_thread || selected_thread->state & cpu_flag::exit) + { + return send_cmd_ack(""); + } + + if (auto ppu = selected_thread->try_get>()) { - auto ppu = static_cast*>(th.get()); //68 64-bit registers, and 3 32-bit result.reserve(68*16 + 3*8); for (int i = 0; i < 71; ++i) @@ -719,17 +732,22 @@ bool gdb_thread::cmd_read_all_registers(gdb_cmd&) } return send_cmd_ack(result); } - GDB.warning("Unimplemented thread type %d.", th->id_type()); + + GDB.warning("Unimplemented thread type %d.", selected_thread ->id_type()); return send_cmd_ack(""); } bool gdb_thread::cmd_write_all_registers(gdb_cmd& cmd) { select_thread(general_ops_thread_id); - auto th = selected_thread.lock(); - if (th->get_class() == thread_class::ppu) + + if (!selected_thread || selected_thread->state & cpu_flag::exit) + { + return send_cmd_ack(""); + } + + if (auto ppu = selected_thread->try_get>()) { - auto ppu = static_cast*>(th.get()); int ptr = 0; for (int i = 0; i < 71; ++i) { @@ -739,7 +757,8 @@ bool gdb_thread::cmd_write_all_registers(gdb_cmd& cmd) } return send_cmd_ack("OK"); } - GDB.warning("Unimplemented thread type %d.", th->id_type()); + + GDB.warning("Unimplemented thread type %d.", selected_thread->id_type()); return send_cmd_ack("E01"); } @@ -789,13 +808,23 @@ bool gdb_thread::cmd_vcont(gdb_cmd& cmd) if (cmd.data[1] == 'c' || cmd.data[1] == 's') { select_thread(continue_ops_thread_id); - auto ppu = std::static_pointer_cast>(selected_thread.lock()); + + auto ppu = !selected_thread || selected_thread->state & cpu_flag::exit ? nullptr : selected_thread->try_get>(); + paused = false; - if (cmd.data[1] == 's') + + if (ppu) { - ppu->state += cpu_flag::dbg_step; + bs_t add_flags{}; + + if (cmd.data[1] == 's') + { + add_flags += cpu_flag::dbg_step; + } + + ppu->add_remove_flags(add_flags, cpu_flag::dbg_pause); } - ppu->state -= cpu_flag::dbg_pause; + //special case if app didn't start yet (only loaded) if (Emu.IsReady()) { @@ -805,19 +834,21 @@ bool gdb_thread::cmd_vcont(gdb_cmd& cmd) { Emu.Resume(); } - else - { - ppu->state.notify_one(); - } + wait_with_interrupts(); //we are in all-stop mode Emu.Pause(); select_thread(pausedBy); // we have to remove dbg_pause from thread that paused execution, otherwise // it will be paused forever (Emu.Resume only removes dbg_global_pause) - ppu = std::static_pointer_cast>(selected_thread.lock()); + + ppu = !selected_thread || selected_thread->state & cpu_flag::exit ? nullptr : selected_thread->try_get>(); + if (ppu) - ppu->state -= cpu_flag::dbg_pause; + { + ppu->add_remove_flags({}, cpu_flag::dbg_pause); + } + return send_reason(); } return send_cmd_ack(""); diff --git a/rpcs3/Emu/GDB.h b/rpcs3/Emu/GDB.h index b77578b3ae..8ba241e110 100644 --- a/rpcs3/Emu/GDB.h +++ b/rpcs3/Emu/GDB.h @@ -16,7 +16,7 @@ class gdb_thread int server_socket = -1; int client_socket = -1; - std::weak_ptr selected_thread{}; + shared_ptr selected_thread{}; u64 continue_ops_thread_id = ANY_THREAD; u64 general_ops_thread_id = ANY_THREAD; diff --git a/rpcs3/Emu/IPC.h b/rpcs3/Emu/IPC.h index 9df802c7bb..26819a3fbd 100644 --- a/rpcs3/Emu/IPC.h +++ b/rpcs3/Emu/IPC.h @@ -5,11 +5,13 @@ #include "Utilities/mutex.h" +#include "util/shared_ptr.hpp" + // IPC manager for objects of type T and IPC keys of type K. template class ipc_manager final { - std::unordered_map> m_map; + std::unordered_map> m_map; mutable shared_mutex m_mutex; @@ -17,12 +19,12 @@ public: // Add new object if specified ipc_key is not used // .first: added new object?, .second: what's at m_map[key] after this function if (peek_ptr || added new object) is true template - std::pair> add(const K& ipc_key, F&& provider, bool peek_ptr = true) + std::pair> add(const K& ipc_key, F&& provider, bool peek_ptr = true) { std::lock_guard lock(m_mutex); // Get object location - std::shared_ptr& ptr = m_map[ipc_key]; + shared_ptr& ptr = m_map[ipc_key]; const bool existed = ptr.operator bool(); if (!existed) @@ -32,7 +34,7 @@ public: } const bool added = !existed && ptr; - return {added, (peek_ptr || added) ? ptr : nullptr}; + return {added, (peek_ptr || added) ? ptr : null_ptr}; } // Unregister specified ipc_key, may return true even if the object doesn't exist anymore @@ -44,7 +46,7 @@ public: } // Get object with specified ipc_key - std::shared_ptr get(const K& ipc_key) const + shared_ptr get(const K& ipc_key) const { reader_lock lock(m_mutex); @@ -55,7 +57,7 @@ public: return found->second; } - return nullptr; + return {}; } // Check whether the object actually exists diff --git a/rpcs3/Emu/IdManager.cpp b/rpcs3/Emu/IdManager.cpp index 71dea33da4..3621c50c66 100644 --- a/rpcs3/Emu/IdManager.cpp +++ b/rpcs3/Emu/IdManager.cpp @@ -33,7 +33,7 @@ std::vector>& id_manager::get_typeinfo_map return s_map; } -idm::map_data* idm::allocate_id(std::vector& vec, u32 type_id, u32 dst_id, u32 base, u32 step, u32 count, bool uses_lowest_id, std::pair invl_range) +id_manager::id_key* idm::allocate_id(std::span keys, usz& highest_index, u32 type_id, u32 dst_id, u32 base, u32 step, u32 count, bool uses_lowest_id, std::pair invl_range) { if (dst_id != (base ? 0 : u32{umax})) { @@ -41,44 +41,43 @@ idm::map_data* idm::allocate_id(std::vector& vec, u32 type_id, u32 dst const u32 index = id_manager::get_index(dst_id, base, step, count, invl_range); ensure(index < count); - vec.resize(std::max(vec.size(), index + 1)); + highest_index = std::max(highest_index, index + 1); - if (vec[index].second) + if (keys[index].type() != umax) { return nullptr; } id_manager::g_id = dst_id; - vec[index] = {id_manager::id_key(dst_id, type_id), nullptr}; - return &vec[index]; + keys[index] = id_manager::id_key(dst_id, type_id); + return &keys[index]; } if (uses_lowest_id) { // Disable the optimization below (hurts accuracy for known cases) - vec.resize(count); + highest_index = count; } - else if (vec.size() < count) + else if (highest_index < count) { // Try to emplace back - const u32 _next = base + step * ::size32(vec); + const u32 _next = base + step * highest_index; id_manager::g_id = _next; - vec.emplace_back(id_manager::id_key(_next, type_id), nullptr); - return &vec.back(); + return &(keys[highest_index++] = (id_manager::id_key(_next, type_id))); } // Check all IDs starting from "next id" (TODO) for (u32 i = 0, next = base; i < count; i++, next += step) { - const auto ptr = &vec[i]; + const auto ptr = &keys[i]; // Look for free ID - if (!ptr->second) + if (ptr->type() == umax) { // Incremenet ID invalidation counter - const u32 id = next | ((ptr->first + (1u << invl_range.first)) & (invl_range.second ? (((1u << invl_range.second) - 1) << invl_range.first) : 0)); + const u32 id = next | ((ptr->value() + (1u << invl_range.first)) & (invl_range.second ? (((1u << invl_range.second) - 1) << invl_range.first) : 0)); id_manager::g_id = id; - ptr->first = id_manager::id_key(id, type_id); + *ptr = id_manager::id_key(id, type_id); return ptr; } } diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index 2b5b05fc5b..ffde4f6ce7 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -7,8 +7,10 @@ #include #include #include +#include #include "util/serialization.hpp" +#include "util/shared_ptr.hpp" #include "util/fixed_typemap.hpp" extern stx::manual_typemap g_fixed_typemap; @@ -19,9 +21,24 @@ enum class thread_state : u32; extern u16 serial_breathe_and_tag(utils::serial& ar, std::string_view name, bool tag_bit); +template +concept IdmCompatible = requires () { u32{T::id_base}, u32{T::id_step}, u32{T::id_count}; }; + +template +concept IdmBaseCompatible = (std::is_final_v ? IdmCompatible : !!(requires () { u32{T::id_step}, u32{T::id_count}; })); + +template +concept IdmSavable = IdmBaseCompatible && T::savestate_init_pos != 0 && (requires () { std::declval().save(std::declval>()); }); + +// If id_base is declared in base type, than storage type must declare id_type +template +concept IdmTypesCompatible = PtrSame && IdmCompatible && IdmBaseCompatible && (std::is_same_v || !IdmCompatible || !!(requires () { u32{Type::id_type}; })); + // Helper namespace namespace id_manager { + using pointer_keeper = std::function; + // Common global mutex extern shared_mutex g_mutex; @@ -31,7 +48,7 @@ namespace id_manager return {0, 0}; } - template requires requires () { T::id_invl_range; } + template requires requires () { T::id_invl_range.first + T::id_invl_range.second; } constexpr std::pair get_invl_range() { return T::id_invl_range; @@ -49,15 +66,6 @@ namespace id_manager return T::id_lowest; } - template - concept IdmCompatible = requires () { +T::id_base, +T::id_step, +T::id_count; }; - - template - concept IdmBaseCompatible = (std::is_final_v ? IdmCompatible : !!(requires () { +T::id_step, +T::id_count; })); - - template - concept IdmSavable = IdmBaseCompatible && T::savestate_init_pos != 0 && (requires () { std::declval().save(std::declval>()); }); - // Last allocated ID for constructors extern thread_local u32 g_id; @@ -102,23 +110,27 @@ namespace id_manager template struct id_traits_load_func { - static constexpr std::shared_ptr(*load)(utils::serial&) = [](utils::serial& ar) -> std::shared_ptr + static constexpr pointer_keeper(*load)(utils::serial&) = [](utils::serial& ar) -> pointer_keeper { + stx::shared_ptr ptr; + if constexpr (std::is_constructible_v, stx::exact_t>) { - return std::make_shared(stx::launch_retainer{}, stx::exact_t(ar)); + ptr = stx::make_shared(stx::launch_retainer{}, stx::exact_t(ar)); } else { - return std::make_shared(stx::exact_t(ar)); + ptr = stx::make_shared(stx::exact_t(ar)); } + + return [ptr](void* storage) { *static_cast*>(storage) = ptr; }; }; }; template struct id_traits_load_func> { - static constexpr std::shared_ptr(*load)(utils::serial&) = [](utils::serial& ar) -> std::shared_ptr + static constexpr pointer_keeper(*load)(utils::serial&) = [](utils::serial& ar) -> pointer_keeper { return T::load(stx::exact_t(ar)); }; @@ -138,8 +150,8 @@ namespace id_manager struct dummy_construct { - dummy_construct() {} - dummy_construct(utils::serial&){} + dummy_construct() = default; + dummy_construct(utils::serial&) noexcept {} void save(utils::serial&) {} static constexpr u32 id_base = 1, id_step = 1, id_count = 1; @@ -154,7 +166,7 @@ namespace id_manager struct typeinfo { public: - std::shared_ptr(*load)(utils::serial&); + std::function(*load)(utils::serial&); void(*save)(utils::serial&, void*); bool(*savable)(void* ptr); @@ -164,13 +176,6 @@ namespace id_manager bool uses_lowest_id; std::pair invl_range; - // Get type index - template - static inline u32 get_index() - { - return stx::typeindex(); - } - // Unique type ID within the same container: we use id_base if nothing else was specified template static consteval u32 get_type() @@ -205,11 +210,11 @@ namespace id_manager const u128 key = u128{get_type()} << 64 | std::bit_cast(C::savestate_init_pos); - for (const auto& tinfo : get_typeinfo_map()) + for (const auto& [tkey, tinfo] : get_typeinfo_map()) { - if (!(tinfo.first ^ key)) + if (!(tkey ^ key)) { - ensure(!std::memcmp(&info, &tinfo.second, sizeof(info))); + ensure(tinfo == info); return info; } } @@ -230,18 +235,23 @@ namespace id_manager return info; } + + bool operator==(const typeinfo& rhs) const noexcept + { + return base == rhs.base && invl_range == rhs.invl_range && save == rhs.save; + } }; // ID value with additional type stored class id_key { - u32 m_value; // ID value - u32 m_base; // ID base (must be unique for each type in the same container) + u32 m_value = 0; // ID value + u32 m_base = umax; // ID base (must be unique for each type in the same container) public: - id_key() = default; + id_key() noexcept = default; - id_key(u32 value, u32 type) + id_key(u32 value, u32 type) noexcept : m_value(value) , m_base(type) { @@ -257,7 +267,12 @@ namespace id_manager return m_base; } - operator u32() const + void clear() + { + m_base = umax; + } + + operator u32() const noexcept { return m_value; } @@ -268,14 +283,14 @@ namespace id_manager { static_assert(IdmBaseCompatible, "Please specify IDM compatible type."); - std::vector>> vec{}, private_copy{}; + std::array, T::id_count> vec_data{}; + std::array, T::id_count> private_copy{}; + std::array vec_keys{}; + usz highest_index = 0; + shared_mutex mutex{}; // TODO: Use this instead of global mutex - id_map() noexcept - { - // Preallocate memory - vec.reserve(T::id_count); - } + id_map() noexcept = default; // Order it directly before the source type's position static constexpr double savestate_init_pos_original = T::savestate_init_pos; @@ -283,10 +298,6 @@ namespace id_manager id_map(utils::serial& ar) noexcept requires IdmSavable { - vec.resize(T::id_count); - - usz highest = 0; - while (true) { const u16 tag = serial_breathe_and_tag(ar, g_fxo->get_name>(), false); @@ -320,25 +331,25 @@ namespace id_manager g_id = id; const usz object_index = get_index(id, info->base, info->step, info->count, info->invl_range); - auto& obj = ::at32(vec, object_index); - ensure(!obj.second); + auto& obj = ::at32(vec_data, object_index); + ensure(!obj); - highest = std::max(highest, object_index + 1); + highest_index = std::max(highest_index, object_index + 1); - obj.first = id_key(id, static_cast(static_cast(type_init_pos >> 64))); - obj.second = info->load(ar); + vec_keys[object_index] = id_key(id, static_cast(static_cast(type_init_pos >> 64))); + info->load(ar)(&obj); } - - vec.resize(highest); } void save(utils::serial& ar) requires IdmSavable { - for (const auto& p : vec) + for (const auto& p : vec_data) { - if (!p.second) continue; + if (!p) continue; - const u128 type_init_pos = u128{p.first.type()} << 64 | std::bit_cast(T::savestate_init_pos); + auto& key = vec_keys[&p - vec_data.data()]; + + const u128 type_init_pos = u128{key.type()} << 64 | std::bit_cast(T::savestate_init_pos); const typeinfo* info = nullptr; // Search load functions for the one of this type (see make_typeinfo() for explenation about key composition reasoning) @@ -351,13 +362,13 @@ namespace id_manager } // Save each object with needed information - if (info && info->savable(p.second.get())) + if (info && info->savable(p.observe())) { // Create a tag for each object serial_breathe_and_tag(ar, g_fxo->get_name>(), false); - ar(p.first.value(), p.first.type()); - info->save(ar, p.second.get()); + ar(key.value(), key.type()); + info->save(ar, p.observe()); } } @@ -367,22 +378,23 @@ namespace id_manager id_map& operator=(thread_state state) noexcept requires (std::is_assignable_v) { - private_copy.clear(); - - if (!vec.empty() || !private_copy.empty()) + if (highest_index) { reader_lock lock(g_mutex); // Save all entries - private_copy = vec; + for (usz i = 0; i < highest_index; i++) + { + private_copy[i] = vec_data[i].load(); + } } // Signal or join threads - for (const auto& [key, ptr] : private_copy) + for (const auto& ptr : private_copy) { if (ptr) { - *static_cast(ptr.get()) = state; + *ptr = state; } } @@ -422,24 +434,27 @@ class idm // Helper type: pointer + return value propagated template - struct return_pair + struct return_pair; + + template + struct return_pair, RT> { - std::shared_ptr ptr; + stx::shared_ptr ptr; RT ret; - explicit operator bool() const + explicit operator bool() const noexcept { return ptr.operator bool(); } - T& operator*() const + T& operator*() const noexcept { return *ptr; } - T* operator->() const + T* operator->() const noexcept { - return ptr.get(); + return ptr.operator->(); } }; @@ -450,61 +465,67 @@ class idm T* ptr; RT ret; - explicit operator bool() const + explicit operator bool() const noexcept { return ptr != nullptr; } - T& operator*() const + T& operator*() const noexcept { return *ptr; } - T* operator->() const + T* operator->() const noexcept { return ptr; } }; - using map_data = std::pair>; + // Get type ID that is meant to be unique within the same container + template + static consteval u32 get_type() + { + return id_manager::typeinfo::get_type(); + } // Prepare new ID (returns nullptr if out of resources) - static map_data* allocate_id(std::vector& vec, u32 type_id, u32 dst_id, u32 base, u32 step, u32 count, bool uses_lowest_id, std::pair invl_range); + static id_manager::id_key* allocate_id(std::span vec, usz& highest_index, u32 type_id, u32 dst_id, u32 base, u32 step, u32 count, bool uses_lowest_id, std::pair invl_range); // Get object by internal index if exists (additionally check type if types are not equal) template - static map_data* find_index(u32 index, u32 id) + static std::pair*, id_manager::id_key*> find_index(u32 index, u32 id) { - static_assert(PtrSame, "Invalid ID type combination"); + static_assert(IdmTypesCompatible, "Invalid ID type combination"); - auto& vec = g_fxo->get>().vec; + auto& map = g_fxo->get>(); - if (index >= vec.size()) + if (index >= map.highest_index) { - return nullptr; + return {}; } - auto& data = vec[index]; + auto& data = map.vec_data[index]; + auto& key = map.vec_keys[index]; - if (data.second) + if (data) { - if (std::is_same_v || data.first.type() == get_type()) + if (std::is_same_v || key.type() == get_type()) { - if (!id_manager::id_traits::invl_range.second || data.first.value() == id) + if (!id_manager::id_traits::invl_range.second || key.value() == id) { - return &data; + return { &data, &key }; } } } - return nullptr; + return {}; } // Find ID template - static map_data* find_id(u32 id) + static std::pair*, id_manager::id_key*> find_id(u32 id) { - static_assert(PtrSame, "Invalid ID type combination"); + static_assert(IdmTypesCompatible, "Invalid ID type combination"); const u32 index = get_index(id); @@ -513,9 +534,9 @@ class idm // Allocate new ID (or use fixed ID) and assign the object from the provider() template - static map_data* create_id(F&& provider, u32 id = id_manager::id_traits::invalid) + static stx::shared_ptr create_id(F&& provider, u32 id = id_manager::id_traits::invalid) { - static_assert(PtrSame, "Invalid ID type combination"); + static_assert(IdmTypesCompatible, "Invalid ID type combination"); // ID traits using traits = id_manager::id_traits; @@ -528,18 +549,23 @@ class idm auto& map = g_fxo->get>(); - if (auto* place = allocate_id(map.vec, get_type(), id, traits::base, traits::step, traits::count, traits::uses_lowest_id, traits::invl_range)) + if (auto* key_ptr = allocate_id({map.vec_keys.data(), map.vec_keys.size()}, map.highest_index, get_type(), id, traits::base, traits::step, traits::count, traits::uses_lowest_id, traits::invl_range)) { - // Get object, store it - place->second = provider(); + auto& place = map.vec_data[key_ptr - map.vec_keys.data()]; - if (place->second) + // Get object, store it + if (auto object = provider()) { - return place; + place = object; + return object; + } + else + { + key_ptr->clear(); } } - return nullptr; + return {}; } public: @@ -549,7 +575,16 @@ public: static inline void clear() { std::lock_guard lock(id_manager::g_mutex); - g_fxo->get>().vec.clear(); + + for (auto& ptr : g_fxo->get>().vec_data) + { + ptr.reset(); + } + + for (auto& key : g_fxo->get>().vec_keys) + { + key.clear(); + } } // Get last ID (updated in create_id/allocate_id) @@ -558,44 +593,38 @@ public: return id_manager::g_id; } - // Get type ID that is meant to be unique within the same container - template - static consteval u32 get_type() - { - return id_manager::typeinfo::get_type(); - } - - // Add a new ID of specified type with specified constructor arguments (returns object or nullptr) + // Add a new ID of specified type with specified constructor arguments (returns object or null_ptr) template requires (std::is_constructible_v) - static inline std::shared_ptr make_ptr(Args&&... args) + static inline stx::shared_ptr make_ptr(Args&&... args) { - if (auto pair = create_id([&] { return std::make_shared(std::forward(args)...); })) + if (auto pair = create_id([&] { return stx::make_shared(std::forward(args)...); })) { - return {pair->second, static_cast(pair->second.get())}; + return pair; } - return nullptr; + return null_ptr; } // Add a new ID of specified type with specified constructor arguments (returns id) template requires (std::is_constructible_v) static inline u32 make(Args&&... args) { - if (auto pair = create_id([&] { return std::make_shared(std::forward(args)...); })) + if (create_id([&] { return stx::make_shared(std::forward(args)...); })) { - return pair->first; + return last_id(); } return id_manager::id_traits::invalid; } // Add a new ID for an object returned by provider() - template requires (std::is_invocable_v) + template + requires IdmTypesCompatible && std::is_convertible_v, stx::shared_ptr> static inline u32 import(F&& provider, u32 id = id_manager::id_traits::invalid) { - if (auto pair = create_id(std::forward(provider), id)) + if (create_id(std::forward(provider), id)) { - return pair->first; + return last_id(); } return id_manager::id_traits::invalid; @@ -603,41 +632,28 @@ public: // Add a new ID for an existing object provided (returns new id) template - static inline u32 import_existing(std::shared_ptr ptr, u32 id = id_manager::id_traits::invalid) + requires IdmTypesCompatible + static inline u32 import_existing(stx::shared_ptr ptr, u32 id = id_manager::id_traits::invalid) { - return import([&] { return std::move(ptr); }, id); - } - - // Access the ID record without locking (unsafe) - template - static inline map_data* find_unlocked(u32 id) - { - return find_id(id); + return import([&]() -> stx::shared_ptr { return std::move(ptr); }, id); } // Check the ID without locking (can be called from other method) template + requires IdmTypesCompatible static inline Get* check_unlocked(u32 id) { - if (const auto found = find_id(id)) + if (const auto found = find_id(id); found.first) { - return static_cast(found->second.get()); + return static_cast(found.first->observe()); } return nullptr; } - // Check the ID - template - static inline Get* check(u32 id) - { - reader_lock lock(id_manager::g_mutex); - - return check_unlocked(id); - } - // Check the ID, access object under shared lock template > + requires IdmTypesCompatible static inline std::conditional_t, Get*, return_pair> check(u32 id, F&& func) { const u32 index = get_index(id); @@ -649,9 +665,9 @@ public: reader_lock lock(id_manager::g_mutex); - if (const auto found = find_index(index, id)) + if (const auto found = find_index(index, id); found.first) { - const auto ptr = static_cast(found->second.get()); + const auto ptr = static_cast(found.first->observe()); if constexpr (!std::is_void_v) { @@ -669,57 +685,51 @@ public: // Get the object without locking (can be called from other method) template - static inline std::shared_ptr get_unlocked(u32 id) + requires IdmTypesCompatible + static inline stx::shared_ptr get_unlocked(u32 id) { const auto found = find_id(id); - if (found == nullptr) [[unlikely]] + if (!found.first) [[unlikely]] { - return nullptr; + return null_ptr; } - return std::static_pointer_cast(found->second); - } - - // Get the object - template - static inline std::shared_ptr get(u32 id) - { - reader_lock lock(id_manager::g_mutex); - - return get_unlocked(id); + return static_cast>(found.first->load()); } // Get the object, access object under reader lock template > - static inline std::conditional_t, std::shared_ptr, return_pair> get(u32 id, F&& func) + requires IdmTypesCompatible + static inline std::conditional_t, stx::shared_ptr, return_pair, FRT>> get(u32 id, F&& func) { const u32 index = get_index(id); if (index >= id_manager::id_traits::count) { - return {nullptr}; + return {}; } reader_lock lock(id_manager::g_mutex); const auto found = find_index(index, id); - if (found == nullptr) [[unlikely]] + if (!found.first) [[unlikely]] { - return {nullptr}; + return {}; } - const auto ptr = static_cast(found->second.get()); + auto ptr = static_cast>(found.first->load()); + Get* obj_ptr = ptr.get(); if constexpr (std::is_void_v) { - func(*ptr); - return {found->second, ptr}; + func(*obj_ptr); + return ptr; } else { - return {{found->second, ptr}, func(*ptr)}; + return {std::move(ptr), func(*obj_ptr)}; } } @@ -728,9 +738,10 @@ public: // Access all objects of specified type. Returns the number of objects processed. // If function result evaluates to true, stop and return the object and the value. template - static inline auto select(F&& func, Lock = {}) + requires IdmBaseCompatible && (IdmCompatible && ...) && (std::is_invocable_v && ...) + static inline auto select(F&& func, Lock = std::true_type{}) { - static_assert((PtrSame && ...), "Invalid ID type combination"); + static_assert((IdmTypesCompatible && ...), "Invalid ID type combination"); [[maybe_unused]] std::conditional_t lock(id_manager::g_mutex); @@ -740,23 +751,30 @@ public: static_assert(PtrSame, "Invalid function argument type combination"); - std::conditional_t, u32, return_pair> result{}; + std::conditional_t, u32, return_pair, result_type>> result{}; - for (auto& id : g_fxo->get>().vec) + auto& map = g_fxo->get>(); + + for (auto& id : map.vec_data) { - if (auto ptr = static_cast(id.second.get())) + if (auto ptr = static_cast(id.observe())) { - if (sizeof...(Get) == 0 || ((id.first.type() == get_type()) || ...)) + auto& key = map.vec_keys[&id - map.vec_data.data()]; + + if (sizeof...(Get) == 0 || ((key.type() == get_type()) || ...)) { if constexpr (std::is_void_v) { - func(id.first, *ptr); + func(key, *ptr); result++; } - else if ((result.ret = func(id.first, *ptr))) + else { - result.ptr = {id.second, ptr}; - break; + if ((result.ret = func(key, *ptr))) + { + result.ptr = static_cast>(id.load()); + break; + } } } } @@ -767,15 +785,17 @@ public: // Remove the ID template + requires IdmTypesCompatible static inline bool remove(u32 id) { - std::shared_ptr ptr; + stx::shared_ptr ptr; { std::lock_guard lock(id_manager::g_mutex); - if (const auto found = find_id(id)) + if (const auto found = find_id(id); found.first) { - ptr = std::move(found->second); + ptr = found.first->exchange(null_ptr); + found.second->clear(); } else { @@ -787,17 +807,18 @@ public: } // Remove the ID if matches the weak/shared ptr - template - static inline bool remove_verify(u32 id, Ptr sptr) + template + requires IdmTypesCompatible && std::is_convertible_v + static inline bool remove_verify(u32 id, Ptr&& sptr, Lock = std::true_type{}) { - std::shared_ptr ptr; + stx::shared_ptr ptr; { - std::lock_guard lock(id_manager::g_mutex); + [[maybe_unused]] std::conditional_t, const shared_mutex&> lock(id_manager::g_mutex); - if (const auto found = find_id(id); found && - (!found->second.owner_before(sptr) && !sptr.owner_before(found->second))) + if (const auto found = find_id(id); found.first && found.first->is_equal(sptr)) { - ptr = std::move(found->second); + ptr = found.first->exchange(null_ptr); + found.second->clear(); } else { @@ -809,16 +830,18 @@ public: } // Remove the ID and return the object - template - static inline std::shared_ptr withdraw(u32 id) + template + requires IdmTypesCompatible + static inline stx::shared_ptr withdraw(u32 id, int = 0, Lock = std::true_type{}) { - std::shared_ptr ptr; + stx::shared_ptr ptr; { - std::lock_guard lock(id_manager::g_mutex); + [[maybe_unused]] std::conditional_t, const shared_mutex&> lock(id_manager::g_mutex); - if (const auto found = find_id(id)) + if (const auto found = find_id(id); found.first) { - ptr = std::static_pointer_cast(::as_rvalue(std::move(found->second))); + ptr = static_cast>(found.first->exchange(null_ptr)); + found.second->clear(); } } @@ -827,25 +850,27 @@ public: // Remove the ID after accessing the object under writer lock, return the object and propagate return value template > - static inline std::conditional_t, std::shared_ptr, return_pair> withdraw(u32 id, F&& func) + requires IdmTypesCompatible && std::is_invocable_v + static inline std::conditional_t, stx::shared_ptr, return_pair, FRT>> withdraw(u32 id, F&& func) { const u32 index = get_index(id); if (index >= id_manager::id_traits::count) { - return {nullptr}; + return {}; } std::unique_lock lock(id_manager::g_mutex); - if (const auto found = find_index(index, id)) + if (const auto found = find_index(index, id); found.first) { - const auto _ptr = static_cast(found->second.get()); + const auto _ptr = static_cast(found.first->observe()); if constexpr (std::is_void_v) { func(*_ptr); - return std::static_pointer_cast(::as_rvalue(std::move(found->second))); + found.second->clear(); + return static_cast>(found.first->exchange(null_ptr)); } else { @@ -854,13 +879,14 @@ public: if (ret) { // If return value evaluates to true, don't delete the object (error code) - return {{found->second, _ptr}, std::move(ret)}; + return {static_cast>(found.first->load()), std::move(ret)}; } - return {std::static_pointer_cast(::as_rvalue(std::move(found->second))), std::move(ret)}; + found.second->clear(); + return {static_cast>(found.first->exchange(null_ptr)), std::move(ret)}; } } - return {nullptr}; + return {}; } }; diff --git a/rpcs3/Emu/NP/np_contexts.cpp b/rpcs3/Emu/NP/np_contexts.cpp index 8c047b7eb5..cd9a11f28d 100644 --- a/rpcs3/Emu/NP/np_contexts.cpp +++ b/rpcs3/Emu/NP/np_contexts.cpp @@ -9,6 +9,7 @@ LOG_CHANNEL(sceNp2); generic_async_transaction_context::generic_async_transaction_context(const SceNpCommunicationId& communicationId, const SceNpCommunicationPassphrase& passphrase, u64 timeout) : communicationId(communicationId), passphrase(passphrase), timeout(timeout) + , idm_id(idm::last_id()) { } @@ -73,12 +74,12 @@ bool destroy_tus_context(s32 ctx_id) return idm::remove(static_cast(ctx_id)); } -tus_transaction_ctx::tus_transaction_ctx(const std::shared_ptr& tus) +tus_transaction_ctx::tus_transaction_ctx(const shared_ptr& tus) : generic_async_transaction_context(tus->communicationId, tus->passphrase, tus->timeout) { } -s32 create_tus_transaction_context(const std::shared_ptr& tus) +s32 create_tus_transaction_context(const shared_ptr& tus) { s32 tus_id = idm::make(tus); @@ -116,13 +117,13 @@ bool destroy_score_context(s32 ctx_id) return idm::remove(static_cast(ctx_id)); } -score_transaction_ctx::score_transaction_ctx(const std::shared_ptr& score) +score_transaction_ctx::score_transaction_ctx(const shared_ptr& score) : generic_async_transaction_context(score->communicationId, score->passphrase, score->timeout) { pcId = score->pcId; } -s32 create_score_transaction_context(const std::shared_ptr& score) +s32 create_score_transaction_context(const shared_ptr& score) { s32 trans_id = idm::make(score); @@ -158,11 +159,11 @@ bool destroy_match2_context(u16 ctx_id) } bool check_match2_context(u16 ctx_id) { - return (idm::check(ctx_id) != nullptr); + return (idm::check_unlocked(ctx_id) != nullptr); } -std::shared_ptr get_match2_context(u16 ctx_id) +shared_ptr get_match2_context(u16 ctx_id) { - return idm::get(ctx_id); + return idm::get_unlocked(ctx_id); } lookup_title_ctx::lookup_title_ctx(vm::cptr communicationId) @@ -207,9 +208,9 @@ bool destroy_commerce2_context(u32 ctx_id) { return idm::remove(static_cast(ctx_id)); } -std::shared_ptr get_commerce2_context(u16 ctx_id) +shared_ptr get_commerce2_context(u16 ctx_id) { - return idm::get(ctx_id); + return idm::get_unlocked(ctx_id); } signaling_ctx::signaling_ctx(vm::ptr npid, vm::ptr handler, vm::ptr arg) @@ -226,9 +227,9 @@ bool destroy_signaling_context(u32 ctx_id) { return idm::remove(static_cast(ctx_id)); } -std::shared_ptr get_signaling_context(u32 ctx_id) +shared_ptr get_signaling_context(u32 ctx_id) { - return idm::get(ctx_id); + return idm::get_unlocked(ctx_id); } matching_ctx::matching_ctx(vm::ptr npId, vm::ptr handler, vm::ptr arg) @@ -266,9 +267,9 @@ s32 create_matching_context(vm::ptr npId, vm::ptr ctx->ctx_id = ctx_id; return static_cast(ctx_id); } -std::shared_ptr get_matching_context(u32 ctx_id) +shared_ptr get_matching_context(u32 ctx_id) { - return idm::get(ctx_id); + return idm::get_unlocked(ctx_id); } bool destroy_matching_context(u32 ctx_id) { diff --git a/rpcs3/Emu/NP/np_contexts.h b/rpcs3/Emu/NP/np_contexts.h index cb576f6e95..cf11098dd8 100644 --- a/rpcs3/Emu/NP/np_contexts.h +++ b/rpcs3/Emu/NP/np_contexts.h @@ -20,7 +20,7 @@ // Used By Score and Tus struct generic_async_transaction_context { - virtual ~generic_async_transaction_context(); + ~generic_async_transaction_context(); generic_async_transaction_context(const SceNpCommunicationId& communicationId, const SceNpCommunicationPassphrase& passphrase, u64 timeout); @@ -37,6 +37,8 @@ struct generic_async_transaction_context u64 timeout; std::thread thread; + + u32 idm_id; }; struct tdata_invalid @@ -137,8 +139,7 @@ bool destroy_tus_context(s32 ctx_id); struct tus_transaction_ctx : public generic_async_transaction_context { - tus_transaction_ctx(const std::shared_ptr& tus); - virtual ~tus_transaction_ctx() = default; + tus_transaction_ctx(const shared_ptr& tus); static const u32 id_base = 0x8001; static const u32 id_step = 1; @@ -148,7 +149,7 @@ struct tus_transaction_ctx : public generic_async_transaction_context std::variant tdata; }; -s32 create_tus_transaction_context(const std::shared_ptr& tus); +s32 create_tus_transaction_context(const shared_ptr& tus); bool destroy_tus_transaction_context(s32 ctx_id); // Score related @@ -172,8 +173,7 @@ bool destroy_score_context(s32 ctx_id); struct score_transaction_ctx : public generic_async_transaction_context { - score_transaction_ctx(const std::shared_ptr& score); - virtual ~score_transaction_ctx() = default; + score_transaction_ctx(const shared_ptr& score); static const u32 id_base = 0x1001; static const u32 id_step = 1; @@ -183,7 +183,7 @@ struct score_transaction_ctx : public generic_async_transaction_context std::variant tdata; s32 pcId = 0; }; -s32 create_score_transaction_context(const std::shared_ptr& score); +s32 create_score_transaction_context(const shared_ptr& score); bool destroy_score_transaction_context(s32 ctx_id); // Match2 related @@ -214,7 +214,7 @@ struct match2_ctx }; u16 create_match2_context(vm::cptr communicationId, vm::cptr passphrase, s32 option); bool check_match2_context(u16 ctx_id); -std::shared_ptr get_match2_context(u16 ctx_id); +shared_ptr get_match2_context(u16 ctx_id); bool destroy_match2_context(u16 ctx_id); struct lookup_title_ctx @@ -261,7 +261,7 @@ struct commerce2_ctx vm::ptr context_callback_param{}; }; s32 create_commerce2_context(u32 version, vm::cptr npid, vm::ptr handler, vm::ptr arg); -std::shared_ptr get_commerce2_context(u16 ctx_id); +shared_ptr get_commerce2_context(u16 ctx_id); bool destroy_commerce2_context(u32 ctx_id); struct signaling_ctx @@ -282,7 +282,7 @@ struct signaling_ctx vm::ptr ext_arg{}; }; s32 create_signaling_context(vm::ptr npid, vm::ptr handler, vm::ptr arg); -std::shared_ptr get_signaling_context(u32 ctx_id); +shared_ptr get_signaling_context(u32 ctx_id); bool destroy_signaling_context(u32 ctx_id); struct matching_ctx @@ -315,5 +315,5 @@ struct matching_ctx atomic_t get_room_limit_version = false; }; s32 create_matching_context(vm::ptr npid, vm::ptr handler, vm::ptr arg); -std::shared_ptr get_matching_context(u32 ctx_id); +shared_ptr get_matching_context(u32 ctx_id); bool destroy_matching_context(u32 ctx_id); diff --git a/rpcs3/Emu/NP/np_handler.cpp b/rpcs3/Emu/NP/np_handler.cpp index e3eafc7b9d..3bcff2f960 100644 --- a/rpcs3/Emu/NP/np_handler.cpp +++ b/rpcs3/Emu/NP/np_handler.cpp @@ -502,7 +502,7 @@ namespace np np_handler::~np_handler() { - std::unordered_map> moved_trans; + std::unordered_map> moved_trans; { std::lock_guard lock(mutex_async_transactions); moved_trans = std::move(async_transactions); @@ -999,7 +999,7 @@ namespace np return CELL_OK; } - std::optional>> np_handler::get_message(u64 id) + std::optional>> np_handler::get_message(u64 id) { return get_rpcn()->get_message(id); } @@ -1019,7 +1019,7 @@ namespace np } } - std::optional>> np_handler::get_message_selected(SceNpBasicAttachmentDataId id) + std::optional>> np_handler::get_message_selected(SceNpBasicAttachmentDataId id) { switch (id) { @@ -1672,7 +1672,7 @@ namespace np return ctx_id; } - std::shared_ptr np_handler::take_pending_gui_request(u32 req_id) + shared_ptr np_handler::take_pending_gui_request(u32 req_id) { const u32 ctx_id = take_gui_request(req_id); diff --git a/rpcs3/Emu/NP/np_handler.h b/rpcs3/Emu/NP/np_handler.h index 8b6f2f7110..e6524ab98a 100644 --- a/rpcs3/Emu/NP/np_handler.h +++ b/rpcs3/Emu/NP/np_handler.h @@ -150,9 +150,9 @@ namespace np error_code get_basic_event(vm::ptr event, vm::ptr from, vm::ptr data, vm::ptr size); // Messages-related functions - std::optional>> get_message(u64 id); + std::optional>> get_message(u64 id); void set_message_selected(SceNpBasicAttachmentDataId id, u64 msg_id); - std::optional>> get_message_selected(SceNpBasicAttachmentDataId id); + std::optional>> get_message_selected(SceNpBasicAttachmentDataId id); void clear_message_selected(SceNpBasicAttachmentDataId id); void send_message(const message_data& msg_data, const std::set& npids); @@ -206,29 +206,29 @@ namespace np void set_current_gui_ctx_id(u32 id); // Score requests - void transaction_async_handler(std::unique_lock lock, const std::shared_ptr& trans_ctx, u32 req_id, bool async); - void get_board_infos(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, vm::ptr boardInfo, bool async); - void record_score(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreValue score, vm::cptr scoreComment, const u8* data, u32 data_size, vm::ptr tmpRank, bool async); - void record_score_data(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreValue score, u32 totalSize, u32 sendSize, const u8* score_data, bool async); - void get_score_data(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const SceNpId& npId, vm::ptr totalSize, u32 recvSize, vm::ptr score_data, bool async); - void get_score_range(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreRankNumber startSerialRank, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated); - void get_score_npid(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const std::vector>& npid_vec, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated); - void get_score_friend(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, bool include_self, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated); + void transaction_async_handler(std::unique_lock lock, const shared_ptr& trans_ctx, u32 req_id, bool async); + void get_board_infos(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, vm::ptr boardInfo, bool async); + void record_score(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreValue score, vm::cptr scoreComment, const u8* data, u32 data_size, vm::ptr tmpRank, bool async); + void record_score_data(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreValue score, u32 totalSize, u32 sendSize, const u8* score_data, bool async); + void get_score_data(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const SceNpId& npId, vm::ptr totalSize, u32 recvSize, vm::ptr score_data, bool async); + void get_score_range(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreRankNumber startSerialRank, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated); + void get_score_npid(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const std::vector>& npid_vec, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated); + void get_score_friend(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, bool include_self, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated); // TUS requests - void tus_set_multislot_variable(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::cptr variableArray, s32 arrayNum, bool vuser, bool async); - void tus_get_multislot_variable(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::ptr variableArray, s32 arrayNum, bool vuser, bool async); - void tus_get_multiuser_variable(std::shared_ptr& trans_ctx, std::vector targetNpIdArray, SceNpTusSlotId slotId, vm::ptr variableArray, s32 arrayNum, bool vuser, bool async); - void tus_get_friends_variable(std::shared_ptr& trans_ctx, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr variableArray,s32 arrayNum, bool async); - void tus_add_and_get_variable(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, s64 inVariable, vm::ptr outVariable, vm::ptr option, bool vuser, bool async); - void tus_try_and_set_variable(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, s32 opeType, s64 variable, vm::ptr resultVariable, vm::ptr option, bool vuser, bool async); - void tus_delete_multislot_variable(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, s32 arrayNum, bool vuser, bool async); - void tus_set_data(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, u32 totalSize, u32 sendSize, vm::cptr data, vm::cptr info, vm::ptr option, bool vuser, bool async); - void tus_get_data(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, vm::ptr dataStatus, vm::ptr data, u32 recvSize, bool vuser, bool async); - void tus_get_multislot_data_status(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::ptr statusArray, s32 arrayNum, bool vuser, bool async); - void tus_get_multiuser_data_status(std::shared_ptr& trans_ctx, std::vector targetNpIdArray, SceNpTusSlotId slotId, vm::ptr statusArray, s32 arrayNum, bool vuser, bool async); - void tus_get_friends_data_status(std::shared_ptr& trans_ctx, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr statusArray, s32 arrayNum, bool async); - void tus_delete_multislot_data(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, s32 arrayNum, bool vuser, bool async); + void tus_set_multislot_variable(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::cptr variableArray, s32 arrayNum, bool vuser, bool async); + void tus_get_multislot_variable(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::ptr variableArray, s32 arrayNum, bool vuser, bool async); + void tus_get_multiuser_variable(shared_ptr& trans_ctx, std::vector targetNpIdArray, SceNpTusSlotId slotId, vm::ptr variableArray, s32 arrayNum, bool vuser, bool async); + void tus_get_friends_variable(shared_ptr& trans_ctx, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr variableArray,s32 arrayNum, bool async); + void tus_add_and_get_variable(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, s64 inVariable, vm::ptr outVariable, vm::ptr option, bool vuser, bool async); + void tus_try_and_set_variable(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, s32 opeType, s64 variable, vm::ptr resultVariable, vm::ptr option, bool vuser, bool async); + void tus_delete_multislot_variable(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, s32 arrayNum, bool vuser, bool async); + void tus_set_data(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, u32 totalSize, u32 sendSize, vm::cptr data, vm::cptr info, vm::ptr option, bool vuser, bool async); + void tus_get_data(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, vm::ptr dataStatus, vm::ptr data, u32 recvSize, bool vuser, bool async); + void tus_get_multislot_data_status(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::ptr statusArray, s32 arrayNum, bool vuser, bool async); + void tus_get_multiuser_data_status(shared_ptr& trans_ctx, std::vector targetNpIdArray, SceNpTusSlotId slotId, vm::ptr statusArray, s32 arrayNum, bool vuser, bool async); + void tus_get_friends_data_status(shared_ptr& trans_ctx, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr statusArray, s32 arrayNum, bool async); + void tus_delete_multislot_data(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, s32 arrayNum, bool vuser, bool async); // Local functions std::pair> local_get_npid(u64 room_id, u16 member_id); @@ -494,7 +494,7 @@ namespace np // Async transaction threads shared_mutex mutex_async_transactions; - std::unordered_map> async_transactions; // (req_id, transaction_ctx) + std::unordered_map> async_transactions; // (req_id, transaction_ctx) // RPCN shared_mutex mutex_rpcn; @@ -529,7 +529,7 @@ namespace np void add_gui_request(u32 req_id, u32 ctx_id); void remove_gui_request(u32 req_id); u32 take_gui_request(u32 req_id); - std::shared_ptr take_pending_gui_request(u32 req_id); + shared_ptr take_pending_gui_request(u32 req_id); shared_mutex mutex_quickmatching; std::map pending_quickmatching; diff --git a/rpcs3/Emu/NP/np_notifications.cpp b/rpcs3/Emu/NP/np_notifications.cpp index 3634ad6cf9..e6b4b547df 100644 --- a/rpcs3/Emu/NP/np_notifications.cpp +++ b/rpcs3/Emu/NP/np_notifications.cpp @@ -348,7 +348,7 @@ namespace np return generic_gui_notification_handler(data, "UserKickedGUI", SCE_NP_MATCHING_EVENT_ROOM_KICKED); } - void gui_epilog(const std::shared_ptr& ctx); + void gui_epilog(const shared_ptr& ctx); void np_handler::notif_quickmatch_complete_gui(std::vector& data) { diff --git a/rpcs3/Emu/NP/np_requests.cpp b/rpcs3/Emu/NP/np_requests.cpp index fd4ae49532..ff124ad15d 100644 --- a/rpcs3/Emu/NP/np_requests.cpp +++ b/rpcs3/Emu/NP/np_requests.cpp @@ -802,7 +802,7 @@ namespace np return true; } - void np_handler::transaction_async_handler(std::unique_lock lock, const std::shared_ptr& trans_ctx, u32 req_id, bool async) + void np_handler::transaction_async_handler(std::unique_lock lock, const shared_ptr& trans_ctx, u32 req_id, bool async) { auto worker_function = [trans_ctx = trans_ctx, req_id, this](std::unique_lock lock) { @@ -842,7 +842,7 @@ namespace np cpu_thread.check_state(); } - void np_handler::get_board_infos(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, vm::ptr boardInfo, bool async) + void np_handler::get_board_infos(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, vm::ptr boardInfo, bool async) { std::unique_lock lock(trans_ctx->mutex); @@ -877,7 +877,7 @@ namespace np return false; } - auto score_trans = std::dynamic_pointer_cast(::at32(async_transactions, req_id)); + auto score_trans = idm::get_unlocked(::at32(async_transactions, req_id)->idm_id); ensure(score_trans); std::lock_guard lock(score_trans->mutex); @@ -892,7 +892,7 @@ namespace np return true; } - void np_handler::record_score(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreValue score, vm::cptr scoreComment, const u8* data, u32 data_size, vm::ptr tmpRank, bool async) + void np_handler::record_score(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreValue score, vm::cptr scoreComment, const u8* data, u32 data_size, vm::ptr tmpRank, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::SCORE); @@ -920,7 +920,7 @@ namespace np return false; } - auto score_trans = std::dynamic_pointer_cast(::at32(async_transactions, req_id)); + auto score_trans = idm::get_unlocked(::at32(async_transactions, req_id)->idm_id); ensure(score_trans); std::lock_guard lock(score_trans->mutex); @@ -961,7 +961,7 @@ namespace np return true; } - void np_handler::record_score_data(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreValue score, u32 totalSize, u32 sendSize, const u8* score_data, bool async) + void np_handler::record_score_data(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreValue score, u32 totalSize, u32 sendSize, const u8* score_data, bool async) { std::unique_lock lock(trans_ctx->mutex); @@ -1021,7 +1021,7 @@ namespace np return set_result_and_wake(CELL_OK); } - void np_handler::get_score_data(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const SceNpId& npId, vm::ptr totalSize, u32 recvSize, vm::ptr score_data, bool async) + void np_handler::get_score_data(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const SceNpId& npId, vm::ptr totalSize, u32 recvSize, vm::ptr score_data, bool async) { std::unique_lock lock(trans_ctx->mutex); @@ -1062,7 +1062,7 @@ namespace np return false; } - auto score_trans = std::dynamic_pointer_cast(::at32(async_transactions, req_id)); + auto score_trans = idm::get_unlocked(::at32(async_transactions, req_id)->idm_id); ensure(score_trans); std::lock_guard lock(score_trans->mutex); @@ -1098,7 +1098,7 @@ namespace np return score_trans->set_result_and_wake(not_an_error(to_copy)); } - void np_handler::get_score_range(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreRankNumber startSerialRank, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated) + void np_handler::get_score_range(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreRankNumber startSerialRank, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::SCORE); @@ -1152,7 +1152,7 @@ namespace np return false; } - auto score_trans = std::dynamic_pointer_cast(::at32(async_transactions, req_id)); + auto score_trans = idm::get_unlocked(::at32(async_transactions, req_id)->idm_id); ensure(score_trans); std::lock_guard lock(score_trans->mutex); @@ -1280,7 +1280,7 @@ namespace np return handle_GetScoreResponse(req_id, reply_data); } - void np_handler::get_score_friend(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, bool include_self, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated) + void np_handler::get_score_friend(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, bool include_self, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::SCORE); @@ -1309,7 +1309,7 @@ namespace np return handle_GetScoreResponse(req_id, reply_data); } - void np_handler::get_score_npid(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const std::vector>& npid_vec, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated) + void np_handler::get_score_npid(shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const std::vector>& npid_vec, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::SCORE); @@ -1380,7 +1380,7 @@ namespace np return false; } - auto tus_trans = std::dynamic_pointer_cast(::at32(async_transactions, req_id)); + auto tus_trans = idm::get_unlocked(::at32(async_transactions, req_id)->idm_id); ensure(tus_trans); std::lock_guard lock(tus_trans->mutex); @@ -1448,7 +1448,7 @@ namespace np return false; } - auto tus_trans = std::dynamic_pointer_cast(::at32(async_transactions, req_id)); + auto tus_trans = idm::get_unlocked(::at32(async_transactions, req_id)->idm_id); ensure(tus_trans); std::lock_guard lock(tus_trans->mutex); @@ -1506,7 +1506,7 @@ namespace np return false; } - auto tus_trans = std::dynamic_pointer_cast(::at32(async_transactions, req_id)); + auto tus_trans = idm::get_unlocked(::at32(async_transactions, req_id)->idm_id); ensure(tus_trans); std::lock_guard lock(tus_trans->mutex); @@ -1568,7 +1568,7 @@ namespace np return true; } - void np_handler::tus_set_multislot_variable(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::cptr variableArray, s32 arrayNum, bool vuser, bool async) + void np_handler::tus_set_multislot_variable(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::cptr variableArray, s32 arrayNum, bool vuser, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); @@ -1582,7 +1582,7 @@ namespace np return handle_tus_no_data(req_id, reply_data); } - void np_handler::tus_get_multislot_variable(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::ptr variableArray, s32 arrayNum, bool vuser, bool async) + void np_handler::tus_get_multislot_variable(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::ptr variableArray, s32 arrayNum, bool vuser, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); @@ -1601,7 +1601,7 @@ namespace np return handle_TusVarResponse(req_id, reply_data); } - void np_handler::tus_get_multiuser_variable(std::shared_ptr& trans_ctx, std::vector targetNpIdArray, SceNpTusSlotId slotId, vm::ptr variableArray, s32 arrayNum, bool vuser, bool async) + void np_handler::tus_get_multiuser_variable(shared_ptr& trans_ctx, std::vector targetNpIdArray, SceNpTusSlotId slotId, vm::ptr variableArray, s32 arrayNum, bool vuser, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); @@ -1620,7 +1620,7 @@ namespace np return handle_TusVarResponse(req_id, reply_data); } - void np_handler::tus_get_friends_variable(std::shared_ptr& trans_ctx, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr variableArray,s32 arrayNum, bool async) + void np_handler::tus_get_friends_variable(shared_ptr& trans_ctx, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr variableArray,s32 arrayNum, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); @@ -1639,7 +1639,7 @@ namespace np return handle_TusVarResponse(req_id, reply_data); } - void np_handler::tus_add_and_get_variable(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, s64 inVariable, vm::ptr outVariable, vm::ptr option, bool vuser, bool async) + void np_handler::tus_add_and_get_variable(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, s64 inVariable, vm::ptr outVariable, vm::ptr option, bool vuser, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); @@ -1657,7 +1657,7 @@ namespace np return handle_TusVariable(req_id, reply_data); } - void np_handler::tus_try_and_set_variable(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, s32 opeType, s64 variable, vm::ptr resultVariable, vm::ptr option, bool vuser, bool async) + void np_handler::tus_try_and_set_variable(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, s32 opeType, s64 variable, vm::ptr resultVariable, vm::ptr option, bool vuser, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); @@ -1675,7 +1675,7 @@ namespace np return handle_TusVariable(req_id, reply_data); } - void np_handler::tus_delete_multislot_variable(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, s32 arrayNum, bool vuser, bool async) + void np_handler::tus_delete_multislot_variable(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, s32 arrayNum, bool vuser, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); @@ -1689,7 +1689,7 @@ namespace np return handle_tus_no_data(req_id, reply_data); } - void np_handler::tus_set_data(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, u32 totalSize, u32 sendSize, vm::cptr data, vm::cptr info, vm::ptr option, bool vuser, bool async) + void np_handler::tus_set_data(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, u32 totalSize, u32 sendSize, vm::cptr data, vm::cptr info, vm::ptr option, bool vuser, bool async) { std::unique_lock lock(trans_ctx->mutex); @@ -1723,7 +1723,7 @@ namespace np return handle_tus_no_data(req_id, reply_data); } - void np_handler::tus_get_data(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, vm::ptr dataStatus, vm::ptr data, u32 recvSize, bool vuser, bool async) + void np_handler::tus_get_data(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, SceNpTusSlotId slotId, vm::ptr dataStatus, vm::ptr data, u32 recvSize, bool vuser, bool async) { std::unique_lock lock(trans_ctx->mutex); @@ -1762,7 +1762,7 @@ namespace np return false; } - auto tus_trans = std::dynamic_pointer_cast(::at32(async_transactions, req_id)); + auto tus_trans = idm::get_unlocked(::at32(async_transactions, req_id)->idm_id); ensure(tus_trans); std::lock_guard lock(tus_trans->mutex); @@ -1835,7 +1835,7 @@ namespace np return true; } - void np_handler::tus_get_multislot_data_status(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::ptr statusArray, s32 arrayNum, bool vuser, bool async) + void np_handler::tus_get_multislot_data_status(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::ptr statusArray, s32 arrayNum, bool vuser, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); @@ -1854,7 +1854,7 @@ namespace np return handle_TusDataStatusResponse(req_id, reply_data); } - void np_handler::tus_get_multiuser_data_status(std::shared_ptr& trans_ctx, std::vector targetNpIdArray, SceNpTusSlotId slotId, vm::ptr statusArray, s32 arrayNum, bool vuser, bool async) + void np_handler::tus_get_multiuser_data_status(shared_ptr& trans_ctx, std::vector targetNpIdArray, SceNpTusSlotId slotId, vm::ptr statusArray, s32 arrayNum, bool vuser, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); @@ -1873,7 +1873,7 @@ namespace np return handle_TusDataStatusResponse(req_id, reply_data); } - void np_handler::tus_get_friends_data_status(std::shared_ptr& trans_ctx, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr statusArray, s32 arrayNum, bool async) + void np_handler::tus_get_friends_data_status(shared_ptr& trans_ctx, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr statusArray, s32 arrayNum, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); @@ -1892,7 +1892,7 @@ namespace np return handle_TusDataStatusResponse(req_id, reply_data); } - void np_handler::tus_delete_multislot_data(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, s32 arrayNum, bool vuser, bool async) + void np_handler::tus_delete_multislot_data(shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, s32 arrayNum, bool vuser, bool async) { std::unique_lock lock(trans_ctx->mutex); const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS); diff --git a/rpcs3/Emu/NP/np_requests_gui.cpp b/rpcs3/Emu/NP/np_requests_gui.cpp index ed099bc6d6..f46307b384 100644 --- a/rpcs3/Emu/NP/np_requests_gui.cpp +++ b/rpcs3/Emu/NP/np_requests_gui.cpp @@ -14,7 +14,7 @@ LOG_CHANNEL(rpcn_log, "rpcn"); namespace np { - std::pair> gui_prelude(u32 ctx_id, vm::ptr handler, vm::ptr arg) + std::pair> gui_prelude(u32 ctx_id, vm::ptr handler, vm::ptr arg) { auto ctx = get_matching_context(ctx_id); @@ -33,7 +33,7 @@ namespace np return {CELL_OK, ctx}; } - void gui_epilog(const std::shared_ptr& ctx) + void gui_epilog(const shared_ptr& ctx) { ensure(ctx->busy.compare_and_swap_test(1, 0), "Matching context wasn't busy in gui_epilog"); ctx->queue_gui_callback(SCE_NP_MATCHING_GUI_EVENT_COMMON_UNLOAD, 0); @@ -662,7 +662,7 @@ namespace np if (ctx->wakey == 0) { // Verify that the context is still valid - if (!idm::check(ctx->ctx_id)) + if (!idm::check_unlocked(ctx->ctx_id)) return; rpcn_log.notice("QuickMatch timeout"); diff --git a/rpcs3/Emu/NP/rpcn_client.cpp b/rpcs3/Emu/NP/rpcn_client.cpp index 245ef2c96c..dc46881b22 100644 --- a/rpcs3/Emu/NP/rpcn_client.cpp +++ b/rpcs3/Emu/NP/rpcn_client.cpp @@ -2775,7 +2775,7 @@ namespace rpcn { std::lock_guard lock(mutex_messages); const u64 msg_id = message_counter++; - auto id_and_msg = std::make_shared>(std::make_pair(std::move(sender), std::move(mdata))); + auto id_and_msg = stx::make_shared>(std::make_pair(std::move(sender), std::move(mdata))); messages.emplace(msg_id, id_and_msg); new_messages.push_back(msg_id); active_messages.insert(msg_id); @@ -2791,7 +2791,7 @@ namespace rpcn } } - std::optional>> rpcn_client::get_message(u64 id) + std::optional>> rpcn_client::get_message(u64 id) { { std::lock_guard lock(mutex_messages); @@ -2803,9 +2803,9 @@ namespace rpcn } } - std::vector>>> rpcn_client::get_messages_and_register_cb(SceNpBasicMessageMainType type_filter, bool include_bootable, message_cb_func cb_func, void* cb_param) + std::vector>>> rpcn_client::get_messages_and_register_cb(SceNpBasicMessageMainType type_filter, bool include_bootable, message_cb_func cb_func, void* cb_param) { - std::vector>>> vec_messages; + std::vector>>> vec_messages; { std::lock_guard lock(mutex_messages); for (auto id : active_messages) diff --git a/rpcs3/Emu/NP/rpcn_client.h b/rpcs3/Emu/NP/rpcn_client.h index 4f772f04c4..fb8921076a 100644 --- a/rpcs3/Emu/NP/rpcn_client.h +++ b/rpcs3/Emu/NP/rpcn_client.h @@ -331,7 +331,7 @@ namespace rpcn }; using friend_cb_func = void (*)(void* param, NotificationType ntype, const std::string& username, bool status); - using message_cb_func = void (*)(void* param, const std::shared_ptr> new_msg, u64 msg_id); + using message_cb_func = void (*)(void* param, const shared_ptr> new_msg, u64 msg_id); struct friend_online_data { @@ -463,8 +463,8 @@ namespace rpcn std::map get_presence_states(); std::vector get_new_messages(); - std::optional>> get_message(u64 id); - std::vector>>> get_messages_and_register_cb(SceNpBasicMessageMainType type, bool include_bootable, message_cb_func cb_func, void* cb_param); + std::optional>> get_message(u64 id); + std::vector>>> get_messages_and_register_cb(SceNpBasicMessageMainType type, bool include_bootable, message_cb_func cb_func, void* cb_param); void remove_message_cb(message_cb_func cb_func, void* cb_param); void mark_message_used(u64 id); @@ -595,7 +595,7 @@ namespace rpcn }; shared_mutex mutex_messages; std::set message_cbs; - std::unordered_map>> messages; // msg id / (sender / message) + std::unordered_map>> messages; // msg id / (sender / message) std::set active_messages; // msg id of messages that have not been discarded std::vector new_messages; // list of msg_id used to inform np_handler of new messages u64 message_counter = 3; // id counter diff --git a/rpcs3/Emu/RSX/GL/GLCompute.h b/rpcs3/Emu/RSX/GL/GLCompute.h index 23752997af..54458c1f1c 100644 --- a/rpcs3/Emu/RSX/GL/GLCompute.h +++ b/rpcs3/Emu/RSX/GL/GLCompute.h @@ -381,7 +381,7 @@ namespace gl template T* get_compute_task() { - u32 index = id_manager::typeinfo::get_index(); + u32 index = stx::typeindex(); auto &e = g_compute_tasks[index]; if (!e) diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index 1ab07b3161..92f76160a8 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -112,7 +112,7 @@ namespace gl template T* get_overlay_pass() { - u32 index = id_manager::typeinfo::get_index(); + u32 index = stx::typeindex(); auto &e = g_overlay_passes[index]; if (!e) diff --git a/rpcs3/Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.cpp b/rpcs3/Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.cpp index d5a2e58f8a..12ccdc0b27 100644 --- a/rpcs3/Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.cpp @@ -9,7 +9,7 @@ namespace rsx { namespace overlays { - void recvmessage_callback(void* param, std::shared_ptr> new_msg, u64 msg_id) + void recvmessage_callback(void* param, shared_ptr> new_msg, u64 msg_id) { auto* dlg = static_cast(param); dlg->callback_handler(std::move(new_msg), msg_id); @@ -319,7 +319,7 @@ namespace rsx return result; } - void recvmessage_dialog::callback_handler(std::shared_ptr> new_msg, u64 msg_id) + void recvmessage_dialog::callback_handler(shared_ptr> new_msg, u64 msg_id) { ensure(new_msg); diff --git a/rpcs3/Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.h b/rpcs3/Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.h index 8d2ea4500f..0c910e1311 100644 --- a/rpcs3/Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.h +++ b/rpcs3/Emu/RSX/Overlays/Network/overlay_recvmessage_dialog.h @@ -36,7 +36,7 @@ namespace rsx compiled_resource get_compiled() override; error_code Exec(SceNpBasicMessageMainType type, SceNpBasicMessageRecvOptions options, SceNpBasicMessageRecvAction& recv_result, u64& chosen_msg_id) override; - void callback_handler(const std::shared_ptr> new_msg, u64 msg_id) override; + void callback_handler(const shared_ptr> new_msg, u64 msg_id) override; }; } } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_manager.h b/rpcs3/Emu/RSX/Overlays/overlay_manager.h index 18359b7cec..d7a10988c1 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_manager.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_manager.h @@ -52,7 +52,7 @@ namespace rsx std::lock_guard lock(m_list_mutex); entry->uid = m_uid_ctr.fetch_add(1); - entry->type_index = id_manager::typeinfo::get_index(); + entry->type_index = stx::typeindex(); if (remove_existing) { @@ -88,7 +88,7 @@ namespace rsx template void remove() { - const auto type_id = id_manager::typeinfo::get_index(); + const auto type_id = stx::typeindex(); if (m_list_mutex.try_lock()) { remove_type(type_id); @@ -138,7 +138,7 @@ namespace rsx { reader_lock lock(m_list_mutex); - const auto type_id = id_manager::typeinfo::get_index(); + const auto type_id = stx::typeindex(); for (const auto& iface : m_iface_list) { if (iface->type_index == type_id) diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index e92e02c6cd..e861a96e25 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -269,7 +269,7 @@ namespace rsx const backend_configuration& get_backend_config() const { return backend_config; } public: - std::shared_ptr> intr_thread; + shared_ptr> intr_thread; // I hate this flag, but until hle is closer to lle, its needed bool isHLE{ false }; diff --git a/rpcs3/Emu/RSX/VK/VKCompute.h b/rpcs3/Emu/RSX/VK/VKCompute.h index e3cce8100a..faadecfc18 100644 --- a/rpcs3/Emu/RSX/VK/VKCompute.h +++ b/rpcs3/Emu/RSX/VK/VKCompute.h @@ -668,7 +668,7 @@ namespace vk template T* get_compute_task() { - u32 index = id_manager::typeinfo::get_index(); + u32 index = stx::typeindex(); auto &e = g_compute_tasks[index]; if (!e) diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.h b/rpcs3/Emu/RSX/VK/VKOverlays.h index edce672de8..d1288fb80a 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -237,7 +237,7 @@ namespace vk template T* get_overlay_pass() { - u32 index = id_manager::typeinfo::get_index(); + u32 index = stx::typeindex(); auto& e = g_overlay_passes[index]; if (!e) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index a4dbf084a5..e67cb1bd6e 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -78,12 +78,12 @@ atomic_t g_watchdog_hold_ctr{0}; extern bool ppu_load_exec(const ppu_exec_object&, bool virtual_load, const std::string&, utils::serial* = nullptr); extern void spu_load_exec(const spu_exec_object&); extern void spu_load_rel_exec(const spu_rel_object&); -extern void ppu_precompile(std::vector& dir_queue, std::vector* loaded_prx); -extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0); -extern void ppu_finalize(const ppu_module&); +extern void ppu_precompile(std::vector& dir_queue, std::vector*>* loaded_prx); +extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0); +extern void ppu_finalize(const ppu_module&); extern void ppu_unload_prx(const lv2_prx&); -extern std::shared_ptr ppu_load_prx(const ppu_prx_object&, bool virtual_load, const std::string&, s64 = 0, utils::serial* = nullptr); -extern std::pair, CellError> ppu_load_overlay(const ppu_exec_object&, bool virtual_load, const std::string& path, s64 = 0, utils::serial* = nullptr); +extern shared_ptr ppu_load_prx(const ppu_prx_object&, bool virtual_load, const std::string&, s64 = 0, utils::serial* = nullptr); +extern std::pair, CellError> ppu_load_overlay(const ppu_exec_object&, bool virtual_load, const std::string& path, s64 = 0, utils::serial* = nullptr); extern bool ppu_load_rel_exec(const ppu_rel_object&); extern void send_close_home_menu_cmds(); @@ -209,7 +209,7 @@ void Emulator::BlockingCallFromMainThread(std::function&& func, std::sou // This function ensures constant initialization order between different compilers and builds void init_fxo_for_exec(utils::serial* ar, bool full = false) { - g_fxo->init(); + g_fxo->init>(); void init_ppu_functions(utils::serial* ar, bool full); @@ -305,7 +305,7 @@ static void fixup_settings(const psf::registry* _psf) } } -extern void dump_executable(std::span data, const ppu_module* _module, std::string_view title_id) +extern void dump_executable(std::span data, const ppu_module* _module, std::string_view title_id) { std::string_view filename = _module->path; filename = filename.substr(filename.find_last_of('/') + 1); @@ -1666,7 +1666,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch, { m_state = system_state::ready; GetCallbacks().on_ready(); - ensure(g_fxo->init()); + ensure(g_fxo->init>()); vm::init(); m_force_boot = false; @@ -1754,7 +1754,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch, if (obj == elf_error::ok && ppu_load_exec(obj, true, path)) { - ensure(g_fxo->try_get())->path = path; + ensure(g_fxo->try_get>())->path = path; } else { @@ -1765,7 +1765,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch, g_fxo->init("SPRX Loader"sv, [this, dir_queue]() mutable { - if (auto& _main = *ensure(g_fxo->try_get()); !_main.path.empty()) + if (auto& _main = *ensure(g_fxo->try_get>()); !_main.path.empty()) { if (!_main.analyse(0, _main.elf_entry, _main.seg0_code_end, _main.applied_patches, std::vector{}, [](){ return Emu.IsStopped(); })) { @@ -2365,7 +2365,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch, sys_log.error("Booting HG category outside of HDD0!"); } - const auto _main = ensure(g_fxo->init()); + const auto _main = ensure(g_fxo->init>()); if (ppu_load_exec(ppu_exec, false, m_path, DeserialManager())) { @@ -3010,7 +3010,7 @@ void Emulator::GracefulShutdown(bool allow_autoexit, bool async_op, bool savesta } extern bool check_if_vdec_contexts_exist(); -extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool revert_lock = false, std::vector>, u32>>* out_list = nullptr); +extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool revert_lock = false, std::vector>, u32>>* out_list = nullptr); void Emulator::Kill(bool allow_autoexit, bool savestate, savestate_stage* save_stage) { @@ -3032,7 +3032,7 @@ void Emulator::Kill(bool allow_autoexit, bool savestate, savestate_stage* save_s *pause_thread = make_ptr(new named_thread("Savestate Prepare Thread"sv, [pause_thread, allow_autoexit, this]() mutable { - std::vector>, u32>> paused_spus; + std::vector>, u32>> paused_spus; if (!try_lock_spu_threads_in_a_state_compatible_with_savestates(false, &paused_spus)) { @@ -3926,7 +3926,7 @@ s32 error_code::error_report(s32 result, const logs::message* channel, const cha void Emulator::ConfigurePPUCache() const { - auto& _main = g_fxo->get(); + auto& _main = g_fxo->get>(); _main.cache = rpcs3::utils::get_cache_dir(_main.path); diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 97ff1c1d60..d9d1991b3e 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -401,7 +401,7 @@ private: struct savestate_stage { bool prepared = false; - std::vector>, u32>> paused_spus; + std::vector>, u32>> paused_spus; }; public: diff --git a/rpcs3/Emu/VFS.cpp b/rpcs3/Emu/VFS.cpp index 800a7f9ff6..8484c57246 100644 --- a/rpcs3/Emu/VFS.cpp +++ b/rpcs3/Emu/VFS.cpp @@ -949,7 +949,7 @@ bool vfs::host::rename(const std::string& from, const std::string& to, const lv2 // Lock mount point, close file descriptors, retry const auto from0 = std::string_view(from).substr(0, from.find_last_not_of(fs::delim) + 1); - std::vector, std::string>> escaped_real; + std::vector, std::string>> escaped_real; std::unique_lock mp_lock(mp->mutex, std::defer_lock); diff --git a/rpcs3/Emu/cache_utils.cpp b/rpcs3/Emu/cache_utils.cpp index 601998848b..5c191ee7ee 100644 --- a/rpcs3/Emu/cache_utils.cpp +++ b/rpcs3/Emu/cache_utils.cpp @@ -3,6 +3,7 @@ #include "system_utils.hpp" #include "system_config.h" #include "IdManager.h" +#include "Emu/Cell/lv2/sys_sync.h" #include "Emu/Cell/PPUAnalyser.h" #include "Emu/Cell/PPUThread.h" @@ -12,7 +13,7 @@ namespace rpcs3::cache { std::string get_ppu_cache() { - const auto _main = g_fxo->try_get(); + const auto _main = g_fxo->try_get>(); if (!_main || _main->cache.empty()) { diff --git a/rpcs3/Emu/perf_meter.cpp b/rpcs3/Emu/perf_meter.cpp index db9aace584..70cfa6b63e 100644 --- a/rpcs3/Emu/perf_meter.cpp +++ b/rpcs3/Emu/perf_meter.cpp @@ -26,13 +26,13 @@ void perf_stat_base::print(const char* name) const noexcept { if (u64 num_total = m_log[0].load()) { - perf_log.notice(u8"Perf stats for %s: total events: %u (total time %.4fs, avg %.4fµs)", name, num_total, m_log[65].load() / 1000'000'000., m_log[65].load() / 1000. / num_total); + perf_log.notice(u8"Perf stats for %s: total events: %u (total time %.4fs, avg %.4fus)", name, num_total, m_log[65].load() / 1000'000'000., m_log[65].load() / 1000. / num_total); for (u32 i = 0; i < 13; i++) { if (u64 count = m_log[i + 1].load()) { - perf_log.notice(u8"Perf stats for %s: events < %.3fµs: %u", name, std::pow(2., i) / 1000., count); + perf_log.notice(u8"Perf stats for %s: events < %.3fus: %u", name, std::pow(2., i) / 1000., count); } } @@ -84,7 +84,7 @@ SAFE_BUFFERS(void) perf_stat_base::push(u64 data[66], u64 start_time, const char // Print in microseconds if (static_cast(diff * 1000'000.) >= g_cfg.core.perf_report_threshold) { - perf_log.notice(u8"%s: %.3fµs", name, diff * 1000'000.); + perf_log.notice(u8"%s: %.3fus", name, diff * 1000'000.); } data[0] += ns != 0; diff --git a/rpcs3/Emu/savestate_utils.cpp b/rpcs3/Emu/savestate_utils.cpp index 9f1be4016d..487eab5b07 100644 --- a/rpcs3/Emu/savestate_utils.cpp +++ b/rpcs3/Emu/savestate_utils.cpp @@ -42,7 +42,7 @@ static std::array s_serial_versions; return ::s_serial_versions[identifier].current_version;\ } -SERIALIZATION_VER(global_version, 0, 17) // For stuff not listed here +SERIALIZATION_VER(global_version, 0, 18) // For stuff not listed here SERIALIZATION_VER(ppu, 1, 1, 2/*PPU sleep order*/, 3/*PPU FNID and module*/) SERIALIZATION_VER(spu, 2, 1) SERIALIZATION_VER(lv2_sync, 3, 1) diff --git a/rpcs3/rpcs3qt/cheat_manager.cpp b/rpcs3/rpcs3qt/cheat_manager.cpp index 5fa0d60ba6..27e0860232 100644 --- a/rpcs3/rpcs3qt/cheat_manager.cpp +++ b/rpcs3/rpcs3qt/cheat_manager.cpp @@ -15,6 +15,7 @@ #include "Emu/IdManager.h" #include "Emu/Cell/PPUAnalyser.h" #include "Emu/Cell/PPUFunction.h" +#include "Emu/Cell/lv2/sys_sync.h" #include "util/yaml.hpp" #include "util/asm.hpp" @@ -441,7 +442,7 @@ bool cheat_engine::is_addr_safe(const u32 offset) if (Emu.IsStopped()) return false; - const auto ppum = g_fxo->try_get(); + const auto ppum = g_fxo->try_get>(); if (!ppum) { diff --git a/rpcs3/rpcs3qt/debugger_frame.cpp b/rpcs3/rpcs3qt/debugger_frame.cpp index d515751523..bdddada077 100644 --- a/rpcs3/rpcs3qt/debugger_frame.cpp +++ b/rpcs3/rpcs3qt/debugger_frame.cpp @@ -54,14 +54,14 @@ extern bool is_using_interpreter(thread_class t_class) } } -extern std::shared_ptr make_disasm(const cpu_thread* cpu, std::shared_ptr handle) +extern std::shared_ptr make_disasm(const cpu_thread* cpu, shared_ptr handle) { if (!handle) { switch (cpu->get_class()) { - case thread_class::ppu: handle = idm::get>(cpu->id); break; - case thread_class::spu: handle = idm::get>(cpu->id); break; + case thread_class::ppu: handle = idm::get_unlocked>(cpu->id); break; + case thread_class::spu: handle = idm::get_unlocked>(cpu->id); break; default: break; } } @@ -850,7 +850,7 @@ std::function debugger_frame::make_check_cpu(cpu_thread* cpu, boo const auto type = cpu ? cpu->get_class() : thread_class::general; - std::shared_ptr shared; + shared_ptr shared; if (g_fxo->is_init>>() && g_fxo->is_init>>()) { @@ -869,11 +869,11 @@ std::function debugger_frame::make_check_cpu(cpu_thread* cpu, boo { if (type == thread_class::ppu) { - shared = idm::get>(cpu->id); + shared = idm::get_unlocked>(cpu->id); } else if (type == thread_class::spu) { - shared = idm::get>(cpu->id); + shared = idm::get_unlocked>(cpu->id); } } } @@ -1153,7 +1153,7 @@ void debugger_frame::OnSelectUnit() { case 1: { - m_cpu = idm::get>(cpu_id); + m_cpu = idm::get_unlocked>(cpu_id); if (selected == m_cpu.get()) { @@ -1164,7 +1164,7 @@ void debugger_frame::OnSelectUnit() } case 2: { - m_cpu = idm::get>(cpu_id); + m_cpu = idm::get_unlocked>(cpu_id); if (selected == m_cpu.get()) { @@ -1179,7 +1179,7 @@ void debugger_frame::OnSelectUnit() if (get_cpu()) { - m_disasm = make_disasm(m_rsx, nullptr); + m_disasm = make_disasm(m_rsx, null_ptr); } break; diff --git a/rpcs3/rpcs3qt/debugger_frame.h b/rpcs3/rpcs3qt/debugger_frame.h index c09716a1f8..ee685231c5 100644 --- a/rpcs3/rpcs3qt/debugger_frame.h +++ b/rpcs3/rpcs3qt/debugger_frame.h @@ -1,6 +1,7 @@ #pragma once #include "util/types.hpp" +#include "util/shared_ptr.hpp" #include "custom_dock_widget.h" @@ -75,7 +76,7 @@ class debugger_frame : public custom_dock_widget bool m_thread_list_pending_update = false; std::shared_ptr m_disasm; // Only shared to allow base/derived functionality - std::shared_ptr m_cpu; + shared_ptr m_cpu; rsx::thread* m_rsx = nullptr; std::shared_ptr m_spu_disasm_memory; u32 m_spu_disasm_origin_eal = 0; diff --git a/rpcs3/rpcs3qt/kernel_explorer.cpp b/rpcs3/rpcs3qt/kernel_explorer.cpp index a70e12cb97..e30fdff643 100644 --- a/rpcs3/rpcs3qt/kernel_explorer.cpp +++ b/rpcs3/rpcs3qt/kernel_explorer.cpp @@ -317,7 +317,7 @@ void kernel_explorer::update() add_solid_node(find_node(root, additional_nodes::process_info), qstr(fmt::format("Process Info, Sdk Version: 0x%08x, PPC SEG: %#x, SFO Category: %s (Fake: %s)", g_ps3_process_info.sdk_ver, g_ps3_process_info.ppc_seg, Emu.GetCat(), Emu.GetFakeCat()))); - auto display_program_segments = [this](QTreeWidgetItem* tree, const ppu_module& m) + auto display_program_segments = [this](QTreeWidgetItem* tree, const ppu_module& m) { for (usz i = 0; i < m.segs.size(); i++) { @@ -528,7 +528,7 @@ void kernel_explorer::update() auto& timer = static_cast(obj); u32 timer_state{SYS_TIMER_STATE_STOP}; - std::shared_ptr port; + shared_ptr port; u64 source = 0; u64 data1 = 0; u64 data2 = 0; diff --git a/rpcs3/rpcs3qt/memory_viewer_panel.cpp b/rpcs3/rpcs3qt/memory_viewer_panel.cpp index c6c466155c..f9f246fbda 100644 --- a/rpcs3/rpcs3qt/memory_viewer_panel.cpp +++ b/rpcs3/rpcs3qt/memory_viewer_panel.cpp @@ -660,11 +660,11 @@ std::string memory_viewer_panel::getHeaderAtAddr(u32 addr) const if (spu_boundary <= addr + m_colcount * 4 - 1) { - std::shared_ptr> spu; + shared_ptr> spu; if (const u32 raw_spu_index = (spu_boundary - RAW_SPU_BASE_ADDR) / SPU_LS_SIZE; raw_spu_index < 5) { - spu = idm::get>(spu_thread::find_raw_spu(raw_spu_index)); + spu = idm::get_unlocked>(spu_thread::find_raw_spu(raw_spu_index)); if (spu && spu->get_type() == spu_type::threaded) { @@ -673,7 +673,7 @@ std::string memory_viewer_panel::getHeaderAtAddr(u32 addr) const } else if (const u32 spu_index = (spu_boundary - SPU_FAKE_BASE_ADDR) / SPU_LS_SIZE; spu_index < spu_thread::id_count) { - spu = idm::get>(spu_thread::id_base | spu_index); + spu = idm::get_unlocked>(spu_thread::id_base | spu_index); if (spu && spu->get_type() != spu_type::threaded) { diff --git a/rpcs3/rpcs3qt/recvmessage_dialog_frame.cpp b/rpcs3/rpcs3qt/recvmessage_dialog_frame.cpp index 6b549d3e23..b617d74d95 100644 --- a/rpcs3/rpcs3qt/recvmessage_dialog_frame.cpp +++ b/rpcs3/rpcs3qt/recvmessage_dialog_frame.cpp @@ -12,7 +12,7 @@ LOG_CHANNEL(recvmessage_dlg_log, "recvmessage dlg"); -void recvmessage_callback(void* param, std::shared_ptr> new_msg, u64 msg_id) +void recvmessage_callback(void* param, shared_ptr> new_msg, u64 msg_id) { auto* dlg = static_cast(param); dlg->callback_handler(std::move(new_msg), msg_id); @@ -132,7 +132,7 @@ error_code recvmessage_dialog_frame::Exec(SceNpBasicMessageMainType type, SceNpB return result; } -void recvmessage_dialog_frame::add_message(const std::shared_ptr>& msg, u64 msg_id) +void recvmessage_dialog_frame::add_message(const shared_ptr>& msg, u64 msg_id) { ensure(msg); auto new_item = new QListWidgetItem(QString::fromStdString(msg->first)); @@ -145,7 +145,7 @@ void recvmessage_dialog_frame::slot_new_message(recvmessage_signal_struct msg_an add_message(msg_and_id.msg, msg_and_id.msg_id); } -void recvmessage_dialog_frame::callback_handler(std::shared_ptr> new_msg, u64 msg_id) +void recvmessage_dialog_frame::callback_handler(shared_ptr> new_msg, u64 msg_id) { recvmessage_signal_struct signal_struct = { .msg = new_msg, diff --git a/rpcs3/rpcs3qt/recvmessage_dialog_frame.h b/rpcs3/rpcs3qt/recvmessage_dialog_frame.h index f17f3afd73..28255253dd 100644 --- a/rpcs3/rpcs3qt/recvmessage_dialog_frame.h +++ b/rpcs3/rpcs3qt/recvmessage_dialog_frame.h @@ -9,7 +9,7 @@ struct recvmessage_signal_struct { - std::shared_ptr> msg; + shared_ptr> msg; u64 msg_id; }; @@ -23,10 +23,10 @@ public: recvmessage_dialog_frame() = default; ~recvmessage_dialog_frame(); error_code Exec(SceNpBasicMessageMainType type, SceNpBasicMessageRecvOptions options, SceNpBasicMessageRecvAction& recv_result, u64& chosen_msg_id) override; - void callback_handler(const std::shared_ptr> new_msg, u64 msg_id) override; + void callback_handler(const shared_ptr> new_msg, u64 msg_id) override; private: - void add_message(const std::shared_ptr>& msg, u64 msg_id); + void add_message(const shared_ptr>& msg, u64 msg_id); Q_SIGNALS: void signal_new_message(const recvmessage_signal_struct msg_and_id); diff --git a/rpcs3/util/logs.cpp b/rpcs3/util/logs.cpp index 764dbc7efc..79ae9e8f4c 100644 --- a/rpcs3/util/logs.cpp +++ b/rpcs3/util/logs.cpp @@ -789,7 +789,7 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st case level::trace: text = reinterpret_cast(u8"·T "); break; } - // Print µs timestamp + // Print microsecond timestamp const u64 hours = stamp / 3600'000'000; const u64 mins = (stamp % 3600'000'000) / 60'000'000; const u64 secs = (stamp % 60'000'000) / 1'000'000; diff --git a/rpcs3/util/shared_ptr.hpp b/rpcs3/util/shared_ptr.hpp index 70bac278e3..6e07db68fd 100644 --- a/rpcs3/util/shared_ptr.hpp +++ b/rpcs3/util/shared_ptr.hpp @@ -2,13 +2,14 @@ #include #include +#include #include "atomic.hpp" #include "bless.hpp" namespace stx { template - constexpr bool same_ptr_implicit_v = std::is_convertible_v ? is_same_ptr() : false; + constexpr bool same_ptr_implicit_v = std::is_convertible_v ? PtrSame : false; template class single_ptr; @@ -126,7 +127,7 @@ namespace stx r.m_ptr = nullptr; } - ~single_ptr() + ~single_ptr() noexcept { reset(); } @@ -168,7 +169,7 @@ namespace stx return m_ptr; } - decltype(auto) operator*() const noexcept requires (!std::is_void_v) + element_type& operator*() const noexcept requires (!std::is_void_v) { return *m_ptr; } @@ -178,16 +179,9 @@ namespace stx return m_ptr; } - decltype(auto) operator[](std::ptrdiff_t idx) const noexcept requires (!std::is_void_v) + element_type& operator[](std::ptrdiff_t idx) const noexcept requires (!std::is_void_v && std::is_array_v) { - if constexpr (std::is_array_v) - { - return m_ptr[idx]; - } - else - { - return *m_ptr; - } + return m_ptr[idx]; } template requires (std::is_invocable_v) @@ -196,11 +190,6 @@ namespace stx return std::invoke(*m_ptr, std::forward(args)...); } - operator element_type*() const noexcept - { - return m_ptr; - } - explicit constexpr operator bool() const noexcept { return m_ptr != nullptr; @@ -214,6 +203,12 @@ namespace stx r.m_ptr = static_cast(std::exchange(m_ptr, nullptr)); return r; } + + template requires same_ptr_implicit_v + bool operator==(const single_ptr& r) const noexcept + { + return get() == r.get(); + } }; #ifndef _MSC_VER @@ -222,7 +217,8 @@ namespace stx #endif template - static std::enable_if_t) && (Init || !sizeof...(Args)), single_ptr> make_single(Args&&... args) noexcept + requires(!std::is_unbounded_array_v && (Init || std::is_array_v) && (Init || !sizeof...(Args))) + static single_ptr make_single(Args&&... args) noexcept { static_assert(offsetof(shared_data, m_data) - offsetof(shared_data, m_ctr) == sizeof(shared_counter)); @@ -230,7 +226,7 @@ namespace stx shared_data* ptr = nullptr; - if constexpr (Init && !std::is_array_v) + if constexpr (!std::is_array_v) { ptr = new shared_data(std::forward(args)...); } @@ -258,7 +254,8 @@ namespace stx } template )> - static std::enable_if_t, single_ptr> make_single(usz count) noexcept + requires (std::is_unbounded_array_v && std::is_default_constructible_v>) + static single_ptr make_single(usz count) noexcept { static_assert(sizeof(shared_data) - offsetof(shared_data, m_ctr) == sizeof(shared_counter)); @@ -397,7 +394,7 @@ namespace stx r.m_ptr = nullptr; } - ~shared_ptr() + ~shared_ptr() noexcept { reset(); } @@ -479,7 +476,7 @@ namespace stx return m_ptr; } - decltype(auto) operator*() const noexcept requires (!std::is_void_v) + element_type& operator*() const noexcept requires (!std::is_void_v) { return *m_ptr; } @@ -489,16 +486,9 @@ namespace stx return m_ptr; } - decltype(auto) operator[](std::ptrdiff_t idx) const noexcept requires (!std::is_void_v) + element_type& operator[](std::ptrdiff_t idx) const noexcept requires (!std::is_void_v && std::is_array_v) { - if constexpr (std::is_array_v) - { - return m_ptr[idx]; - } - else - { - return *m_ptr; - } + return m_ptr[idx]; } template requires (std::is_invocable_v) @@ -519,11 +509,6 @@ namespace stx } } - operator element_type*() const noexcept - { - return m_ptr; - } - explicit constexpr operator bool() const noexcept { return m_ptr != nullptr; @@ -551,21 +536,30 @@ namespace stx r.m_ptr = static_cast(std::exchange(m_ptr, nullptr)); return r; } + + template requires same_ptr_implicit_v + bool operator==(const shared_ptr& r) const noexcept + { + return get() == r.get(); + } }; - template - static std::enable_if_t && (!Init || !sizeof...(Args)), shared_ptr> make_shared(Args&&... args) noexcept + template + requires(!std::is_unbounded_array_v && std::is_constructible_v, Args&& ...>) + static shared_ptr make_shared(Args&&... args) noexcept { - return make_single(std::forward(args)...); + return make_single(std::forward(args)...); } template - static std::enable_if_t, shared_ptr> make_shared(usz count) noexcept + requires (std::is_unbounded_array_v && std::is_default_constructible_v>) + static shared_ptr make_shared(usz count) noexcept { return make_single(count); } template + requires (std::is_constructible_v, T&&>) static shared_ptr> make_shared_value(T&& value) { return make_single_value(std::forward(value)); @@ -638,11 +632,15 @@ namespace stx ~atomic_ptr() { const uptr v = m_val.raw(); - const auto o = d(v); - if (v >> c_ref_size && !o->refs.sub_fetch(c_ref_mask + 1 - (v & c_ref_mask))) + if (v >> c_ref_size) { - o->destroy.load()(o); + const auto o = d(v); + + if (!o->refs.sub_fetch(c_ref_mask + 1 - (v & c_ref_mask))) + { + o->destroy.load()(o); + } } } @@ -1035,9 +1033,9 @@ namespace stx } // Simple atomic load is much more effective than load(), but it's a non-owning reference - const volatile void* observe() const noexcept + T* observe() const noexcept { - return reinterpret_cast(m_val >> c_ref_size); + return reinterpret_cast(m_val >> c_ref_size); } explicit constexpr operator bool() const noexcept @@ -1048,13 +1046,13 @@ namespace stx template requires same_ptr_implicit_v bool is_equal(const shared_ptr& r) const noexcept { - return observe() == r.get(); + return static_cast(observe()) == r.get(); } template requires same_ptr_implicit_v bool is_equal(const single_ptr& r) const noexcept { - return observe() == r.get(); + return static_cast(observe()) == r.get(); } void wait(std::nullptr_t, atomic_wait_timeout timeout = atomic_wait_timeout::inf) @@ -1099,11 +1097,6 @@ namespace stx return false; } - constexpr operator std::nullptr_t() const noexcept - { - return nullptr; - } - constexpr std::nullptr_t get() const noexcept { return nullptr; @@ -1112,10 +1105,29 @@ namespace stx } null_ptr; } +template +struct std::hash> +{ + usz operator()(const stx::single_ptr& x) const noexcept + { + return std::hash()(x.get()); + } +}; + +template +struct std::hash> +{ + usz operator()(const stx::shared_ptr& x) const noexcept + { + return std::hash()(x.get()); + } +}; + using stx::null_ptr; using stx::single_ptr; using stx::shared_ptr; using stx::atomic_ptr; using stx::make_single; +using stx::make_shared; using stx::make_single_value; using stx::make_shared_value;