mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Improve thread aborting mechanism (#10490)
Call pseudo-virtual operator=(thread_state) of thread context.
This commit is contained in:
parent
58847fa2ca
commit
0aed00a758
@ -35,8 +35,6 @@ enum class thread_state : u32
|
||||
mask = 3
|
||||
};
|
||||
|
||||
class need_wakeup {};
|
||||
|
||||
template <class Context>
|
||||
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<Context&, thread_state>)
|
||||
{
|
||||
static_cast<Context&>(*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<need_wakeup, Context>)
|
||||
{
|
||||
this->wake_up();
|
||||
}
|
||||
}
|
||||
|
||||
if (s == thread_state::finished)
|
||||
|
@ -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<named_thread<ppu_thread>>(on_stop);
|
||||
idm::select<named_thread<spu_thread>>(on_stop);
|
||||
}
|
||||
|
||||
sys_log.notice("All CPU threads have been signaled.");
|
||||
}
|
||||
|
||||
void cpu_thread::cleanup() noexcept
|
||||
{
|
||||
ensure(!s_cpu_counter);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<u8> data, u64 seq)
|
||||
@ -423,9 +423,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void wake_up()
|
||||
tcp_timeout_monitor& operator=(thread_state)
|
||||
{
|
||||
wakey.notify_one();
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -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<signaling_info>& si, u32 new_addr, u16 new_port)
|
||||
{
|
||||
ensure(si);
|
||||
|
@ -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);
|
||||
|
@ -1534,14 +1534,6 @@ void Emulator::Stop(bool restart)
|
||||
}
|
||||
});
|
||||
|
||||
if (auto rsx = g_fxo->try_get<rsx::thread>())
|
||||
{
|
||||
// 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
|
||||
|
Loading…
Reference in New Issue
Block a user