mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 13:31:27 +12:00
Implement thread_ctrl::emergency_exit()
Replace exception throws with this.
This commit is contained in:
parent
814c73407d
commit
07e1766a7c
4 changed files with 62 additions and 16 deletions
|
@ -2,9 +2,11 @@
|
||||||
#include "BEType.h"
|
#include "BEType.h"
|
||||||
#include "StrUtil.h"
|
#include "StrUtil.h"
|
||||||
#include "cfmt.h"
|
#include "cfmt.h"
|
||||||
|
#include "util/logs.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include "Thread.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -203,7 +205,7 @@ namespace fmt
|
||||||
{
|
{
|
||||||
void raw_error(const char* msg)
|
void raw_error(const char* msg)
|
||||||
{
|
{
|
||||||
throw std::runtime_error{msg};
|
thread_ctrl::emergency_exit(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void raw_verify_error(const char* msg, const fmt_type_info* sup, u64 arg)
|
void raw_verify_error(const char* msg, const fmt_type_info* sup, u64 arg)
|
||||||
|
@ -236,7 +238,7 @@ namespace fmt
|
||||||
out += msg;
|
out += msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::runtime_error{out};
|
thread_ctrl::emergency_exit(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void raw_narrow_error(const char* msg, const fmt_type_info* sup, u64 arg)
|
void raw_narrow_error(const char* msg, const fmt_type_info* sup, u64 arg)
|
||||||
|
@ -256,14 +258,14 @@ namespace fmt
|
||||||
out += msg;
|
out += msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::range_error{out};
|
thread_ctrl::emergency_exit(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void raw_throw_exception(const char* fmt, const fmt_type_info* sup, const u64* args)
|
void raw_throw_exception(const char* fmt, const fmt_type_info* sup, const u64* args)
|
||||||
{
|
{
|
||||||
std::string out;
|
std::string out;
|
||||||
raw_append(out, fmt, sup, args);
|
raw_append(out, fmt, sup, args);
|
||||||
throw std::runtime_error{out};
|
thread_ctrl::emergency_exit(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cfmt_src;
|
struct cfmt_src;
|
||||||
|
|
|
@ -2018,6 +2018,31 @@ u64 thread_base::get_cycles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void thread_ctrl::emergency_exit(std::string_view reason)
|
||||||
|
{
|
||||||
|
sig_log.fatal("Thread terminated due to fatal error: %s", reason);
|
||||||
|
|
||||||
|
if (const auto _this = g_tls_this_thread)
|
||||||
|
{
|
||||||
|
if (_this->finalize(0))
|
||||||
|
{
|
||||||
|
delete _this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do some not very useful cleanup
|
||||||
|
thread_base::finalize();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
_endthreadex(0);
|
||||||
|
#else
|
||||||
|
pthread_exit(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assume main thread
|
||||||
|
report_fatal_error(std::string(reason));
|
||||||
|
}
|
||||||
|
|
||||||
void thread_ctrl::detect_cpu_layout()
|
void thread_ctrl::detect_cpu_layout()
|
||||||
{
|
{
|
||||||
if (!g_native_core_layout.compare_and_swap_test(native_core_arrangement::undefined, native_core_arrangement::generic))
|
if (!g_native_core_layout.compare_and_swap_test(native_core_arrangement::undefined, native_core_arrangement::generic))
|
||||||
|
|
|
@ -225,6 +225,9 @@ public:
|
||||||
_wait_for(-1, true);
|
_wait_for(-1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exit.
|
||||||
|
[[noreturn]] static void emergency_exit(std::string_view reason);
|
||||||
|
|
||||||
// Get current thread (may be nullptr)
|
// Get current thread (may be nullptr)
|
||||||
static thread_base* get_current()
|
static thread_base* get_current()
|
||||||
{
|
{
|
||||||
|
|
|
@ -349,6 +349,34 @@ void cpu_thread::operator()()
|
||||||
state += cpu_flag::wait;
|
state += cpu_flag::wait;
|
||||||
g_cpu_suspend_lock.lock_unlock();
|
g_cpu_suspend_lock.lock_unlock();
|
||||||
|
|
||||||
|
static thread_local struct thread_cleanup_t
|
||||||
|
{
|
||||||
|
cpu_thread* _this;
|
||||||
|
u64 slot;
|
||||||
|
|
||||||
|
thread_cleanup_t(cpu_thread* _this, u64 slot)
|
||||||
|
: _this(_this)
|
||||||
|
, slot(slot)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~thread_cleanup_t()
|
||||||
|
{
|
||||||
|
if (auto ptr = vm::g_tls_locked)
|
||||||
|
{
|
||||||
|
ptr->compare_and_swap(_this, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unregister and wait if necessary
|
||||||
|
_this->state += cpu_flag::wait;
|
||||||
|
if (g_cpu_array[slot].exchange(nullptr) != _this)
|
||||||
|
sys_log.fatal("Inconsistency for array slot %u", slot);
|
||||||
|
g_cpu_array_bits[slot / 64] &= ~(1ull << (slot % 64));
|
||||||
|
g_cpu_array_sema--;
|
||||||
|
g_cpu_suspend_lock.lock_unlock();
|
||||||
|
}
|
||||||
|
} cleanup{this, array_slot};
|
||||||
|
|
||||||
// Check thread status
|
// Check thread status
|
||||||
while (!(state & (cpu_flag::exit + cpu_flag::dbg_global_stop)) && thread_ctrl::state() != thread_state::aborting)
|
while (!(state & (cpu_flag::exit + cpu_flag::dbg_global_stop)) && thread_ctrl::state() != thread_state::aborting)
|
||||||
{
|
{
|
||||||
|
@ -373,18 +401,6 @@ void cpu_thread::operator()()
|
||||||
|
|
||||||
thread_ctrl::wait();
|
thread_ctrl::wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto ptr = vm::g_tls_locked)
|
|
||||||
{
|
|
||||||
ptr->compare_and_swap(this, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unregister and wait if necessary
|
|
||||||
state += cpu_flag::wait;
|
|
||||||
verify("g_cpu_array[...] -> null" HERE), g_cpu_array[array_slot].exchange(nullptr) == this;
|
|
||||||
g_cpu_array_bits[array_slot / 64] &= ~(1ull << (array_slot % 64));
|
|
||||||
g_cpu_array_sema--;
|
|
||||||
g_cpu_suspend_lock.lock_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_thread::~cpu_thread()
|
cpu_thread::~cpu_thread()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue