mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 05:51:27 +12:00
thread_t cleanup
This commit is contained in:
parent
be9a599beb
commit
d9403c2ed2
7 changed files with 40 additions and 94 deletions
|
@ -1199,36 +1199,6 @@ std::string thread_ctrl_t::get_name() const
|
||||||
return name();
|
return name();
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_ctrl_t::set_current()
|
|
||||||
{
|
|
||||||
const auto old_value = g_tls_this_thread;
|
|
||||||
|
|
||||||
if (old_value == this)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (old_value)
|
|
||||||
{
|
|
||||||
vm::reservation_free();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (true && assigned.exchange(true))
|
|
||||||
{
|
|
||||||
LOG_ERROR(GENERAL, "Thread '%s' was already assigned to g_tls_this_thread of another thread", get_name());
|
|
||||||
g_tls_this_thread = nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_tls_this_thread = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (old_value)
|
|
||||||
{
|
|
||||||
old_value->assigned = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_t::thread_t(std::function<std::string()> name, std::function<void()> func)
|
thread_t::thread_t(std::function<std::string()> name, std::function<void()> func)
|
||||||
{
|
{
|
||||||
start(std::move(name), func);
|
start(std::move(name), func);
|
||||||
|
@ -1272,12 +1242,12 @@ void thread_t::start(std::function<std::string()> name, std::function<void()> fu
|
||||||
// start thread
|
// start thread
|
||||||
m_thread->m_thread = std::thread([](std::shared_ptr<thread_ctrl_t> ctrl, std::function<void()> func)
|
m_thread->m_thread = std::thread([](std::shared_ptr<thread_ctrl_t> ctrl, std::function<void()> func)
|
||||||
{
|
{
|
||||||
g_thread_count++;
|
g_tls_this_thread = ctrl.get();
|
||||||
|
|
||||||
SetCurrentThreadDebugName(ctrl->get_name().c_str());
|
SetCurrentThreadDebugName(ctrl->get_name().c_str());
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
auto old_se_translator = _set_se_translator(_se_translator);
|
_set_se_translator(_se_translator);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -1294,16 +1264,9 @@ void thread_t::start(std::function<std::string()> name, std::function<void()> fu
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// error handler
|
|
||||||
const auto error = [&](const char* text)
|
|
||||||
{
|
|
||||||
log_message(GENERAL, Emu.IsStopped() ? Log::Severity::Warning : Log::Severity::Error, "Exception: %s", text);
|
|
||||||
Emu.Pause();
|
|
||||||
};
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ctrl->set_current();
|
g_thread_count++;
|
||||||
|
|
||||||
if (Ini.HLELogging.GetValue())
|
if (Ini.HLELogging.GetValue())
|
||||||
{
|
{
|
||||||
|
@ -1311,36 +1274,31 @@ void thread_t::start(std::function<std::string()> name, std::function<void()> fu
|
||||||
}
|
}
|
||||||
|
|
||||||
func();
|
func();
|
||||||
}
|
|
||||||
catch (const char* e) // obsolete
|
if (Ini.HLELogging.GetValue())
|
||||||
{
|
{
|
||||||
LOG_ERROR(GENERAL, "Deprecated exception type (const char*)");
|
LOG_NOTICE(GENERAL, "Thread ended");
|
||||||
error(e);
|
}
|
||||||
}
|
|
||||||
catch (const std::string& e) // obsolete
|
|
||||||
{
|
|
||||||
LOG_ERROR(GENERAL, "Deprecated exception type (std::string)");
|
|
||||||
error(e.c_str());
|
|
||||||
}
|
}
|
||||||
catch (const fmt::exception& e)
|
catch (const fmt::exception& e)
|
||||||
{
|
{
|
||||||
error(e);
|
LOG_ERROR(GENERAL, "Exception: %s", e.message.get());
|
||||||
|
Emu.Pause();
|
||||||
}
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
if (Ini.HLELogging.GetValue())
|
|
||||||
{
|
{
|
||||||
LOG_NOTICE(GENERAL, "Thread ended");
|
LOG_ERROR(GENERAL, "STD Exception: %s", e.what());
|
||||||
|
Emu.Pause();
|
||||||
|
}
|
||||||
|
catch (EmulationStopped)
|
||||||
|
{
|
||||||
|
LOG_NOTICE(GENERAL, "Thread aborted");
|
||||||
}
|
}
|
||||||
|
|
||||||
//ctrl->set_current(false);
|
|
||||||
|
|
||||||
vm::reservation_free();
|
vm::reservation_free();
|
||||||
|
|
||||||
g_thread_count--;
|
g_thread_count--;
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
_set_se_translator(old_se_translator);
|
|
||||||
#endif
|
|
||||||
}, m_thread, std::move(func));
|
}, m_thread, std::move(func));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,6 @@ class thread_ctrl_t final
|
||||||
// name getter
|
// name getter
|
||||||
const std::function<std::string()> name;
|
const std::function<std::string()> name;
|
||||||
|
|
||||||
// true if assigned somewhere in TLS
|
|
||||||
std::atomic<bool> assigned{ false };
|
|
||||||
|
|
||||||
// assign TLS (must be assigned only once)
|
|
||||||
void set_current();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
thread_ctrl_t(std::function<std::string()> name)
|
thread_ctrl_t(std::function<std::string()> name)
|
||||||
: name(std::move(name))
|
: name(std::move(name))
|
||||||
|
|
|
@ -48,7 +48,7 @@ CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function<
|
||||||
m_state |= CPU_STATE_DEAD;
|
m_state |= CPU_STATE_DEAD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (const fmt::exception&)
|
catch (...)
|
||||||
{
|
{
|
||||||
dump_info();
|
dump_info();
|
||||||
throw;
|
throw;
|
||||||
|
|
|
@ -2,11 +2,6 @@
|
||||||
|
|
||||||
#include "Utilities/Thread.h"
|
#include "Utilities/Thread.h"
|
||||||
|
|
||||||
namespace vm
|
|
||||||
{
|
|
||||||
class waiter_lock_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CPUThreadType
|
enum CPUThreadType
|
||||||
{
|
{
|
||||||
CPU_THREAD_PPU,
|
CPU_THREAD_PPU,
|
||||||
|
@ -31,19 +26,25 @@ enum : u64
|
||||||
};
|
};
|
||||||
|
|
||||||
// "HLE return" exception event
|
// "HLE return" exception event
|
||||||
class CPUThreadReturn{};
|
class CPUThreadReturn {};
|
||||||
|
|
||||||
// CPUThread::Stop exception event
|
// CPUThread::Stop exception event
|
||||||
class CPUThreadStop{};
|
class CPUThreadStop {};
|
||||||
|
|
||||||
// CPUThread::Exit exception event
|
// CPUThread::Exit exception event
|
||||||
class CPUThreadExit{};
|
class CPUThreadExit {};
|
||||||
|
|
||||||
class CPUDecoder;
|
class CPUDecoder;
|
||||||
|
|
||||||
class CPUThread : protected thread_t, public std::enable_shared_from_this<CPUThread>
|
class CPUThread : public thread_t, public std::enable_shared_from_this<CPUThread>
|
||||||
{
|
{
|
||||||
|
using thread_t::start;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
using thread_t::detach;
|
||||||
|
using thread_t::join;
|
||||||
|
using thread_t::joinable;
|
||||||
|
|
||||||
atomic_t<u64> m_state; // thread state flags
|
atomic_t<u64> m_state; // thread state flags
|
||||||
|
|
||||||
std::unique_ptr<CPUDecoder> m_dec;
|
std::unique_ptr<CPUDecoder> m_dec;
|
||||||
|
@ -52,15 +53,6 @@ protected:
|
||||||
const CPUThreadType m_type;
|
const CPUThreadType m_type;
|
||||||
const std::string m_name; // changing m_name would be terribly thread-unsafe in current implementation
|
const std::string m_name; // changing m_name would be terribly thread-unsafe in current implementation
|
||||||
|
|
||||||
public:
|
|
||||||
using thread_t::mutex;
|
|
||||||
using thread_t::cv;
|
|
||||||
using thread_t::is_current;
|
|
||||||
using thread_t::get_thread_ctrl;
|
|
||||||
|
|
||||||
friend vm::waiter_lock_t;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
CPUThread(CPUThreadType type, const std::string& name, std::function<std::string()> thread_name);
|
CPUThread(CPUThreadType type, const std::string& name, std::function<std::string()> thread_name);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -248,6 +248,12 @@ namespace vm
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waiter_lock_t::waiter_lock_t(thread_t& thread, u32 addr, u32 size)
|
||||||
|
: m_waiter(_add_waiter(thread, addr, size))
|
||||||
|
, m_lock(thread.mutex, std::adopt_lock) // must be locked in _add_waiter
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void waiter_lock_t::wait()
|
void waiter_lock_t::wait()
|
||||||
{
|
{
|
||||||
// if another thread successfully called pred(), it must be set to null
|
// if another thread successfully called pred(), it must be set to null
|
||||||
|
|
|
@ -62,9 +62,6 @@ namespace vm
|
||||||
bool try_notify();
|
bool try_notify();
|
||||||
};
|
};
|
||||||
|
|
||||||
// for internal use
|
|
||||||
waiter_t* _add_waiter(thread_t& thread, u32 addr, u32 size);
|
|
||||||
|
|
||||||
class waiter_lock_t
|
class waiter_lock_t
|
||||||
{
|
{
|
||||||
waiter_t* m_waiter;
|
waiter_t* m_waiter;
|
||||||
|
@ -73,11 +70,7 @@ namespace vm
|
||||||
public:
|
public:
|
||||||
waiter_lock_t() = delete;
|
waiter_lock_t() = delete;
|
||||||
|
|
||||||
template<typename T> inline waiter_lock_t(T& thread, u32 addr, u32 size)
|
waiter_lock_t(thread_t& thread, u32 addr, u32 size);
|
||||||
: m_waiter(_add_waiter(static_cast<thread_t&>(thread), addr, size))
|
|
||||||
, m_lock(thread.mutex, std::adopt_lock) // must be locked in _add_waiter
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
waiter_t* operator ->() const
|
waiter_t* operator ->() const
|
||||||
{
|
{
|
||||||
|
@ -90,7 +83,7 @@ namespace vm
|
||||||
};
|
};
|
||||||
|
|
||||||
// wait until pred() returns true, addr must be aligned to size which must be a power of 2, pred() may be called by any thread
|
// wait until pred() returns true, addr must be aligned to size which must be a power of 2, pred() may be called by any thread
|
||||||
template<typename T, typename F, typename... Args> auto wait_op(T& thread, u32 addr, u32 size, F pred, Args&&... args) -> decltype(static_cast<void>(pred(args...)))
|
template<typename F, typename... Args> auto wait_op(thread_t& thread, u32 addr, u32 size, F pred, Args&&... args) -> decltype(static_cast<void>(pred(args...)))
|
||||||
{
|
{
|
||||||
// return immediately if condition passed (optimistic case)
|
// return immediately if condition passed (optimistic case)
|
||||||
if (pred(args...)) return;
|
if (pred(args...)) return;
|
||||||
|
|
|
@ -10,6 +10,9 @@ enum Status : u32
|
||||||
Ready,
|
Ready,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Emulation Stopped exception event
|
||||||
|
class EmulationStopped {};
|
||||||
|
|
||||||
class CPUThreadManager;
|
class CPUThreadManager;
|
||||||
class PadManager;
|
class PadManager;
|
||||||
class KeyboardManager;
|
class KeyboardManager;
|
||||||
|
@ -209,7 +212,7 @@ inline bool check_lv2_lock(lv2_lock_t& lv2_lock)
|
||||||
#define LV2_LOCK lv2_lock_t lv2_lock(Emu.GetCoreMutex())
|
#define LV2_LOCK lv2_lock_t lv2_lock(Emu.GetCoreMutex())
|
||||||
#define LV2_DEFER_LOCK lv2_lock_t lv2_lock
|
#define LV2_DEFER_LOCK lv2_lock_t lv2_lock
|
||||||
#define CHECK_LV2_LOCK(x) if (!check_lv2_lock(x)) throw EXCEPTION("lv2_lock is invalid or not locked")
|
#define CHECK_LV2_LOCK(x) if (!check_lv2_lock(x)) throw EXCEPTION("lv2_lock is invalid or not locked")
|
||||||
#define CHECK_EMU_STATUS if (Emu.IsStopped()) throw EXCEPTION("Aborted (emulation stopped)")
|
#define CHECK_EMU_STATUS if (Emu.IsStopped()) throw EmulationStopped{}
|
||||||
|
|
||||||
typedef void(*CallAfterCbType)(std::function<void()> func);
|
typedef void(*CallAfterCbType)(std::function<void()> func);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue