diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 3130c0fcb2..c378b872f9 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -635,16 +635,16 @@ public: // Join thread by thread_state::finished named_thread& operator=(thread_state s) { - if constexpr (std::is_assignable_v) - { - static_cast(*this) = s; - } - if (s >= thread_state::aborting && thread::m_sync.fetch_op([](u64& v){ return !(v & 3) && (v |= 1); }).second) { thread::m_sync.notify_one(1); } + if constexpr (std::is_assignable_v) + { + static_cast(*this) = s; + } + if (s == thread_state::finished) { // This participates in emulation stopping, use destruction-alike semantics diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index d84b48bc07..e7169c89e4 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -12,6 +12,7 @@ #include "Utilities/StrUtil.h" #include "Utilities/JIT.h" #include "util/init_mutex.hpp" +#include "util/shared_ptr.hpp" #include "SPUThread.h" #include "SPUAnalyser.h" @@ -10647,6 +10648,7 @@ struct spu_llvm { // Workload lf_queue> registered; + atomic_ptr> m_workers; spu_llvm() { @@ -10716,7 +10718,9 @@ struct spu_llvm u32 worker_index = 0; - named_thread_group workers("SPUW.", worker_count); + m_workers = make_single>("SPUW.", worker_count); + auto workers_ptr = m_workers.load(); + auto& workers = *workers_ptr; while (thread_ctrl::state() != thread_state::aborting) { @@ -10769,12 +10773,27 @@ struct spu_llvm static_cast(prof_mutex.init_always([&]{ samples.clear(); })); + m_workers.reset(); + for (u32 i = 0; i < worker_count; i++) { - (workers.begin() + i)->registered.push(0, nullptr); + (workers.begin() + i)->operator=(thread_state::aborting); } } + spu_llvm& operator=(thread_state) + { + if (const auto workers = m_workers.load()) + { + for (u32 i = 0; i < workers->size(); i++) + { + (workers->begin() + i)->operator=(thread_state::aborting); + } + } + + return *this; + } + static constexpr auto thread_name = "SPU LLVM"sv; };