diff --git a/Utilities/Thread.h b/Utilities/Thread.h index e7a4cf6ee2..29d80ab4b6 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -35,8 +35,6 @@ enum class thread_state : u32 mask = 3 }; -class need_wakeup {}; - template class named_thread; @@ -616,14 +614,14 @@ 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_base_of_v) - { - this->wake_up(); - } } if (s == thread_state::finished) diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 96421925e4..d1d9003b88 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -812,6 +812,8 @@ bool cpu_thread::check_state() noexcept void cpu_thread::notify() { + state.notify_one(); + // Downcast to correct type if (id_type() == 1) { @@ -827,6 +829,13 @@ void cpu_thread::notify() } } +cpu_thread& cpu_thread::operator=(thread_state) +{ + state += cpu_flag::exit; + state.notify_one(cpu_flag::exit); + return *this; +} + std::string cpu_thread::get_name() const { // Downcast to correct type @@ -1099,29 +1108,6 @@ bool cpu_thread::suspend_work::push(cpu_thread* _this) noexcept return true; } -void cpu_thread::stop_all() noexcept -{ - if (g_tls_this_thread) - { - // Report unsupported but unnecessary case - sys_log.fatal("cpu_thread::stop_all() has been called from a CPU thread."); - return; - } - else - { - auto on_stop = [](u32, cpu_thread& cpu) - { - cpu.state += cpu_flag::exit; - cpu.state.notify_one(cpu_flag::exit); - }; - - idm::select>(on_stop); - idm::select>(on_stop); - } - - sys_log.notice("All CPU threads have been signaled."); -} - void cpu_thread::cleanup() noexcept { ensure(!s_cpu_counter); diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index e96d8824bf..26148ba6ef 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -139,6 +139,7 @@ public: u32* get_pc2(); // Last PC before stepping for the debugger (may be null) void notify(); + cpu_thread& operator=(thread_state); public: // Thread stats for external observation @@ -263,9 +264,6 @@ public: } } - // Stop all threads with cpu_flag::exit - static void stop_all() noexcept; - // Cleanup thread counting information static void cleanup() noexcept; diff --git a/rpcs3/Emu/Cell/lv2/sys_net.cpp b/rpcs3/Emu/Cell/lv2/sys_net.cpp index 00fc9af6a1..fc1b813153 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net.cpp @@ -296,7 +296,7 @@ static void network_clear_queue(ppu_thread& ppu) } // Object in charge of retransmiting packets for STREAM_P2P sockets -class tcp_timeout_monitor : public need_wakeup +class tcp_timeout_monitor { public: void add_message(s32 sock_id, const sockaddr_in *dst, std::vector data, u64 seq) @@ -423,9 +423,10 @@ public: } } - void wake_up() + tcp_timeout_monitor& operator=(thread_state) { wakey.notify_one(); + return *this; } public: diff --git a/rpcs3/Emu/NP/signaling_handler.cpp b/rpcs3/Emu/NP/signaling_handler.cpp index da5d8ae88a..fab7a43872 100644 --- a/rpcs3/Emu/NP/signaling_handler.cpp +++ b/rpcs3/Emu/NP/signaling_handler.cpp @@ -377,6 +377,12 @@ void signaling_handler::wake_up() wakey.notify_one(); } +signaling_handler& signaling_handler::operator=(thread_state) +{ + wakey.notify_one(); + return *this; +} + void signaling_handler::update_si_addr(std::shared_ptr& si, u32 new_addr, u16 new_port) { ensure(si); diff --git a/rpcs3/Emu/NP/signaling_handler.h b/rpcs3/Emu/NP/signaling_handler.h index 95515d0d9b..de50611142 100644 --- a/rpcs3/Emu/NP/signaling_handler.h +++ b/rpcs3/Emu/NP/signaling_handler.h @@ -45,11 +45,12 @@ enum SignalingCommand : u32 signal_finished_ack, }; -class signaling_handler : public need_wakeup +class signaling_handler { public: void operator()(); void wake_up(); + signaling_handler& operator=(thread_state); void set_self_sig_info(SceNpId& npid); void set_self_sig2_info(u64 room_id, u16 member_id); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 7397bf5358..895a30f3eb 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -1534,14 +1534,6 @@ void Emulator::Stop(bool restart) } }); - if (auto rsx = g_fxo->try_get()) - { - // TODO: notify? - rsx->state += cpu_flag::exit; - } - - cpu_thread::stop_all(); - // Signal threads for (const auto& [type, data] : *g_fxo) { @@ -1551,6 +1543,11 @@ void Emulator::Stop(bool restart) } } + sys_log.notice("All emulation threads have been signaled."); + + // Wait fot newly created cpu_thread to see that emulation has been stopped + id_manager::g_mutex.lock_unlock(); + GetCallbacks().on_stop(); // Join threads