diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index 095892b0de..56c8dfed43 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -1390,13 +1390,13 @@ void lv2_obj::schedule_all() } } -ppu_thread_status lv2_obj::ppu_state(ppu_thread* ppu, bool lock_idm) +ppu_thread_status lv2_obj::ppu_state(ppu_thread* ppu, bool lock_idm, bool lock_lv2) { - std::optional opt_lock; + std::optional opt_lock[2]; if (lock_idm) { - opt_lock.emplace(id_manager::g_mutex); + opt_lock[0].emplace(id_manager::g_mutex); } if (ppu->state & cpu_flag::stop) @@ -1411,7 +1411,10 @@ ppu_thread_status lv2_obj::ppu_state(ppu_thread* ppu, bool lock_idm) default: break; } - reader_lock lock(g_mutex); + if (lock_lv2) + { + opt_lock[1].emplace(lv2_obj::g_mutex); + } const auto it = std::find(g_ppu.begin(), g_ppu.end(), ppu); diff --git a/rpcs3/Emu/Cell/lv2/sys_sync.h b/rpcs3/Emu/Cell/lv2/sys_sync.h index ccf5a91d1c..d0c84834d0 100644 --- a/rpcs3/Emu/Cell/lv2/sys_sync.h +++ b/rpcs3/Emu/Cell/lv2/sys_sync.h @@ -187,7 +187,7 @@ public: g_to_awake.clear(); } - static ppu_thread_status ppu_state(ppu_thread* ppu, bool lock_idm = true); + static ppu_thread_status ppu_state(ppu_thread* ppu, bool lock_idm = true, bool lock_lv2 = true); static inline void append(cpu_thread* const thread) { @@ -406,10 +406,10 @@ public: return true; } -private: // Scheduler mutex static shared_mutex g_mutex; +private: // Pending list of threads to run static thread_local std::vector g_to_awake; diff --git a/rpcs3/rpcs3qt/kernel_explorer.cpp b/rpcs3/rpcs3qt/kernel_explorer.cpp index 92b0e52ef4..b80cf85a0d 100644 --- a/rpcs3/rpcs3qt/kernel_explorer.cpp +++ b/rpcs3/rpcs3qt/kernel_explorer.cpp @@ -556,15 +556,19 @@ void kernel_explorer::update() add_leaf(find_node(root, additional_nodes::memory_containers), qstr(fmt::format("Memory Container 0x%08x: Used: 0x%x/0x%x (%0.2f/%0.2f MB)", id, used, container.size, used * 1. / (1024 * 1024), container.size * 1. / (1024 * 1024)))); }); + std::unique_lock lock_lv2(lv2_obj::g_mutex); + idm::select>([&](u32 id, ppu_thread& ppu) { const auto func = ppu.last_function; - const ppu_thread_status status = lv2_obj::ppu_state(&ppu, false); + const ppu_thread_status status = lv2_obj::ppu_state(&ppu, false, false); add_leaf(find_node(root, additional_nodes::ppu_threads), qstr(fmt::format(u8"PPU 0x%07x: “%s”, PRIO: %d, Joiner: %s, Status: %s, State: %s, %s func: “%s”", id, *ppu.ppu_tname.load(), +ppu.prio, ppu.joiner.load(), status, ppu.state.load() , ppu.current_function ? "In" : "Last", func ? func : ""))); }); + lock_lv2.unlock(); + idm::select>([&](u32 /*id*/, spu_thread& spu) { QTreeWidgetItem* spu_thread_tree = add_solid_node(find_node(root, additional_nodes::spu_threads), qstr(fmt::format(u8"SPU 0x%07x: “%s”, State: %s, Type: %s", spu.lv2_id, *spu.spu_tname.load(), spu.state.load(), spu.get_type())));