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;