From 9524211b9adc7459fa3d770623615bb3503bbff9 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Sun, 21 Sep 2025 17:48:09 +0300 Subject: [PATCH] sys_spu: Untangle IDM mutex from sys_spu's --- rpcs3/Emu/Cell/SPUThread.cpp | 6 +++++ rpcs3/Emu/Cell/SPUThread.h | 2 +- rpcs3/Emu/Cell/lv2/sys_spu.cpp | 44 ++++++++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 7630989a33..cc21e2ebb8 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1899,6 +1899,12 @@ void spu_thread::cpu_task() return fmt::format("%sSPU[0x%07x] Thread (%s) [0x%05x]", type >= spu_type::raw ? type == spu_type::isolated ? "Iso" : "Raw" : "", cpu->lv2_id, *name_cache.get(), cpu->pc); }; + if (get_type() == spu_type::threaded) + { + // Update thread name (spu_thread::lv2_id update) + thread_ctrl::set_name(*group->threads[group->threads_map[index]], thread_name); + } + constexpr u32 invalid_spurs = 0u - 0x80; if (spurs_addr == 0) diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 5c23e1f502..36d24ff55e 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -768,7 +768,7 @@ public: std::shared_ptr shm; // SPU memory const std::add_pointer_t ls; // SPU LS pointer const u32 option; // sys_spu_thread_initialize option - const u32 lv2_id; // The actual id that is used by syscalls + u32 lv2_id; // The actual id that is used by syscalls u32 spurs_addr = 0; bool spurs_waited = false; bool spurs_entered_wait = false; diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index 3c2489c9b2..c3328eb604 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -776,8 +776,6 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr thread, u32 g return CELL_ESRCH; } - std::unique_lock lock(group->mutex); - if (auto state = +group->run_state; state != SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED) { if (state == SPU_THREAD_GROUP_STATUS_DESTROYED) @@ -793,6 +791,34 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr thread, u32 g return CELL_EBUSY; } + const u32 inited_before_lock = group->init; + + u32 tid = (inited_before_lock << 24) | (group_id & 0xffffff); + + const auto spu_ptr = ensure(idm::make_ptr>(group.get(), spu_num, thread_name, tid, false, option)); + + std::unique_lock lock(group->mutex); + + if (auto state = +group->run_state; state != SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED) + { + lock.unlock(); + idm::remove>(idm::last_id()); + + if (state == SPU_THREAD_GROUP_STATUS_DESTROYED) + { + return CELL_ESRCH; + } + + return CELL_EBUSY; + } + + if (group->threads_map[spu_num] != -1) + { + lock.unlock(); + idm::remove>(idm::last_id()); + return CELL_EBUSY; + } + if (option & SYS_SPU_THREAD_OPTION_ASYNC_INTR_ENABLE) { sys_spu.warning("Unimplemented SPU Thread options (0x%x)", option); @@ -800,15 +826,13 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr thread, u32 g const u32 inited = group->init; - const u32 tid = (inited << 24) | (group_id & 0xffffff); + tid = (inited << 24) | (group_id & 0xffffff); - ensure(idm::import>([&]() - { - 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; - })); + // Update lv2_id (potentially changed after locking) + spu_ptr->lv2_id = tid; + + group->threads[inited] = spu_ptr; + group->threads_map[spu_num] = static_cast(inited); // alloc_hidden indicates falloc to allocate page with no access rights in base memory auto& spu = group->threads[inited];