thread_t cleanup

This commit is contained in:
Nekotekina 2015-08-11 16:26:08 +03:00
parent be9a599beb
commit d9403c2ed2
7 changed files with 40 additions and 94 deletions

View File

@ -1199,36 +1199,6 @@ std::string thread_ctrl_t::get_name() const
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)
{
start(std::move(name), func);
@ -1272,12 +1242,12 @@ void thread_t::start(std::function<std::string()> name, std::function<void()> fu
// start thread
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());
#if defined(_MSC_VER)
auto old_se_translator = _set_se_translator(_se_translator);
_set_se_translator(_se_translator);
#endif
#ifdef _WIN32
@ -1294,16 +1264,9 @@ void thread_t::start(std::function<std::string()> name, std::function<void()> fu
}
#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
{
ctrl->set_current();
g_thread_count++;
if (Ini.HLELogging.GetValue())
{
@ -1311,36 +1274,31 @@ void thread_t::start(std::function<std::string()> name, std::function<void()> fu
}
func();
}
catch (const char* e) // obsolete
{
LOG_ERROR(GENERAL, "Deprecated exception type (const char*)");
error(e);
}
catch (const std::string& e) // obsolete
{
LOG_ERROR(GENERAL, "Deprecated exception type (std::string)");
error(e.c_str());
if (Ini.HLELogging.GetValue())
{
LOG_NOTICE(GENERAL, "Thread ended");
}
}
catch (const fmt::exception& e)
{
error(e);
LOG_ERROR(GENERAL, "Exception: %s", e.message.get());
Emu.Pause();
}
if (Ini.HLELogging.GetValue())
catch (const std::exception& e)
{
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();
g_thread_count--;
#if defined(_MSC_VER)
_set_se_translator(old_se_translator);
#endif
}, m_thread, std::move(func));
}

View File

@ -13,12 +13,6 @@ class thread_ctrl_t final
// name getter
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:
thread_ctrl_t(std::function<std::string()> name)
: name(std::move(name))

View File

@ -48,7 +48,7 @@ CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function<
m_state |= CPU_STATE_DEAD;
break;
}
catch (const fmt::exception&)
catch (...)
{
dump_info();
throw;

View File

@ -2,11 +2,6 @@
#include "Utilities/Thread.h"
namespace vm
{
class waiter_lock_t;
}
enum CPUThreadType
{
CPU_THREAD_PPU,
@ -31,19 +26,25 @@ enum : u64
};
// "HLE return" exception event
class CPUThreadReturn{};
class CPUThreadReturn {};
// CPUThread::Stop exception event
class CPUThreadStop{};
class CPUThreadStop {};
// CPUThread::Exit exception event
class CPUThreadExit{};
class CPUThreadExit {};
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:
using thread_t::detach;
using thread_t::join;
using thread_t::joinable;
atomic_t<u64> m_state; // thread state flags
std::unique_ptr<CPUDecoder> m_dec;
@ -52,15 +53,6 @@ protected:
const CPUThreadType m_type;
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);
public:

View File

@ -248,6 +248,12 @@ namespace vm
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()
{
// if another thread successfully called pred(), it must be set to null

View File

@ -62,9 +62,6 @@ namespace vm
bool try_notify();
};
// for internal use
waiter_t* _add_waiter(thread_t& thread, u32 addr, u32 size);
class waiter_lock_t
{
waiter_t* m_waiter;
@ -73,11 +70,7 @@ namespace vm
public:
waiter_lock_t() = delete;
template<typename T> inline waiter_lock_t(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_lock_t(thread_t& thread, u32 addr, u32 size);
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
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)
if (pred(args...)) return;

View File

@ -10,6 +10,9 @@ enum Status : u32
Ready,
};
// Emulation Stopped exception event
class EmulationStopped {};
class CPUThreadManager;
class PadManager;
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_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_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);