From 3eff94245771745d6f9c6f7fbe83d74fbc94dee5 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Fri, 12 Jan 2024 15:38:39 -0600 Subject: [PATCH] Always return outermost thread id -flyby: deprecate get_outer_self_id --- .../iostreams/src/server/output_stream.cpp | 11 ++- .../include/hpx/threading/thread.hpp | 63 +++++++-------- libs/core/threading/src/thread.cpp | 80 +++++++++---------- .../hpx/threading_base/thread_data.hpp | 32 +++++--- .../threading_base/thread_data_stackful.hpp | 4 +- .../hpx/threading_base/threading_base_fwd.hpp | 15 ++-- .../src/set_thread_state_timed.cpp | 4 +- libs/core/threading_base/src/thread_data.cpp | 23 ++---- 8 files changed, 117 insertions(+), 115 deletions(-) diff --git a/components/iostreams/src/server/output_stream.cpp b/components/iostreams/src/server/output_stream.cpp index dd0a519b27f8..2658f2c592b2 100644 --- a/components/iostreams/src/server/output_stream.cpp +++ b/components/iostreams/src/server/output_stream.cpp @@ -34,7 +34,7 @@ namespace hpx::iostreams::detail { ar << valid; if (valid) { - ar& data_; + ar & data_; } } @@ -44,7 +44,7 @@ namespace hpx::iostreams::detail { ar >> valid; if (valid) { - ar& data_; + ar & data_; } } } // namespace hpx::iostreams::detail @@ -89,10 +89,9 @@ namespace hpx::iostreams::server { { // {{{ // Perform the IO in another OS thread. detail::buffer in(buf_in); - hpx::get_thread_pool("io_pool")->get_io_service().post( - hpx::bind_front(&output_stream::call_write_sync, this, locality_id, - count, std::ref(in), - threads::thread_id_ref_type(threads::get_outer_self_id()))); + hpx::get_thread_pool("io_pool")->get_io_service().post(hpx::bind_front( + &output_stream::call_write_sync, this, locality_id, count, + std::ref(in), threads::thread_id_ref_type(threads::get_self_id()))); // Sleep until the worker thread wakes us up. this_thread::suspend(threads::thread_schedule_state::suspended, diff --git a/libs/core/threading/include/hpx/threading/thread.hpp b/libs/core/threading/include/hpx/threading/thread.hpp index 77005ea665d8..7a69ffd32dda 100644 --- a/libs/core/threading/include/hpx/threading/thread.hpp +++ b/libs/core/threading/include/hpx/threading/thread.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2022 Hartmut Kaiser +// Copyright (c) 2007-2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -41,7 +41,7 @@ namespace hpx { thread_termination_handler_type f); /// The class thread represents a single thread of execution. Threads allow - /// multiple functions to execute concurrently. hreads begin execution + /// multiple functions to execute concurrently. Threads begin execution /// immediately upon construction of the associated thread object (pending /// any OS scheduling delays), starting at the top-level function provided /// as a constructor argument. The return value of the top-level function is @@ -60,8 +60,6 @@ namespace hpx { { using mutex_type = hpx::spinlock; - void terminate(char const* function, char const* reason) const; - public: class id; using native_handle_type = threads::thread_id_type; @@ -73,7 +71,7 @@ namespace hpx { std::enable_if_t, thread>>> explicit thread(F&& f) { - auto thrd_data = threads::get_self_id_data(); + auto const thrd_data = threads::get_self_id_data(); HPX_ASSERT(thrd_data); start_thread(thrd_data->get_scheduler_base()->get_parent_pool(), util::deferred_call(HPX_FORWARD(F, f))); @@ -82,7 +80,7 @@ namespace hpx { template explicit thread(F&& f, Ts&&... vs) { - auto thrd_data = threads::get_self_id_data(); + auto const thrd_data = threads::get_self_id_data(); HPX_ASSERT(thrd_data); start_thread(thrd_data->get_scheduler_base()->get_parent_pool(), util::deferred_call(HPX_FORWARD(F, f), HPX_FORWARD(Ts, vs)...)); @@ -143,15 +141,15 @@ namespace hpx { [[nodiscard]] static unsigned int hardware_concurrency() noexcept; // extensions - void interrupt(bool flag = true); + void interrupt(bool flag = true) const; bool interruption_requested() const; - static void interrupt(id, bool flag = true); + static void interrupt(id const&, bool flag = true); - hpx::future get_future(error_code& ec = throws); + hpx::future get_future(error_code& ec = throws) const; std::size_t get_thread_data() const; - std::size_t set_thread_data(std::size_t); + std::size_t set_thread_data(std::size_t) const; #if defined(HPX_HAVE_LIBCDS) std::size_t get_libcds_data() const; @@ -295,7 +293,7 @@ namespace hpx { /// (and if there are no other threads at the same priority, /// yield has no effect). HPX_CORE_EXPORT void yield() noexcept; - HPX_CORE_EXPORT void yield_to(thread::id) noexcept; + HPX_CORE_EXPORT void yield_to(thread::id const&) noexcept; // extensions HPX_CORE_EXPORT threads::thread_priority get_priority() noexcept; @@ -350,45 +348,46 @@ namespace hpx { class HPX_CORE_EXPORT disable_interruption { - private: - disable_interruption(disable_interruption const&); - disable_interruption& operator=(disable_interruption const&); + public: + disable_interruption(disable_interruption&&) = delete; + disable_interruption& operator=(disable_interruption&&) = delete; + disable_interruption(disable_interruption const&) = delete; + disable_interruption& operator=( + disable_interruption const&) = delete; bool interruption_was_enabled_; friend class restore_interruption; - public: disable_interruption(); ~disable_interruption(); }; class HPX_CORE_EXPORT restore_interruption { - private: - restore_interruption(restore_interruption const&); - restore_interruption& operator=(restore_interruption const&); + public: + restore_interruption(restore_interruption&&) = delete; + restore_interruption& operator=(restore_interruption&&) = delete; + restore_interruption(restore_interruption const&) = delete; + restore_interruption& operator=( + restore_interruption const&) = delete; bool interruption_was_enabled_; - public: - explicit restore_interruption(disable_interruption& d); + explicit restore_interruption(disable_interruption const& d); ~restore_interruption(); }; } // namespace this_thread } // namespace hpx -namespace std { - - // specialize std::hash for hpx::thread::id - template <> - struct hash<::hpx::thread::id> +// specialize std::hash for hpx::thread::id +template <> +struct std::hash<::hpx::thread::id> +{ + std::size_t operator()(::hpx::thread::id const& id) const noexcept { - std::size_t operator()(::hpx::thread::id const& id) const - { - std::hash<::hpx::threads::thread_id_ref_type> hasher_; - return hasher_(id.native_handle()); - } - }; -} // namespace std + std::hash<::hpx::threads::thread_id_ref_type> const hasher_; + return hasher_(id.native_handle()); + } +}; // namespace std #include diff --git a/libs/core/threading/src/thread.cpp b/libs/core/threading/src/thread.cpp index 7b135e96bb0f..8df3b30b57cf 100644 --- a/libs/core/threading/src/thread.cpp +++ b/libs/core/threading/src/thread.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2022 Hartmut Kaiser +// Copyright (c) 2007-2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -22,7 +22,6 @@ #include #include -#include #include #include @@ -32,14 +31,14 @@ namespace hpx { - namespace detail { + namespace { - static thread_termination_handler_type thread_termination_handler; + thread_termination_handler_type thread_termination_handler; } void set_thread_termination_handler(thread_termination_handler_type f) { - detail::thread_termination_handler = HPX_MOVE(f); + thread_termination_handler = HPX_MOVE(f); } thread::thread() noexcept @@ -74,7 +73,7 @@ namespace hpx { { if (joinable()) { - if (detail::thread_termination_handler) + if (thread_termination_handler) { try { @@ -83,8 +82,7 @@ namespace hpx { } catch (...) { - detail::thread_termination_handler( - std::current_exception()); + thread_termination_handler(std::current_exception()); } } else @@ -103,17 +101,20 @@ namespace hpx { std::swap(id_, rhs.id_); } - static void run_thread_exit_callbacks() - { - threads::thread_id_type id = threads::get_self_id(); - if (id == threads::invalid_thread_id) + namespace { + + void run_thread_exit_callbacks() { - HPX_THROW_EXCEPTION(hpx::error::null_thread_id, - "run_thread_exit_callbacks", "null thread id encountered"); + threads::thread_id_type const id = threads::get_self_id(); + if (id == threads::invalid_thread_id) + { + HPX_THROW_EXCEPTION(hpx::error::null_thread_id, + "run_thread_exit_callbacks", "null thread id encountered"); + } + threads::run_thread_exit_callbacks(id); + threads::free_thread_exit_callbacks(id); } - threads::run_thread_exit_callbacks(id); - threads::free_thread_exit_callbacks(id); - } + } // namespace threads::thread_result_type thread::thread_function_nullary( hpx::move_only_function const& func) @@ -146,9 +147,8 @@ namespace hpx { // run all callbacks attached to the exit event for this thread run_thread_exit_callbacks(); - return threads::thread_result_type( - threads::thread_schedule_state::terminated, - threads::invalid_thread_id); + return {threads::thread_schedule_state::terminated, + threads::invalid_thread_id}; } thread::id thread::get_id() const noexcept @@ -182,15 +182,17 @@ namespace hpx { { HPX_THROW_EXCEPTION(hpx::error::thread_resource_error, "thread::start_thread", "Could not create thread"); - return; } } - static void resume_thread(threads::thread_id_ref_type const& id) - { - threads::set_thread_state( - id.noref(), threads::thread_schedule_state::pending); - } + namespace { + + void resume_thread(threads::thread_id_ref_type const& id) + { + threads::set_thread_state( + id.noref(), threads::thread_schedule_state::pending); + } + } // namespace void thread::join() { @@ -210,7 +212,6 @@ namespace hpx { l.unlock(); HPX_THROW_EXCEPTION(hpx::error::thread_resource_error, "thread::join", "hpx::thread: trying joining itself"); - return; } this_thread::interruption_point(); @@ -228,7 +229,7 @@ namespace hpx { } // extensions - void thread::interrupt(bool flag) + void thread::interrupt(bool flag) const { threads::interrupt_thread(native_handle(), flag); } @@ -238,7 +239,7 @@ namespace hpx { return threads::get_thread_interruption_requested(native_handle()); } - void thread::interrupt(thread::id id, bool flag) + void thread::interrupt(thread::id const& id, bool flag) { threads::interrupt_thread(id.id_, flag); } @@ -247,7 +248,7 @@ namespace hpx { { return threads::get_thread_data(native_handle()); } - std::size_t thread::set_thread_data(std::size_t data) + std::size_t thread::set_thread_data(std::size_t data) const { return threads::set_thread_data(native_handle(), data); } @@ -297,7 +298,7 @@ namespace hpx { using base_type::mtx_; public: - thread_task_base(threads::thread_id_ref_type const& id) + explicit thread_task_base(threads::thread_id_ref_type const& id) { if (threads::add_thread_exit_callback(id.noref(), hpx::bind_front(&thread_task_base::thread_exit_function, @@ -345,13 +346,13 @@ namespace hpx { }; } // namespace detail - hpx::future thread::get_future(error_code& ec) + hpx::future thread::get_future(error_code& ec) const { if (id_ == threads::invalid_thread_id) { HPX_THROWS_IF(ec, hpx::error::null_thread_id, "thread::get_future", "null thread id encountered"); - return hpx::future(); + return {}; } detail::thread_task_base* p = new detail::thread_task_base(id_); @@ -361,7 +362,7 @@ namespace hpx { HPX_THROWS_IF(ec, hpx::error::thread_resource_error, "thread::get_future", "Could not create future as thread has been terminated."); - return hpx::future(); + return {}; } using traits::future_access; @@ -371,7 +372,7 @@ namespace hpx { /////////////////////////////////////////////////////////////////////////// namespace this_thread { - void yield_to(thread::id id) noexcept + void yield_to(thread::id const& id) noexcept { this_thread::suspend(threads::thread_schedule_state::pending, id.native_handle(), "this_thread::yield_to"); @@ -486,8 +487,7 @@ namespace hpx { disable_interruption::~disable_interruption() { - threads::thread_self* p = threads::get_self_ptr(); - if (p) + if (threads::get_self_ptr() != nullptr) { threads::set_thread_interruption_enabled( threads::get_self_id(), interruption_was_enabled_); @@ -495,7 +495,8 @@ namespace hpx { } /////////////////////////////////////////////////////////////////////// - restore_interruption::restore_interruption(disable_interruption& d) + restore_interruption::restore_interruption( + disable_interruption const& d) : interruption_was_enabled_(d.interruption_was_enabled_) { if (!interruption_was_enabled_) @@ -508,8 +509,7 @@ namespace hpx { restore_interruption::~restore_interruption() { - threads::thread_self* p = threads::get_self_ptr(); - if (p) + if (threads::get_self_ptr() != nullptr) { threads::set_thread_interruption_enabled( threads::get_self_id(), interruption_was_enabled_); diff --git a/libs/core/threading_base/include/hpx/threading_base/thread_data.hpp b/libs/core/threading_base/include/hpx/threading_base/thread_data.hpp index f32d5ac84545..3047f7262d1e 100644 --- a/libs/core/threading_base/include/hpx/threading_base/thread_data.hpp +++ b/libs/core/threading_base/include/hpx/threading_base/thread_data.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2023 Hartmut Kaiser +// Copyright (c) 2007-2024 Hartmut Kaiser // Copyright (c) 2011 Bryce Lelbach // Copyright (c) 2008-2009 Chirag Dekate, Anshul Tandon // @@ -253,24 +253,24 @@ namespace hpx::threads { } #if !defined(HPX_HAVE_THREAD_DESCRIPTION) - threads::thread_description get_description() const + static threads::thread_description get_description() { - return threads::thread_description(""); + return {""}; } - threads::thread_description set_description( + static threads::thread_description set_description( threads::thread_description /*value*/) { - return threads::thread_description(""); + return {""}; } - threads::thread_description get_lco_description() const //-V524 + static threads::thread_description get_lco_description() //-V524 { - return threads::thread_description(""); + return {""}; } - threads::thread_description set_lco_description( //-V524 + static threads::thread_description set_lco_description( //-V524 threads::thread_description /*value*/) { - return threads::thread_description(""); + return {""}; } #else threads::thread_description get_description() const @@ -306,20 +306,20 @@ namespace hpx::threads { #if !defined(HPX_HAVE_THREAD_PARENT_REFERENCE) /// Return the locality of the parent thread - constexpr std::uint32_t get_parent_locality_id() const noexcept + static constexpr std::uint32_t get_parent_locality_id() noexcept { // this is the same as naming::invalid_locality_id return ~static_cast(0); } /// Return the thread id of the parent thread - constexpr thread_id_type get_parent_thread_id() const noexcept + static constexpr thread_id_type get_parent_thread_id() noexcept { return threads::invalid_thread_id; } /// Return the phase of the parent thread - constexpr std::size_t get_parent_thread_phase() const noexcept + static constexpr std::size_t get_parent_thread_phase() noexcept { return 0; } @@ -688,8 +688,11 @@ namespace hpx::threads { if (is_stackless()) { + HPX_ASSERT(dynamic_cast(this) != nullptr); return static_cast(this)->call(); } + + HPX_ASSERT(dynamic_cast(this) != nullptr); return static_cast(this)->call(agent_storage); } @@ -699,8 +702,11 @@ namespace hpx::threads { if (is_stackless()) { + HPX_ASSERT(dynamic_cast(this) != nullptr); return static_cast(this)->call(); } - return static_cast(this)->invoke_directly(); + + HPX_ASSERT(dynamic_cast(this) != nullptr); + return static_cast(this)->call_directly(); } } // namespace hpx::threads diff --git a/libs/core/threading_base/include/hpx/threading_base/thread_data_stackful.hpp b/libs/core/threading_base/include/hpx/threading_base/thread_data_stackful.hpp index c9eee85b8752..d3240aef378c 100644 --- a/libs/core/threading_base/include/hpx/threading_base/thread_data_stackful.hpp +++ b/libs/core/threading_base/include/hpx/threading_base/thread_data_stackful.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2023 Hartmut Kaiser +// Copyright (c) 2007-2024 Hartmut Kaiser // Copyright (c) 2011 Bryce Lelbach // Copyright (c) 2008-2009 Chirag Dekate, Anshul Tandon // @@ -68,7 +68,7 @@ namespace hpx::threads { return coroutine_(set_state_ex(thread_restart_state::signaled)); } - HPX_FORCEINLINE coroutine_type::result_type invoke_directly() + HPX_FORCEINLINE coroutine_type::result_type call_directly() { HPX_ASSERT(get_state().state() == thread_schedule_state::active); HPX_ASSERT(this == coroutine_.get_thread_id().get()); diff --git a/libs/core/threading_base/include/hpx/threading_base/threading_base_fwd.hpp b/libs/core/threading_base/include/hpx/threading_base/threading_base_fwd.hpp index 230468b44c42..ad05e6bf5dfc 100644 --- a/libs/core/threading_base/include/hpx/threading_base/threading_base_fwd.hpp +++ b/libs/core/threading_base/include/hpx/threading_base/threading_base_fwd.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2023 Hartmut Kaiser +// Copyright (c) 2007-2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -101,10 +101,15 @@ namespace hpx::threads { /// The function \a get_outer_self_id returns the HPX thread id of /// the current outer thread (or zero if the current thread is not a HPX - /// thread). This usually returns the same as \a get_self_id, except for - /// directly executed threads, in which case this returns the thread id - /// of the outermost HPX thread. - HPX_CORE_EXPORT thread_id_type get_outer_self_id() noexcept; + /// thread). This now always returns the same as \a get_self_id, even for + /// directly executed threads. + HPX_DEPRECATED_V(1, 10, + "hpx::threads::get_outer_self_id is deprecated, use " + "hpx::threads::get_self_id instead") + inline thread_id_type get_outer_self_id() noexcept + { + return get_self_id(); + } /// The function \a get_parent_id returns the HPX thread id of the /// current thread's parent (or zero if the current thread is not a diff --git a/libs/core/threading_base/src/set_thread_state_timed.cpp b/libs/core/threading_base/src/set_thread_state_timed.cpp index 9b762a825935..f28ff76c95d5 100644 --- a/libs/core/threading_base/src/set_thread_state_timed.cpp +++ b/libs/core/threading_base/src/set_thread_state_timed.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2023 Hartmut Kaiser +// Copyright (c) 2007-2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -83,7 +83,7 @@ namespace hpx::threads::detail { // create a new thread in suspended state, which will execute the // requested set_state when timer fires and will re-awaken this thread, // allowing the deadline_timer to go out of scope gracefully - thread_id_ref_type const self_id = get_outer_self_id(); // keep alive + thread_id_ref_type const self_id = get_self_id(); // keep alive std::shared_ptr> triggered( std::make_shared>(false)); diff --git a/libs/core/threading_base/src/thread_data.cpp b/libs/core/threading_base/src/thread_data.cpp index a884fbc33d52..5049acf2c214 100644 --- a/libs/core/threading_base/src/thread_data.cpp +++ b/libs/core/threading_base/src/thread_data.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2023 Hartmut Kaiser +// Copyright (c) 2007-2024 Hartmut Kaiser // Copyright (c) 2008-2009 Chirag Dekate, Anshul Tandon // Copyright (c) 2011 Bryce Lelbach // @@ -28,11 +28,14 @@ namespace hpx::threads { namespace detail { - static get_locality_id_type* get_locality_id_f; + namespace { + + get_locality_id_type* get_locality_id_f = nullptr; + } void set_get_locality_id(get_locality_id_type* f) { - get_locality_id_f = HPX_MOVE(f); + get_locality_id_f = f; } std::uint32_t get_locality_id(hpx::error_code& ec) @@ -312,16 +315,6 @@ namespace hpx::threads { } thread_id_type get_self_id() noexcept - { - if (thread_self const* self = get_self_ptr(); - HPX_LIKELY(nullptr != self)) - { - return self->get_thread_id(); - } - return threads::invalid_thread_id; - } - - thread_id_type get_outer_self_id() noexcept { if (thread_self const* self = get_self_ptr(); HPX_LIKELY(nullptr != self)) @@ -336,7 +329,7 @@ namespace hpx::threads { if (thread_self const* self = get_self_ptr(); HPX_LIKELY(nullptr != self)) { - return get_thread_id_data(self->get_thread_id()); + return get_thread_id_data(self->get_outer_thread_id()); } return nullptr; } @@ -415,7 +408,7 @@ namespace hpx::threads { if (thread_data const* thrd_data = get_self_id_data(); HPX_LIKELY(nullptr != thrd_data)) { - return thrd_data->get_component_id(); + return hpx::threads::thread_data::get_component_id(); } return 0; #endif