From 3359e9a51be94385fcc307cab821874348528187 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 1 Oct 2018 20:05:47 +0300 Subject: [PATCH] Minor thread fixes Call thread result destructor --- Utilities/Thread.cpp | 14 +------- Utilities/Thread.h | 85 +++++++++++++++++++++++++++++++++----------- 2 files changed, 66 insertions(+), 33 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index f820494a7f..5a38894191 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -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); diff --git a/Utilities/Thread.h b/Utilities/Thread.h index bdcea7b01e..46c1b94ba0 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -64,6 +64,11 @@ struct result_storage { return reinterpret_cast(&data); } + + void destroy() noexcept + { + get()->~T(); + } }; template <> @@ -77,12 +82,12 @@ struct result_storage template using result_storage_t = result_storage>; -// Detect on_stop() method (should return void) +// Detect on_abort() method (should return void) template -struct thread_on_stop : std::bool_constant {}; +struct thread_abort : std::bool_constant {}; template -struct thread_on_stop&>().on_stop())> : std::bool_constant {}; +struct thread_abort&>().on_abort())> : std::bool_constant {}; // 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 { // 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 + static std::string_view get_name(const named_thread& thread) + { + return static_cast(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 + static void set_name(named_thread& thread, std::string_view name) + { + static_cast(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, public thr return thread::finalize(nullptr); } -public: + friend class thread_ctrl; +public: // Normal forwarding constructor template >> 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()) + // Call on_abort() method if it's available + if constexpr (thread_abort()) { - 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(); } } };