mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-28 19:20:36 +00:00
Minor thread fixes
Call thread result destructor
This commit is contained in:
parent
7a024f3355
commit
3359e9a51b
@ -1807,13 +1807,7 @@ bool thread_ctrl::_wait_for(u64 usec)
|
||||
|
||||
void thread_base::_notify(cond_variable thread_base::* ptr)
|
||||
{
|
||||
// Optimized lock + unlock
|
||||
if (!m_mutex.is_free())
|
||||
{
|
||||
m_mutex.lock();
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
m_mutex.lock_unlock();
|
||||
(this->*ptr).notify_one();
|
||||
}
|
||||
|
||||
@ -1834,12 +1828,6 @@ thread_base::~thread_base()
|
||||
}
|
||||
}
|
||||
|
||||
std::exception_ptr thread_base::get_exception() const
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
return m_exception;
|
||||
}
|
||||
|
||||
void thread_base::set_exception(std::exception_ptr ptr)
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
@ -64,6 +64,11 @@ struct result_storage
|
||||
{
|
||||
return reinterpret_cast<const T*>(&data);
|
||||
}
|
||||
|
||||
void destroy() noexcept
|
||||
{
|
||||
get()->~T();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -77,12 +82,12 @@ struct result_storage<void>
|
||||
template <class Context, typename... Args>
|
||||
using result_storage_t = result_storage<std::invoke_result_t<Context, Args...>>;
|
||||
|
||||
// Detect on_stop() method (should return void)
|
||||
// Detect on_abort() method (should return void)
|
||||
template <typename T, typename = void>
|
||||
struct thread_on_stop : std::bool_constant<false> {};
|
||||
struct thread_abort : std::bool_constant<false> {};
|
||||
|
||||
template <typename T>
|
||||
struct thread_on_stop<T, decltype(std::declval<named_thread<T>&>().on_stop())> : std::bool_constant<true> {};
|
||||
struct thread_abort<T, decltype(std::declval<named_thread<T>&>().on_abort())> : std::bool_constant<true> {};
|
||||
|
||||
// Simple list of void() functors
|
||||
class task_stack
|
||||
@ -153,7 +158,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Thread base class
|
||||
// Thread base class (TODO: remove shared_ptr, make private base)
|
||||
class thread_base : public std::enable_shared_from_this<thread_base>
|
||||
{
|
||||
// Native thread entry point function type
|
||||
@ -240,15 +245,6 @@ public:
|
||||
// Get CPU cycles since last time this function was called. First call returns 0.
|
||||
u64 get_cycles();
|
||||
|
||||
// Get platform-specific thread handle
|
||||
std::uintptr_t get_native_handle() const
|
||||
{
|
||||
return m_thread.load();
|
||||
}
|
||||
|
||||
// Get exception
|
||||
std::exception_ptr get_exception() const;
|
||||
|
||||
// Set exception
|
||||
void set_exception(std::exception_ptr ptr);
|
||||
|
||||
@ -277,6 +273,32 @@ class thread_ctrl final
|
||||
friend class thread_base;
|
||||
|
||||
public:
|
||||
// Get current thread name
|
||||
static std::string_view get_name()
|
||||
{
|
||||
return g_tls_this_thread->m_name.get();
|
||||
}
|
||||
|
||||
// Get thread name
|
||||
template <typename T>
|
||||
static std::string_view get_name(const named_thread<T>& thread)
|
||||
{
|
||||
return static_cast<const thread_base&>(thread).m_name.get();
|
||||
}
|
||||
|
||||
// Set current thread name (not recommended)
|
||||
static void set_name(std::string_view name)
|
||||
{
|
||||
g_tls_this_thread->m_name.assign(name);
|
||||
}
|
||||
|
||||
// Set thread name (not recommended)
|
||||
template <typename T>
|
||||
static void set_name(named_thread<T>& thread, std::string_view name)
|
||||
{
|
||||
static_cast<thread_base&>(thread).m_name.assign(name);
|
||||
}
|
||||
|
||||
// Read current state
|
||||
static inline thread_state state()
|
||||
{
|
||||
@ -412,8 +434,9 @@ class named_thread final : public Context, result_storage_t<Context>, public thr
|
||||
return thread::finalize(nullptr);
|
||||
}
|
||||
|
||||
public:
|
||||
friend class thread_ctrl;
|
||||
|
||||
public:
|
||||
// Normal forwarding constructor
|
||||
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<Context, Args&&...>>>
|
||||
named_thread(std::string_view name, Args&&... args)
|
||||
@ -431,6 +454,10 @@ public:
|
||||
thread::start(&named_thread::entry_point);
|
||||
}
|
||||
|
||||
named_thread(const named_thread&) = delete;
|
||||
|
||||
named_thread& operator=(const named_thread&) = delete;
|
||||
|
||||
// Wait for the completion and access result (if not void)
|
||||
[[nodiscard]] decltype(auto) operator()()
|
||||
{
|
||||
@ -459,20 +486,38 @@ public:
|
||||
return thread::m_state.load();
|
||||
}
|
||||
|
||||
// Context type doesn't need virtual destructor
|
||||
~named_thread()
|
||||
// Try to set thread_state::aborting
|
||||
named_thread& operator=(thread_state s)
|
||||
{
|
||||
if (s != thread_state::aborting)
|
||||
{
|
||||
ASSUME(0);
|
||||
}
|
||||
|
||||
// Notify thread if not detached or terminated
|
||||
if (thread::m_state.compare_and_swap_test(thread_state::created, thread_state::aborting))
|
||||
{
|
||||
// Additional notification if on_stop() method exists
|
||||
if constexpr (thread_on_stop<Context>())
|
||||
// Call on_abort() method if it's available
|
||||
if constexpr (thread_abort<Context>())
|
||||
{
|
||||
Context::on_stop();
|
||||
Context::on_abort();
|
||||
}
|
||||
|
||||
thread::notify();
|
||||
thread::join();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Context type doesn't need virtual destructor
|
||||
~named_thread()
|
||||
{
|
||||
*this = thread_state::aborting;
|
||||
thread::join();
|
||||
|
||||
if constexpr (!result::empty)
|
||||
{
|
||||
result::destroy();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user