mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42: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
|
mask = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
class need_wakeup {};
|
|
||||||
|
|
||||||
template <class Context>
|
template <class Context>
|
||||||
class named_thread;
|
class named_thread;
|
||||||
|
|
||||||
@ -616,14 +614,14 @@ public:
|
|||||||
// Join thread by thread_state::finished
|
// Join thread by thread_state::finished
|
||||||
named_thread& operator=(thread_state s)
|
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)
|
if (s >= thread_state::aborting && thread::m_sync.fetch_op([](u64& v){ return !(v & 3) && (v |= 1); }).second)
|
||||||
{
|
{
|
||||||
thread::m_sync.notify_one(1);
|
thread::m_sync.notify_one(1);
|
||||||
|
|
||||||
if constexpr (std::is_base_of_v<need_wakeup, Context>)
|
|
||||||
{
|
|
||||||
this->wake_up();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s == thread_state::finished)
|
if (s == thread_state::finished)
|
||||||
|
@ -812,6 +812,8 @@ bool cpu_thread::check_state() noexcept
|
|||||||
|
|
||||||
void cpu_thread::notify()
|
void cpu_thread::notify()
|
||||||
{
|
{
|
||||||
|
state.notify_one();
|
||||||
|
|
||||||
// Downcast to correct type
|
// Downcast to correct type
|
||||||
if (id_type() == 1)
|
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
|
std::string cpu_thread::get_name() const
|
||||||
{
|
{
|
||||||
// Downcast to correct type
|
// Downcast to correct type
|
||||||
@ -1099,29 +1108,6 @@ bool cpu_thread::suspend_work::push(cpu_thread* _this) noexcept
|
|||||||
return true;
|
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
|
void cpu_thread::cleanup() noexcept
|
||||||
{
|
{
|
||||||
ensure(!s_cpu_counter);
|
ensure(!s_cpu_counter);
|
||||||
|
@ -139,6 +139,7 @@ public:
|
|||||||
u32* get_pc2(); // Last PC before stepping for the debugger (may be null)
|
u32* get_pc2(); // Last PC before stepping for the debugger (may be null)
|
||||||
|
|
||||||
void notify();
|
void notify();
|
||||||
|
cpu_thread& operator=(thread_state);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Thread stats for external observation
|
// 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
|
// Cleanup thread counting information
|
||||||
static void cleanup() noexcept;
|
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
|
// Object in charge of retransmiting packets for STREAM_P2P sockets
|
||||||
class tcp_timeout_monitor : public need_wakeup
|
class tcp_timeout_monitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void add_message(s32 sock_id, const sockaddr_in *dst, std::vector<u8> data, u64 seq)
|
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();
|
wakey.notify_one();
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -377,6 +377,12 @@ void signaling_handler::wake_up()
|
|||||||
wakey.notify_one();
|
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)
|
void signaling_handler::update_si_addr(std::shared_ptr<signaling_info>& si, u32 new_addr, u16 new_port)
|
||||||
{
|
{
|
||||||
ensure(si);
|
ensure(si);
|
||||||
|
@ -45,11 +45,12 @@ enum SignalingCommand : u32
|
|||||||
signal_finished_ack,
|
signal_finished_ack,
|
||||||
};
|
};
|
||||||
|
|
||||||
class signaling_handler : public need_wakeup
|
class signaling_handler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void operator()();
|
void operator()();
|
||||||
void wake_up();
|
void wake_up();
|
||||||
|
signaling_handler& operator=(thread_state);
|
||||||
|
|
||||||
void set_self_sig_info(SceNpId& npid);
|
void set_self_sig_info(SceNpId& npid);
|
||||||
void set_self_sig2_info(u64 room_id, u16 member_id);
|
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
|
// Signal threads
|
||||||
for (const auto& [type, data] : *g_fxo)
|
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();
|
GetCallbacks().on_stop();
|
||||||
|
|
||||||
// Join threads
|
// Join threads
|
||||||
|
Loading…
Reference in New Issue
Block a user