mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 22:11:26 +12:00
Minor thread fixes
Call thread result destructor
This commit is contained in:
parent
7a024f3355
commit
3359e9a51b
2 changed files with 66 additions and 33 deletions
|
@ -1807,13 +1807,7 @@ bool thread_ctrl::_wait_for(u64 usec)
|
||||||
|
|
||||||
void thread_base::_notify(cond_variable thread_base::* ptr)
|
void thread_base::_notify(cond_variable thread_base::* ptr)
|
||||||
{
|
{
|
||||||
// Optimized lock + unlock
|
m_mutex.lock_unlock();
|
||||||
if (!m_mutex.is_free())
|
|
||||||
{
|
|
||||||
m_mutex.lock();
|
|
||||||
m_mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
(this->*ptr).notify_one();
|
(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)
|
void thread_base::set_exception(std::exception_ptr ptr)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_mutex);
|
std::lock_guard lock(m_mutex);
|
||||||
|
|
|
@ -64,6 +64,11 @@ struct result_storage
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const T*>(&data);
|
return reinterpret_cast<const T*>(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroy() noexcept
|
||||||
|
{
|
||||||
|
get()->~T();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -77,12 +82,12 @@ struct result_storage<void>
|
||||||
template <class Context, typename... Args>
|
template <class Context, typename... Args>
|
||||||
using result_storage_t = result_storage<std::invoke_result_t<Context, 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>
|
template <typename T, typename = void>
|
||||||
struct thread_on_stop : std::bool_constant<false> {};
|
struct thread_abort : std::bool_constant<false> {};
|
||||||
|
|
||||||
template <typename T>
|
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
|
// Simple list of void() functors
|
||||||
class task_stack
|
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>
|
class thread_base : public std::enable_shared_from_this<thread_base>
|
||||||
{
|
{
|
||||||
// Native thread entry point function type
|
// 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.
|
// Get CPU cycles since last time this function was called. First call returns 0.
|
||||||
u64 get_cycles();
|
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
|
// Set exception
|
||||||
void set_exception(std::exception_ptr ptr);
|
void set_exception(std::exception_ptr ptr);
|
||||||
|
|
||||||
|
@ -277,6 +273,32 @@ class thread_ctrl final
|
||||||
friend class thread_base;
|
friend class thread_base;
|
||||||
|
|
||||||
public:
|
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
|
// Read current state
|
||||||
static inline thread_state 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);
|
return thread::finalize(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
friend class thread_ctrl;
|
||||||
|
|
||||||
|
public:
|
||||||
// Normal forwarding constructor
|
// Normal forwarding constructor
|
||||||
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<Context, Args&&...>>>
|
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<Context, Args&&...>>>
|
||||||
named_thread(std::string_view name, Args&&... args)
|
named_thread(std::string_view name, Args&&... args)
|
||||||
|
@ -431,6 +454,10 @@ public:
|
||||||
thread::start(&named_thread::entry_point);
|
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)
|
// Wait for the completion and access result (if not void)
|
||||||
[[nodiscard]] decltype(auto) operator()()
|
[[nodiscard]] decltype(auto) operator()()
|
||||||
{
|
{
|
||||||
|
@ -459,20 +486,38 @@ public:
|
||||||
return thread::m_state.load();
|
return thread::m_state.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context type doesn't need virtual destructor
|
// Try to set thread_state::aborting
|
||||||
~named_thread()
|
named_thread& operator=(thread_state s)
|
||||||
{
|
{
|
||||||
|
if (s != thread_state::aborting)
|
||||||
|
{
|
||||||
|
ASSUME(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Notify thread if not detached or terminated
|
// Notify thread if not detached or terminated
|
||||||
if (thread::m_state.compare_and_swap_test(thread_state::created, thread_state::aborting))
|
if (thread::m_state.compare_and_swap_test(thread_state::created, thread_state::aborting))
|
||||||
{
|
{
|
||||||
// Additional notification if on_stop() method exists
|
// Call on_abort() method if it's available
|
||||||
if constexpr (thread_on_stop<Context>())
|
if constexpr (thread_abort<Context>())
|
||||||
{
|
{
|
||||||
Context::on_stop();
|
Context::on_abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
thread::notify();
|
thread::notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context type doesn't need virtual destructor
|
||||||
|
~named_thread()
|
||||||
|
{
|
||||||
|
*this = thread_state::aborting;
|
||||||
thread::join();
|
thread::join();
|
||||||
|
|
||||||
|
if constexpr (!result::empty)
|
||||||
|
{
|
||||||
|
result::destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue