From 16db4132754a7da2b3effb98b15930e99e9830b3 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 -flyby: ignoring locks during termination detection --- .circleci/config.yml | 46 ++++++- .../iostreams/src/server/output_stream.cpp | 11 +- .../server/cancelable_action.hpp | 17 ++- .../include/hpx/config/threads_stack.hpp | 20 +-- .../include/hpx/coroutines/thread_enums.hpp | 8 +- libs/core/execution/tests/unit/bulk_async.cpp | 35 +++-- .../tests/unit/minimal_async_executor.cpp | 93 +++++++------ .../detail/hierarchical_spawning.hpp | 20 +-- .../executors/detail/index_queue_spawning.hpp | 7 +- .../executors/thread_pool_scheduler_bulk.hpp | 3 +- .../executors/tests/unit/created_executor.cpp | 54 +++++--- .../tests/unit/parallel_executor.cpp | 55 +++++--- .../unit/parallel_executor_parameters.cpp | 39 ++++-- .../tests/unit/parallel_policy_executor.cpp | 57 ++++---- .../tests/unit/shared_parallel_executor.cpp | 29 +++-- .../unit/standalone_thread_pool_executor.cpp | 33 +++-- .../futures/src/detail/execute_thread.cpp | 8 +- .../local_priority_queue_scheduler.hpp | 4 +- .../local_workrequesting_scheduler.hpp | 4 +- .../include/hpx/threading/thread.hpp | 63 +++++---- libs/core/threading/src/thread.cpp | 80 ++++++------ .../hpx/threading_base/thread_data.hpp | 8 +- .../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 | 18 +-- .../threading_base/src/thread_helpers.cpp | 6 +- .../regressions/thread_stacksize_current.cpp | 16 ++- .../unit/minimal_timed_async_executor.cpp | 56 +++++--- .../counter_interface.hpp | 8 +- .../detail/counter_interface_functions.hpp | 8 +- .../src/counter_interface.cpp | 8 +- .../performance_counters/src/counters.cpp | 2 +- .../detail/counter_interface_functions.cpp | 9 +- .../stubs/runtime_support.hpp | 47 +++---- .../src/runtime_support.cpp | 18 +-- .../src/server/runtime_support_server.cpp | 35 +++-- .../src/stubs/runtime_support_stubs.cpp | 123 +++++++++--------- .../threads/main_thread_exit_callbacks.cpp | 3 +- 39 files changed, 629 insertions(+), 445 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 014765077dda..4887c607fcd1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -497,10 +497,8 @@ jobs: - run: name: Building Unit Tests (Algorithms) command: | - ninja -j2 -k 0 \ - tests.unit.modules.algorithms.algorithms \ - tests.unit.modules.algorithms.block -# tests.unit.modules.algorithms.datapar_algorithms + ninja -j 1 -k 0 \ + tests.unit.modules.algorithms.algorithms - run: name: Running Unit Tests when: always @@ -512,9 +510,7 @@ jobs: --no-compress-output \ --output-on-failure \ --tests-regex \ - "tests.unit.modules.algorithms.algorithms|\ - tests.unit.modules.algorithms.block" -# "|tests.unit.modules.algorithms.datapar_algorithms" + "tests.unit.modules.algorithms.algorithms" - run: <<: *convert_xml - run: @@ -526,6 +522,39 @@ jobs: - store_artifacts: path: tests.unit.algorithms + tests.unit.algorithms.block: + <<: *defaults + steps: + - attach_workspace: + at: /hpx + - run: + name: Building Unit Tests (Algorithms) + command: | + ninja -j2 -k 0 \ + tests.unit.modules.algorithms.block + - run: + name: Running Unit Tests + when: always + command: | + ulimit -c unlimited + ctest \ + --timeout 120 \ + -T test \ + --no-compress-output \ + --output-on-failure \ + --tests-regex \ + "tests.unit.modules.algorithms.block" + - run: + <<: *convert_xml + - run: + <<: *move_core_dump + - run: + <<: *move_debug_log + - store_test_results: + path: tests.unit.algorithms.block + - store_artifacts: + path: tests.unit.algorithms.block + tests.unit.container_algorithms: <<: *defaults steps: @@ -913,6 +942,8 @@ workflows: <<: *core_dependency - tests.unit.algorithms: <<: *core_dependency + - tests.unit.algorithms.block: + <<: *core_dependency - tests.unit.container_algorithms: <<: *core_dependency - tests.unit.segmented_algorithms: @@ -970,6 +1001,7 @@ workflows: - core - tests.examples - tests.unit.algorithms + - tests.unit.algorithms.block - tests.unit.container_algorithms - tests.unit.segmented_algorithms - tests.unit1 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/examples/cancelable_action/cancelable_action/server/cancelable_action.hpp b/examples/cancelable_action/cancelable_action/server/cancelable_action.hpp index 9c131d256650..2042103cf06a 100644 --- a/examples/cancelable_action/cancelable_action/server/cancelable_action.hpp +++ b/examples/cancelable_action/cancelable_action/server/cancelable_action.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 @@ -63,6 +63,9 @@ namespace examples::server { } ~reset_id() { + auto const mtx = outer_.mtx_; + std::lock_guard l(*mtx); + [[maybe_unused]] hpx::thread::id const old_value = outer_.id_; outer_.id_ = hpx::thread::id(); HPX_ASSERT(old_value != hpx::thread::id()); @@ -104,9 +107,15 @@ namespace examples::server { }); auto const mtx = mtx_; - std::lock_guard l(*mtx); - HPX_ASSERT(id_ != hpx::thread::id()); - hpx::thread::interrupt(id_); + + std::unique_lock l(*mtx); + auto const id = id_; + + if (id != hpx::thread::id()) + { + l.unlock(); + hpx::thread::interrupt(id); + } } HPX_DEFINE_COMPONENT_ACTION(cancelable_action, do_it, do_it_action) diff --git a/libs/core/config/include/hpx/config/threads_stack.hpp b/libs/core/config/include/hpx/config/threads_stack.hpp index f2e0507fbe75..67f4101e442c 100644 --- a/libs/core/config/include/hpx/config/threads_stack.hpp +++ b/libs/core/config/include/hpx/config/threads_stack.hpp @@ -40,20 +40,22 @@ #endif #if !defined(HPX_SMALL_STACK_SIZE) -# if defined(HPX_WINDOWS) && !defined(HPX_HAVE_GENERIC_CONTEXT_COROUTINES) -# define HPX_SMALL_STACK_SIZE_TARGET 0x4000 // 16kByte -# else -# if defined(HPX_DEBUG) -# define HPX_SMALL_STACK_SIZE_TARGET 0x20000 // 128kByte +# if !defined(HPX_SMALL_STACK_SIZE_TARGET) +# if defined(HPX_WINDOWS) && !defined(HPX_HAVE_GENERIC_CONTEXT_COROUTINES) +# define HPX_SMALL_STACK_SIZE_TARGET 0x4000 // 16kByte # else -# if defined(__powerpc__) || defined(__INTEL_COMPILER) -# define HPX_SMALL_STACK_SIZE_TARGET 0x20000 // 128kByte +# if defined(HPX_DEBUG) +# define HPX_SMALL_STACK_SIZE_TARGET 0x20000 // 128kByte # else -# define HPX_SMALL_STACK_SIZE_TARGET 0x10000 // 64kByte +# if defined(__powerpc__) || defined(__INTEL_COMPILER) +# define HPX_SMALL_STACK_SIZE_TARGET 0x20000 // 128kByte +# else +# define HPX_SMALL_STACK_SIZE_TARGET 0x10000 // 64kByte +# endif # endif # endif # endif - +# # if HPX_SMALL_STACK_SIZE_TARGET < (2 * HPX_THREADS_STACK_OVERHEAD) # define HPX_SMALL_STACK_SIZE (2 * HPX_THREADS_STACK_OVERHEAD) # else diff --git a/libs/core/coroutines/include/hpx/coroutines/thread_enums.hpp b/libs/core/coroutines/include/hpx/coroutines/thread_enums.hpp index 7abf67d5c3d6..2ab5bef47cdc 100644 --- a/libs/core/coroutines/include/hpx/coroutines/thread_enums.hpp +++ b/libs/core/coroutines/include/hpx/coroutines/thread_enums.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 @@ -425,6 +425,12 @@ namespace hpx::threads { runs_as_child_mode_bits = static_cast(bits); } + void schedule_hint(std::int16_t core) noexcept + { + mode = thread_schedule_hint_mode::thread; + hint = core; + } + /// The hint associated with the mode. The interpretation of this hint /// depends on the given mode. std::int16_t hint = -1; diff --git a/libs/core/execution/tests/unit/bulk_async.cpp b/libs/core/execution/tests/unit/bulk_async.cpp index ee5e54cd876d..8f7e5b359825 100644 --- a/libs/core/execution/tests/unit/bulk_async.cpp +++ b/libs/core/execution/tests/unit/bulk_async.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2015 Daniel Bourgeois +// Copyright (c) 2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -16,8 +17,8 @@ #include //////////////////////////////////////////////////////////////////////////////// -int bulk_test( - hpx::thread::id tid, int value, bool is_par, int passed_through) //-V813 +int bulk_test(hpx::thread::id const& tid, int value, bool is_par, + int passed_through) //-V813 { HPX_TEST_EQ(is_par, (tid != hpx::this_thread::get_id())); HPX_TEST_EQ(passed_through, 42); @@ -25,7 +26,7 @@ int bulk_test( } template -void test_bulk_sync(Executor& exec) +void test_bulk_sync(Executor&& exec) { hpx::thread::id tid = hpx::this_thread::get_id(); @@ -35,14 +36,15 @@ void test_bulk_sync(Executor& exec) using hpx::placeholders::_1; using hpx::placeholders::_2; - std::vector results = hpx::parallel::execution::bulk_sync_execute( - exec, hpx::bind(&bulk_test, tid, _1, false, _2), v, 42); + std::vector results = + hpx::parallel::execution::bulk_sync_execute(HPX_FORWARD(Executor, exec), + hpx::bind(&bulk_test, tid, _1, false, _2), v, 42); HPX_TEST(std::equal(std::begin(results), std::end(results), std::begin(v))); } template -void test_bulk_async(Executor& exec) +void test_bulk_async(Executor&& exec) { hpx::thread::id tid = hpx::this_thread::get_id(); @@ -54,7 +56,8 @@ void test_bulk_async(Executor& exec) std::vector> results = hpx::parallel::execution::bulk_async_execute( - exec, hpx::bind(&bulk_test, tid, _1, true, _2), v, 42); + HPX_FORWARD(Executor, exec), + hpx::bind(&bulk_test, tid, _1, true, _2), v, 42); HPX_TEST(std::equal(std::begin(results), std::end(results), std::begin(v), [](hpx::future& lhs, const int& rhs) { @@ -62,23 +65,33 @@ void test_bulk_async(Executor& exec) })); } +template +decltype(auto) disable_run_as_child(Executor&& exec) +{ + auto hint = hpx::execution::experimental::get_hint(exec); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + + return hpx::experimental::prefer(hpx::execution::experimental::with_hint, + HPX_FORWARD(Executor, exec), hint); +} + //////////////////////////////////////////////////////////////////////////////// int hpx_main() { hpx::execution::sequenced_executor seq_exec; - test_bulk_sync(seq_exec); + test_bulk_sync(disable_run_as_child(seq_exec)); hpx::execution::parallel_executor par_exec; hpx::execution::parallel_executor par_fork_exec(hpx::launch::fork); - test_bulk_async(par_exec); - test_bulk_async(par_fork_exec); + test_bulk_async(disable_run_as_child(par_exec)); + test_bulk_async(disable_run_as_child(par_fork_exec)); return hpx::local::finalize(); } int main(int argc, char* argv[]) { - // By default this test should run on all available cores + // By default, this test should run on all available cores std::vector const cfg = {"hpx.os_threads=all"}; // Initialize and run HPX diff --git a/libs/core/execution/tests/unit/minimal_async_executor.cpp b/libs/core/execution/tests/unit/minimal_async_executor.cpp index f9c5db8453a0..3e099db189fe 100644 --- a/libs/core/execution/tests/unit/minimal_async_executor.cpp +++ b/libs/core/execution/tests/unit/minimal_async_executor.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 @@ -36,7 +36,8 @@ void apply_test(hpx::latch& l, hpx::thread::id& id, int passed_through) l.count_down(1); } -void async_bulk_test(int, hpx::thread::id tid, int passed_through) //-V813 +void async_bulk_test( + int, hpx::thread::id const& tid, int passed_through) //-V813 { HPX_TEST_NEQ(tid, hpx::this_thread::get_id()); HPX_TEST_EQ(passed_through, 42); @@ -57,14 +58,14 @@ void test_apply(Executor& exec) } template -void test_sync(Executor& exec) +void test_sync(Executor&& exec) { HPX_TEST(hpx::parallel::execution::sync_execute(exec, &async_test, 42) != hpx::this_thread::get_id()); } template -void test_async(Executor& exec) +void test_async(Executor&& exec) { HPX_TEST( hpx::parallel::execution::async_execute(exec, &async_test, 42).get() != @@ -72,7 +73,7 @@ void test_async(Executor& exec) } template -void test_bulk_sync(Executor& exec) +void test_bulk_sync(Executor&& exec) { hpx::thread::id tid = hpx::this_thread::get_id(); @@ -89,7 +90,7 @@ void test_bulk_sync(Executor& exec) } template -void test_bulk_async(Executor& exec) +void test_bulk_async(Executor&& exec) { hpx::thread::id tid = hpx::this_thread::get_id(); @@ -153,17 +154,21 @@ struct test_async_executor1 test_async_executor1 const&, F&& f, Ts&&... ts) { ++count_async; - return hpx::async( - hpx::launch::async, std::forward(f), std::forward(ts)...); + + auto policy = hpx::launch::async; + auto hint = policy.hint(); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + policy.set_hint(hint); + + return hpx::async(policy, std::forward(f), std::forward(ts)...); } }; -namespace hpx::parallel::execution { - template <> - struct is_two_way_executor : std::true_type - { - }; -} // namespace hpx::parallel::execution +template <> +struct hpx::parallel::execution::is_two_way_executor + : std::true_type +{ +}; struct test_async_executor2 : test_async_executor1 { @@ -174,18 +179,22 @@ struct test_async_executor2 : test_async_executor1 test_async_executor2 const&, F&& f, Ts&&... ts) { ++count_sync; - return hpx::async( - hpx::launch::async, std::forward(f), std::forward(ts)...) + + auto policy = hpx::launch::async; + auto hint = policy.hint(); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + policy.set_hint(hint); + + return hpx::async(policy, std::forward(f), std::forward(ts)...) .get(); } }; -namespace hpx::parallel::execution { - template <> - struct is_two_way_executor : std::true_type - { - }; -} // namespace hpx::parallel::execution +template <> +struct hpx::parallel::execution::is_two_way_executor + : std::true_type +{ +}; struct test_async_executor3 : test_async_executor1 { @@ -197,21 +206,26 @@ struct test_async_executor3 : test_async_executor1 test_async_executor3 const&, F f, Shape const& shape, Ts&&... ts) { ++count_bulk_sync; + + auto policy = hpx::launch::async; + auto hint = policy.hint(); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + policy.set_hint(hint); + std::vector> results; for (auto const& elem : shape) { - results.push_back(hpx::async(hpx::launch::async, f, elem, ts...)); + results.push_back(hpx::async(policy, f, elem, ts...)); } hpx::when_all(results).get(); } }; -namespace hpx::parallel::execution { - template <> - struct is_two_way_executor : std::true_type - { - }; -} // namespace hpx::parallel::execution +template <> +struct hpx::parallel::execution::is_two_way_executor + : std::true_type +{ +}; struct test_async_executor4 : test_async_executor1 { @@ -223,10 +237,16 @@ struct test_async_executor4 : test_async_executor1 test_async_executor4 const&, F f, Shape const& shape, Ts&&... ts) { ++count_bulk_async; + + auto policy = hpx::launch::async; + auto hint = policy.hint(); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + policy.set_hint(hint); + std::vector> results; for (auto const& elem : shape) { - results.push_back(hpx::async(hpx::launch::async, f, elem, ts...)); + results.push_back(hpx::async(policy, f, elem, ts...)); } return results; } @@ -257,12 +277,11 @@ struct test_async_executor5 : test_async_executor1 } }; -namespace hpx::parallel::execution { - template <> - struct is_two_way_executor : std::true_type - { - }; -} // namespace hpx::parallel::execution +template <> +struct hpx::parallel::execution::is_two_way_executor + : std::true_type +{ +}; /////////////////////////////////////////////////////////////////////////////// int hpx_main() @@ -278,7 +297,7 @@ int hpx_main() int main(int argc, char* argv[]) { - // By default this test should run on all available cores + // By default, this test should run on all available cores std::vector const cfg = {"hpx.os_threads=all"}; // Initialize and run HPX diff --git a/libs/core/executors/include/hpx/executors/detail/hierarchical_spawning.hpp b/libs/core/executors/include/hpx/executors/detail/hierarchical_spawning.hpp index 899b37d5d80e..cde46fef7146 100644 --- a/libs/core/executors/include/hpx/executors/detail/hierarchical_spawning.hpp +++ b/libs/core/executors/include/hpx/executors/detail/hierarchical_spawning.hpp @@ -1,5 +1,5 @@ // Copyright (c) 2019-2020 ETH Zurich -// Copyright (c) 2007-2022 Hartmut Kaiser +// Copyright (c) 2007-2024 Hartmut Kaiser // Copyright (c) 2019 Agustin Berge // // SPDX-License-Identifier: BSL-1.0 @@ -52,7 +52,7 @@ namespace hpx::parallel::execution::detail { HPX_ASSERT(pool); using result_type = std::vector< - hpx::future>>; + hpx::future>>; result_type results; std::size_t const size = hpx::util::size(shape); @@ -69,9 +69,10 @@ namespace hpx::parallel::execution::detail { std::size_t const part_end = ((t + 1) * size) / num_threads; std::size_t const part_size = part_end - part_begin; - auto async_policy = hpx::execution::experimental::with_hint(policy, - threads::thread_schedule_hint{ - static_cast(first_thread + t)}); + auto hint = hpx::execution::experimental::get_hint(policy); + hint.schedule_hint(static_cast(first_thread + t)); + auto async_policy = + hpx::execution::experimental::with_hint(policy, hint); if (hierarchical_threshold != 0 && part_size > hierarchical_threshold) @@ -161,10 +162,13 @@ namespace hpx::parallel::execution::detail { auto it = std::begin(shape); for (std::size_t t = 0; t != num_threads; ++t) { + auto inner_hint = + hpx::execution::experimental::get_hint(policy); + inner_hint.schedule_hint( + static_cast(first_thread + t)); auto inner_post_policy = - hpx::execution::experimental::with_hint(policy, - threads::thread_schedule_hint{ - static_cast(first_thread + t)}); + hpx::execution::experimental::with_hint( + policy, inner_hint); std::size_t const end = ((t + 1) * size) / num_threads; std::size_t const part_size = end - begin; diff --git a/libs/core/executors/include/hpx/executors/detail/index_queue_spawning.hpp b/libs/core/executors/include/hpx/executors/detail/index_queue_spawning.hpp index 927a1ca7b705..737694e7c2b7 100644 --- a/libs/core/executors/include/hpx/executors/detail/index_queue_spawning.hpp +++ b/libs/core/executors/include/hpx/executors/detail/index_queue_spawning.hpp @@ -104,7 +104,7 @@ namespace hpx::parallel::execution::detail { if (allow_stealing) { // Then steal from the opposite end of the neighboring queues - static constexpr auto opposite_end = + constexpr auto opposite_end = hpx::concurrency::detail::opposite_end_v; for (std::uint32_t offset = 1; offset != state->num_threads; @@ -150,7 +150,7 @@ namespace hpx::parallel::execution::detail { // Finish the work for one worker thread. If this is not the last worker // thread to finish, it will only decrement the counter. If it is the // last thread it will call set_exception if there is an exception. - // Otherwise it will call set_value on the shared state. + // Otherwise, it will call set_value on the shared state. void finish() const { if (--(state->tasks_remaining.data_) == 0) @@ -338,8 +338,7 @@ namespace hpx::parallel::execution::detail { hint.hint == -1) { // apply hint if none was given - hint.mode = hpx::threads::thread_schedule_hint_mode::thread; - hint.hint = worker_thread + first_thread; + hint.schedule_hint(worker_thread + first_thread); hpx::detail::post_policy_dispatch::call( hpx::execution::experimental::with_hint(post_policy, hint), diff --git a/libs/core/executors/include/hpx/executors/thread_pool_scheduler_bulk.hpp b/libs/core/executors/include/hpx/executors/thread_pool_scheduler_bulk.hpp index fb826e25e93f..ea6ffc141adb 100644 --- a/libs/core/executors/include/hpx/executors/thread_pool_scheduler_bulk.hpp +++ b/libs/core/executors/include/hpx/executors/thread_pool_scheduler_bulk.hpp @@ -400,8 +400,7 @@ namespace hpx::execution::experimental::detail { hint.hint == -1) { // apply hint if none was given - hint.mode = hpx::threads::thread_schedule_hint_mode::thread; - hint.hint = worker_thread + op_state->first_thread; + hint.schedule_hint(worker_thread + op_state->first_thread); auto policy = hpx::execution::experimental::with_hint( op_state->scheduler.policy(), hint); diff --git a/libs/core/executors/tests/unit/created_executor.cpp b/libs/core/executors/tests/unit/created_executor.cpp index 910bdf399399..c7a11a8c073d 100644 --- a/libs/core/executors/tests/unit/created_executor.cpp +++ b/libs/core/executors/tests/unit/created_executor.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2015 Daniel Bourgeois -// Copyright (c) 2022 Hartmut Kaiser +// Copyright (c) 2022-2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -24,7 +24,7 @@ #include using hpx::util::deferred_call; -typedef std::vector::iterator iter; +using iter = std::vector::iterator; //////////////////////////////////////////////////////////////////////////////// // A parallel executor that returns void for bulk_execute and hpx::future @@ -72,7 +72,17 @@ namespace hpx::parallel::execution { //////////////////////////////////////////////////////////////////////////////// // Tests to void_parallel_executor behavior for the bulk executes -void bulk_test(int, hpx::thread::id tid, int passed_through) //-V813 +template +decltype(auto) disable_run_as_child(Executor&& exec) +{ + auto hint = hpx::execution::experimental::get_hint(exec); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + + return hpx::experimental::prefer(hpx::execution::experimental::with_hint, + HPX_FORWARD(Executor, exec), hint); +} + +void bulk_test(int, hpx::thread::id const& tid, int passed_through) //-V813 { HPX_TEST_NEQ(tid, hpx::this_thread::get_id()); HPX_TEST_EQ(passed_through, 42); @@ -92,8 +102,9 @@ void test_void_bulk_sync() executor exec; hpx::parallel::execution::bulk_sync_execute( - exec, hpx::bind(&bulk_test, _1, tid, _2), v, 42); - hpx::parallel::execution::bulk_sync_execute(exec, &bulk_test, v, tid, 42); + disable_run_as_child(exec), hpx::bind(&bulk_test, _1, tid, _2), v, 42); + hpx::parallel::execution::bulk_sync_execute( + disable_run_as_child(exec), &bulk_test, v, tid, 42); } void test_void_bulk_async() @@ -109,11 +120,12 @@ void test_void_bulk_async() using hpx::placeholders::_2; executor exec; - hpx::when_all(hpx::parallel::execution::bulk_async_execute( - exec, hpx::bind(&bulk_test, _1, tid, _2), v, 42)) + hpx::when_all( + hpx::parallel::execution::bulk_async_execute(disable_run_as_child(exec), + hpx::bind(&bulk_test, _1, tid, _2), v, 42)) .get(); hpx::when_all(hpx::parallel::execution::bulk_async_execute( - exec, &bulk_test, v, tid, 42)) + disable_run_as_child(exec), &bulk_test, v, tid, 42)) .get(); } @@ -122,16 +134,16 @@ void test_void_bulk_async() // Create shape argument for parallel_executor std::vector> split( - iter first, iter last, int parts) + iter first, iter const& last, int parts) { - typedef std::iterator_traits::difference_type sz_type; - sz_type count = std::distance(first, last); - sz_type increment = count / parts; + using sz_type = std::iterator_traits::difference_type; + sz_type const count = std::distance(first, last); + sz_type const increment = count / parts; std::vector> results; while (first != last) { - iter prev = first; + iter const prev = first; std::advance(first, (std::min)(increment, std::distance(first, last))); results.push_back(hpx::util::iterator_range(prev, first)); } @@ -139,7 +151,7 @@ std::vector> split( } // parallel sum using hpx's parallel executor -int parallel_sum(iter first, iter last, int num_parts) +int parallel_sum(iter const& first, iter const& last, int num_parts) { hpx::execution::parallel_executor exec; @@ -158,22 +170,22 @@ int parallel_sum(iter first, iter last, int num_parts) [](int a, hpx::future& b) -> int { return a + b.get(); }); } -// parallel sum using void parallel executer -int void_parallel_sum(iter first, iter last, int num_parts) +// parallel sum using void parallel executor +int void_parallel_sum(iter const& first, iter const& last, int num_parts) { void_parallel_executor exec; std::vector temp(num_parts + 1, 0); std::iota(std::begin(temp), std::end(temp), 0); - std::ptrdiff_t section_size = std::distance(first, last) / num_parts; + std::ptrdiff_t const section_size = std::distance(first, last) / num_parts; std::vector> f = hpx::parallel::execution::bulk_async_execute( exec, [&](const int& i) { - iter b = first + i * section_size; //-V104 - iter e = first + + iter const b = first + i * section_size; //-V104 + iter const e = first + (std::min)(std::distance(first, last), static_cast( (i + 1) * section_size) //-V104 @@ -193,7 +205,7 @@ void sum_test() auto random_num = []() { return std::rand() % 50 - 25; }; std::generate(std::begin(vec), std::end(vec), random_num); - int sum = std::accumulate(std::begin(vec), std::end(vec), 0); + int const sum = std::accumulate(std::begin(vec), std::end(vec), 0); int num_parts = std::rand() % 5 + 3; // Return futures holding results of parallel_sum and void_parallel_sum @@ -235,7 +247,7 @@ int main(int argc, char* argv[]) desc_commandline.add_options()("seed,s", value(), "the random number generator seed to use for this run"); - // By default this test should run on all available cores + // By default, this test should run on all available cores std::vector const cfg = {"hpx.os_threads=all"}; // Initialize and run HPX diff --git a/libs/core/executors/tests/unit/parallel_executor.cpp b/libs/core/executors/tests/unit/parallel_executor.cpp index 5912b9ee154f..a661539c9403 100644 --- a/libs/core/executors/tests/unit/parallel_executor.cpp +++ b/libs/core/executors/tests/unit/parallel_executor.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 @@ -25,7 +25,7 @@ hpx::thread::id test(int passed_through) void test_sync() { - typedef hpx::execution::parallel_executor executor; + using executor = hpx::execution::parallel_executor; executor exec; HPX_TEST(hpx::parallel::execution::sync_execute(exec, &test, 42) == @@ -34,7 +34,7 @@ void test_sync() void test_async() { - typedef hpx::execution::parallel_executor executor; + using executor = hpx::execution::parallel_executor; executor exec; HPX_TEST(hpx::parallel::execution::async_execute(exec, &test, 42).get() != @@ -54,7 +54,7 @@ hpx::thread::id test_f(hpx::future f, int passed_through) void test_then() { - typedef hpx::execution::parallel_executor executor; + using executor = hpx::execution::parallel_executor; hpx::future f = hpx::make_ready_future(); @@ -65,7 +65,17 @@ void test_then() } /////////////////////////////////////////////////////////////////////////////// -void bulk_test(int, hpx::thread::id tid, int passed_through) //-V813 +template +decltype(auto) disable_run_as_child(Executor&& exec) +{ + auto hint = hpx::execution::experimental::get_hint(exec); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + + return hpx::experimental::prefer(hpx::execution::experimental::with_hint, + HPX_FORWARD(Executor, exec), hint); +} + +void bulk_test(int, hpx::thread::id const& tid, int passed_through) //-V813 { HPX_TEST_NEQ(tid, hpx::this_thread::get_id()); HPX_TEST_EQ(passed_through, 42); @@ -73,7 +83,7 @@ void bulk_test(int, hpx::thread::id tid, int passed_through) //-V813 void test_bulk_sync() { - typedef hpx::execution::parallel_executor executor; + using executor = hpx::execution::parallel_executor; hpx::thread::id tid = hpx::this_thread::get_id(); @@ -85,14 +95,15 @@ void test_bulk_sync() executor exec; hpx::parallel::execution::bulk_sync_execute( - exec, hpx::bind(&bulk_test, _1, tid, _2), v, 42); - hpx::parallel::execution::bulk_sync_execute(exec, &bulk_test, v, tid, 42); + disable_run_as_child(exec), hpx::bind(&bulk_test, _1, tid, _2), v, 42); + hpx::parallel::execution::bulk_sync_execute( + disable_run_as_child(exec), &bulk_test, v, tid, 42); } /////////////////////////////////////////////////////////////////////////////// void test_bulk_async() { - typedef hpx::execution::parallel_executor executor; + using executor = hpx::execution::parallel_executor; hpx::thread::id tid = hpx::this_thread::get_id(); @@ -103,16 +114,18 @@ void test_bulk_async() using hpx::placeholders::_2; executor exec; - hpx::when_all(hpx::parallel::execution::bulk_async_execute( - exec, hpx::bind(&bulk_test, _1, tid, _2), v, 42)) + hpx::when_all( + hpx::parallel::execution::bulk_async_execute(disable_run_as_child(exec), + hpx::bind(&bulk_test, _1, tid, _2), v, 42)) .get(); hpx::when_all(hpx::parallel::execution::bulk_async_execute( - exec, &bulk_test, v, tid, 42)) + disable_run_as_child(exec), &bulk_test, v, tid, 42)) .get(); } /////////////////////////////////////////////////////////////////////////////// -void bulk_test_f(int, hpx::shared_future f, hpx::thread::id tid, +void bulk_test_f(int, hpx::shared_future const& f, + hpx::thread::id const& tid, int passed_through) //-V813 { HPX_TEST(f.is_ready()); // make sure, future is ready @@ -125,7 +138,7 @@ void bulk_test_f(int, hpx::shared_future f, hpx::thread::id tid, void test_bulk_then() { - typedef hpx::execution::parallel_executor executor; + using executor = hpx::execution::parallel_executor; hpx::thread::id tid = hpx::this_thread::get_id(); @@ -167,19 +180,19 @@ void test_processing_mask() hpx::execution::parallel_executor exec; { - auto pool = hpx::threads::detail::get_self_or_default_pool(); - auto expected_mask = + auto const pool = hpx::threads::detail::get_self_or_default_pool(); + auto const expected_mask = pool->get_used_processing_units(pool->get_os_thread_count(), false); - auto mask = + auto const mask = hpx::execution::experimental::get_processing_units_mask(exec); HPX_TEST(mask == expected_mask); } { - auto pool = hpx::threads::detail::get_self_or_default_pool(); - auto expected_mask = + auto const pool = hpx::threads::detail::get_self_or_default_pool(); + auto const expected_mask = pool->get_used_processing_units(pool->get_os_thread_count(), true); - auto mask = hpx::execution::experimental::get_cores_mask(exec); + auto const mask = hpx::execution::experimental::get_cores_mask(exec); HPX_TEST(mask == expected_mask); } } @@ -204,7 +217,7 @@ int hpx_main() int main(int argc, char* argv[]) { - // By default this test should run on all available cores + // By default, this test should run on all available cores std::vector const cfg = {"hpx.os_threads=all"}; // Initialize and run HPX diff --git a/libs/core/executors/tests/unit/parallel_executor_parameters.cpp b/libs/core/executors/tests/unit/parallel_executor_parameters.cpp index 7822d93193a0..c55a0c70840f 100644 --- a/libs/core/executors/tests/unit/parallel_executor_parameters.cpp +++ b/libs/core/executors/tests/unit/parallel_executor_parameters.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 @@ -14,6 +14,16 @@ #include #include +template +decltype(auto) disable_run_as_child(Executor&& exec) +{ + auto hint = hpx::execution::experimental::get_hint(exec); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + + return hpx::experimental::prefer(hpx::execution::experimental::with_hint, + HPX_FORWARD(Executor, exec), hint); +} + hpx::threads::thread_stacksize get_stacksize() { return hpx::threads::get_self_stacksize_enum(); @@ -33,8 +43,8 @@ void test_stacksize() HPX_TEST(hpx::execution::experimental::get_stacksize(exec) == hpx::threads::thread_stacksize::default_); - auto newexec = - hpx::execution::experimental::with_stacksize(exec, stacksize); + auto newexec = disable_run_as_child( + hpx::execution::experimental::with_stacksize(exec, stacksize)); HPX_TEST(hpx::execution::experimental::get_stacksize(exec) == hpx::threads::thread_stacksize::default_); @@ -64,8 +74,8 @@ void test_priority() HPX_TEST(hpx::execution::experimental::get_priority(exec) == hpx::threads::thread_priority::default_); - auto newexec = - hpx::execution::experimental::with_priority(exec, priority); + auto newexec = disable_run_as_child( + hpx::execution::experimental::with_priority(exec, priority)); HPX_TEST(hpx::execution::experimental::get_priority(exec) == hpx::threads::thread_priority::default_); @@ -84,22 +94,22 @@ void test_hint() auto orghint = hpx::execution::experimental::get_hint(exec); HPX_TEST(orghint.mode == hpx::threads::thread_schedule_hint_mode::none); - HPX_TEST(orghint.hint == std::int16_t(-1)); + HPX_TEST(orghint.hint == static_cast(-1)); - for (auto mode : {hpx::threads::thread_schedule_hint_mode::none, + for (auto const mode : {hpx::threads::thread_schedule_hint_mode::none, hpx::threads::thread_schedule_hint_mode::thread, hpx::threads::thread_schedule_hint_mode::numa}) { - for (auto hint : {0, 1}) + for (auto const hint : {0, 1}) { hpx::threads::thread_schedule_hint newhint(mode, hint); - auto newexec = - hpx::execution::experimental::with_hint(exec, newhint); + auto newexec = disable_run_as_child( + hpx::execution::experimental::with_hint(exec, newhint)); orghint = hpx::execution::experimental::get_hint(exec); HPX_TEST( orghint.mode == hpx::threads::thread_schedule_hint_mode::none); - HPX_TEST(orghint.hint == std::int16_t(-1)); + HPX_TEST(orghint.hint == static_cast(-1)); newhint = hpx::execution::experimental::get_hint(newexec); HPX_TEST(newhint.mode == mode); @@ -155,14 +165,15 @@ void test_num_cores() using executor = hpx::execution::parallel_executor; executor exec; - auto num_cores = hpx::parallel::execution::processing_units_count(exec); + auto const num_cores = + hpx::parallel::execution::processing_units_count(exec); auto newexec = hpx::parallel::execution::with_processing_units_count(exec, 2); HPX_TEST( num_cores == hpx::parallel::execution::processing_units_count(exec)); - HPX_TEST(std::size_t(2) == + HPX_TEST(static_cast(2) == hpx::parallel::execution::processing_units_count(newexec)); } @@ -182,7 +193,7 @@ int hpx_main() int main(int argc, char* argv[]) { - // By default this test should run on all available cores + // By default, this test should run on all available cores std::vector const cfg = {"hpx.os_threads=all"}; // Initialize and run HPX diff --git a/libs/core/executors/tests/unit/parallel_policy_executor.cpp b/libs/core/executors/tests/unit/parallel_policy_executor.cpp index c3f1ed7c04f2..c5c767d97a9e 100644 --- a/libs/core/executors/tests/unit/parallel_policy_executor.cpp +++ b/libs/core/executors/tests/unit/parallel_policy_executor.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2019 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 @@ -17,6 +17,16 @@ #include /////////////////////////////////////////////////////////////////////////////// +template +decltype(auto) disable_run_as_child(Executor&& exec) +{ + auto hint = hpx::execution::experimental::get_hint(exec); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + + return hpx::experimental::prefer(hpx::execution::experimental::with_hint, + HPX_FORWARD(Executor, exec), hint); +} + hpx::thread::id test(int passed_through) { HPX_TEST_EQ(passed_through, 42); @@ -26,7 +36,7 @@ hpx::thread::id test(int passed_through) template void test_sync() { - typedef hpx::execution::parallel_policy_executor executor; + using executor = hpx::execution::parallel_policy_executor; executor exec; HPX_TEST(hpx::parallel::execution::sync_execute(exec, &test, 42) == @@ -36,12 +46,12 @@ void test_sync() template void test_async(bool sync) { - typedef hpx::execution::parallel_policy_executor executor; + using executor = hpx::execution::parallel_policy_executor; executor exec; - bool result = - hpx::parallel::execution::async_execute(exec, &test, 42).get() == - hpx::this_thread::get_id(); + bool const result = hpx::parallel::execution::async_execute( + disable_run_as_child(exec), &test, 42) + .get() == hpx::this_thread::get_id(); HPX_TEST_EQ(sync, result); } @@ -60,12 +70,12 @@ hpx::thread::id test_f(hpx::future f, int passed_through) template void test_then(bool sync) { - typedef hpx::execution::parallel_policy_executor executor; + using executor = hpx::execution::parallel_policy_executor; hpx::future f = hpx::make_ready_future(); executor exec; - bool result = + bool const result = hpx::parallel::execution::then_execute(exec, &test_f, f, 42).get() == hpx::this_thread::get_id(); @@ -73,13 +83,13 @@ void test_then(bool sync) } /////////////////////////////////////////////////////////////////////////////// -void bulk_test_s(int, hpx::thread::id tid, int passed_through) //-V813 +void bulk_test_s(int, hpx::thread::id const& tid, int passed_through) //-V813 { HPX_TEST_EQ(tid, hpx::this_thread::get_id()); HPX_TEST_EQ(passed_through, 42); } -void bulk_test_a(int, hpx::thread::id tid, int passed_through) //-V813 +void bulk_test_a(int, hpx::thread::id const& tid, int passed_through) //-V813 { HPX_TEST_NEQ(tid, hpx::this_thread::get_id()); HPX_TEST_EQ(passed_through, 42); @@ -88,7 +98,7 @@ void bulk_test_a(int, hpx::thread::id tid, int passed_through) //-V813 template void test_bulk_sync(bool sync) { - typedef hpx::execution::parallel_policy_executor executor; + using executor = hpx::execution::parallel_policy_executor; hpx::thread::id tid = hpx::this_thread::get_id(); @@ -99,17 +109,17 @@ void test_bulk_sync(bool sync) using hpx::placeholders::_2; executor exec; - hpx::parallel::execution::bulk_sync_execute(exec, + hpx::parallel::execution::bulk_sync_execute(disable_run_as_child(exec), hpx::bind(sync ? &bulk_test_s : &bulk_test_a, _1, tid, _2), v, 42); - hpx::parallel::execution::bulk_sync_execute( - exec, sync ? &bulk_test_s : &bulk_test_a, v, tid, 42); + hpx::parallel::execution::bulk_sync_execute(disable_run_as_child(exec), + sync ? &bulk_test_s : &bulk_test_a, v, tid, 42); } /////////////////////////////////////////////////////////////////////////////// template void test_bulk_async(bool sync) { - typedef hpx::execution::parallel_policy_executor executor; + using executor = hpx::execution::parallel_policy_executor; hpx::thread::id tid = hpx::this_thread::get_id(); @@ -121,16 +131,18 @@ void test_bulk_async(bool sync) executor exec; hpx::when_all( - hpx::parallel::execution::bulk_async_execute(exec, + hpx::parallel::execution::bulk_async_execute(disable_run_as_child(exec), hpx::bind(sync ? &bulk_test_s : &bulk_test_a, _1, tid, _2), v, 42)) .get(); - hpx::when_all(hpx::parallel::execution::bulk_async_execute( - exec, sync ? &bulk_test_s : &bulk_test_a, v, tid, 42)) + hpx::when_all( + hpx::parallel::execution::bulk_async_execute(disable_run_as_child(exec), + sync ? &bulk_test_s : &bulk_test_a, v, tid, 42)) .get(); } /////////////////////////////////////////////////////////////////////////////// -void bulk_test_f_s(int, hpx::shared_future f, hpx::thread::id tid, +void bulk_test_f_s(int, hpx::shared_future const& f, + hpx::thread::id const& tid, int passed_through) //-V813 { HPX_TEST(f.is_ready()); // make sure, future is ready @@ -141,7 +153,8 @@ void bulk_test_f_s(int, hpx::shared_future f, hpx::thread::id tid, HPX_TEST_EQ(passed_through, 42); } -void bulk_test_f_a(int, hpx::shared_future f, hpx::thread::id tid, +void bulk_test_f_a(int, hpx::shared_future const& f, + hpx::thread::id const& tid, int passed_through) //-V813 { HPX_TEST(f.is_ready()); // make sure, future is ready @@ -155,7 +168,7 @@ void bulk_test_f_a(int, hpx::shared_future f, hpx::thread::id tid, template void test_bulk_then(bool sync) { - typedef hpx::execution::parallel_policy_executor executor; + using executor = hpx::execution::parallel_policy_executor; hpx::thread::id tid = hpx::this_thread::get_id(); @@ -223,7 +236,7 @@ int hpx_main() int main(int argc, char* argv[]) { - // By default this test should run on all available cores + // By default, this test should run on all available cores std::vector const cfg = {"hpx.os_threads=all"}; // Initialize and run HPX diff --git a/libs/core/executors/tests/unit/shared_parallel_executor.cpp b/libs/core/executors/tests/unit/shared_parallel_executor.cpp index 35d55dee611b..457b1d26d215 100644 --- a/libs/core/executors/tests/unit/shared_parallel_executor.cpp +++ b/libs/core/executors/tests/unit/shared_parallel_executor.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 @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -27,16 +26,20 @@ struct shared_parallel_executor hpx::parallel::execution::async_execute_t, shared_parallel_executor const&, F&& f, Ts&&... ts) { - return hpx::async(std::forward(f), std::forward(ts)...); + auto policy = hpx::launch::async; + auto hint = policy.hint(); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + policy.set_hint(hint); + + return hpx::async(policy, std::forward(f), std::forward(ts)...); } }; -namespace hpx::parallel::execution { - template <> - struct is_two_way_executor : std::true_type - { - }; -} // namespace hpx::parallel::execution +template <> +struct hpx::parallel::execution::is_two_way_executor + : std::true_type +{ +}; /////////////////////////////////////////////////////////////////////////////// hpx::thread::id test(int passed_through) @@ -60,14 +63,14 @@ void test_async() executor exec; - hpx::shared_future fut = + hpx::shared_future const fut = hpx::parallel::execution::async_execute(exec, &test, 42); HPX_TEST_NEQ(fut.get(), hpx::this_thread::get_id()); } /////////////////////////////////////////////////////////////////////////////// -void bulk_test(int, hpx::thread::id tid, int passed_through) //-V813 +void bulk_test(int, hpx::thread::id const& tid, int passed_through) //-V813 { HPX_TEST_NEQ(tid, hpx::this_thread::get_id()); HPX_TEST_EQ(passed_through, 42); @@ -133,7 +136,7 @@ void test_async_void() using executor = shared_parallel_executor; executor exec; - hpx::shared_future fut = + hpx::shared_future const fut = hpx::parallel::execution::async_execute(exec, &void_test, 42); fut.get(); } @@ -154,7 +157,7 @@ int hpx_main() int main(int argc, char* argv[]) { - // By default this test should run on all available cores + // By default, this test should run on all available cores std::vector const cfg = {"hpx.os_threads=all"}; // Initialize and run HPX diff --git a/libs/core/executors/tests/unit/standalone_thread_pool_executor.cpp b/libs/core/executors/tests/unit/standalone_thread_pool_executor.cpp index 29233111906e..7250b43d2cdf 100644 --- a/libs/core/executors/tests/unit/standalone_thread_pool_executor.cpp +++ b/libs/core/executors/tests/unit/standalone_thread_pool_executor.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2019 Mikael Simberg -// Copyright (c) 2007-2017 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 @@ -72,7 +72,17 @@ void test_then(Executor& exec) } /////////////////////////////////////////////////////////////////////////////// -void bulk_test(int, hpx::thread::id tid, int passed_through) //-V813 +template +decltype(auto) disable_run_as_child(Executor&& exec) +{ + auto hint = hpx::execution::experimental::get_hint(exec); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + + return hpx::experimental::prefer(hpx::execution::experimental::with_hint, + HPX_FORWARD(Executor, exec), hint); +} + +void bulk_test(int, hpx::thread::id const& tid, int passed_through) //-V813 { HPX_TEST_NEQ(tid, hpx::this_thread::get_id()); HPX_TEST_EQ(passed_through, 42); @@ -90,8 +100,9 @@ void test_bulk_sync(Executor& exec) using hpx::placeholders::_2; hpx::parallel::execution::bulk_sync_execute( - exec, hpx::bind(&bulk_test, _1, tid, _2), v, 42); - hpx::parallel::execution::bulk_sync_execute(exec, &bulk_test, v, tid, 42); + disable_run_as_child(exec), hpx::bind(&bulk_test, _1, tid, _2), v, 42); + hpx::parallel::execution::bulk_sync_execute( + disable_run_as_child(exec), &bulk_test, v, tid, 42); } template @@ -105,16 +116,18 @@ void test_bulk_async(Executor& exec) using hpx::placeholders::_1; using hpx::placeholders::_2; - hpx::when_all(hpx::parallel::execution::bulk_async_execute( - exec, hpx::bind(&bulk_test, _1, tid, _2), v, 42)) + hpx::when_all( + hpx::parallel::execution::bulk_async_execute(disable_run_as_child(exec), + hpx::bind(&bulk_test, _1, tid, _2), v, 42)) .get(); hpx::when_all(hpx::parallel::execution::bulk_async_execute( - exec, &bulk_test, v, tid, 42)) + disable_run_as_child(exec), &bulk_test, v, tid, 42)) .get(); } /////////////////////////////////////////////////////////////////////////////// -void bulk_test_f(int, hpx::shared_future f, hpx::thread::id tid, +void bulk_test_f(int, hpx::shared_future const& f, + hpx::thread::id const& tid, int passed_through) //-V813 { HPX_TEST(f.is_ready()); // make sure, future is ready @@ -166,8 +179,8 @@ int main() hpx::threads::policies::local_priority_queue_scheduler<>; // Choose all the parameters for the thread pool and scheduler. - std::size_t const num_threads = (std::min)( - std::size_t(4), std::size_t(hpx::threads::hardware_concurrency())); + std::size_t const num_threads = (std::min)(static_cast(4), + static_cast(hpx::threads::hardware_concurrency())); std::size_t const max_cores = num_threads; hpx::threads::policies::detail::affinity_data ad{}; ad.init(num_threads, max_cores, 0, 1, 0, "core", "balanced", true); diff --git a/libs/core/futures/src/detail/execute_thread.cpp b/libs/core/futures/src/detail/execute_thread.cpp index 196cb37a1099..53d27a9b5137 100644 --- a/libs/core/futures/src/detail/execute_thread.cpp +++ b/libs/core/futures/src/detail/execute_thread.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2023 Hartmut Kaiser +// Copyright (c) 2019-2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -91,7 +91,7 @@ namespace hpx::threads::detail { bool reschedule = false; // don't directly run any threads that have started running 'normally' - // and were suspended afterwards + // and were suspended afterward if (thrdptr->runs_as_child()) { LTM_(error).format( @@ -131,8 +131,8 @@ namespace hpx::threads::detail { return false; } - // check again, making sure the state has not changed in the mean - // time + // check again, making sure the state has not changed in the + // meantime if (thrdptr->runs_as_child()) { #if defined(HPX_HAVE_APEX) diff --git a/libs/core/schedulers/include/hpx/schedulers/local_priority_queue_scheduler.hpp b/libs/core/schedulers/include/hpx/schedulers/local_priority_queue_scheduler.hpp index f2b42fe1fb84..76733e391d58 100644 --- a/libs/core/schedulers/include/hpx/schedulers/local_priority_queue_scheduler.hpp +++ b/libs/core/schedulers/include/hpx/schedulers/local_priority_queue_scheduler.hpp @@ -560,8 +560,8 @@ namespace hpx::threads::policies { num_thread = select_active_pu(num_thread); - data.schedulehint.mode = thread_schedule_hint_mode::thread; - data.schedulehint.hint = static_cast(num_thread); + data.schedulehint.schedule_hint( + static_cast(num_thread)); // now create the thread switch (data.priority) diff --git a/libs/core/schedulers/include/hpx/schedulers/local_workrequesting_scheduler.hpp b/libs/core/schedulers/include/hpx/schedulers/local_workrequesting_scheduler.hpp index a740cffde3a6..806e8946dd33 100644 --- a/libs/core/schedulers/include/hpx/schedulers/local_workrequesting_scheduler.hpp +++ b/libs/core/schedulers/include/hpx/schedulers/local_workrequesting_scheduler.hpp @@ -692,8 +692,8 @@ namespace hpx::threads::policies { num_thread = select_active_pu(num_thread); - data.schedulehint.mode = thread_schedule_hint_mode::thread; - data.schedulehint.hint = static_cast(num_thread); + data.schedulehint.schedule_hint( + static_cast(num_thread)); // now create the thread switch (data.priority) diff --git a/libs/core/threading/include/hpx/threading/thread.hpp b/libs/core/threading/include/hpx/threading/thread.hpp index d1a60a880e64..8c1943ed4c8a 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 @@ -43,7 +43,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 @@ -62,8 +62,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; @@ -75,7 +73,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))); @@ -84,7 +82,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)...)); @@ -145,15 +143,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; @@ -297,7 +295,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; @@ -352,45 +350,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 ff4e8348cb25..4f84df68aedd 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 @@ -689,8 +689,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); } @@ -700,8 +703,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 228c8de17b2a..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 // @@ -35,7 +35,7 @@ namespace hpx::threads { 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) @@ -315,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)) @@ -339,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; } @@ -418,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 diff --git a/libs/core/threading_base/src/thread_helpers.cpp b/libs/core/threading_base/src/thread_helpers.cpp index 810bf734686e..7e8a3d814310 100644 --- a/libs/core/threading_base/src/thread_helpers.cpp +++ b/libs/core/threading_base/src/thread_helpers.cpp @@ -98,6 +98,9 @@ namespace hpx::threads { void interrupt_thread(thread_id_type const& id, bool flag, error_code& ec) { + // Copy id as the original `id` may get reset by the caller + // asynchronously. + auto const keep_alive = id; if (HPX_UNLIKELY(!id)) { HPX_THROWS_IF(ec, hpx::error::null_thread_id, @@ -112,7 +115,7 @@ namespace hpx::threads { // Set thread state to pending. If the thread is currently active we do // not retry. The thread will either exit or hit an interruption_point. - set_thread_state(id, thread_schedule_state::pending, + set_thread_state(keep_alive, thread_schedule_state::pending, thread_restart_state::abort, thread_priority::normal, false, ec); } @@ -628,6 +631,7 @@ namespace hpx::this_thread { HPX_THROW_EXCEPTION(hpx::error::out_of_memory, "has_sufficient_stack_space", "Stack overflow"); } + bool const sufficient_stack_space = static_cast(remaining_stack) >= space_needed; diff --git a/libs/core/threading_base/tests/regressions/thread_stacksize_current.cpp b/libs/core/threading_base/tests/regressions/thread_stacksize_current.cpp index 28ef29897896..a879ee79e176 100644 --- a/libs/core/threading_base/tests/regressions/thread_stacksize_current.cpp +++ b/libs/core/threading_base/tests/regressions/thread_stacksize_current.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 Mikael Simberg +// Copyright (c) 2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -10,6 +11,7 @@ // thread_stacksize::minimal and thread_stacksize::maximal when a thread has been // created. +#include #include #include #include @@ -20,13 +22,23 @@ #include #include +template +decltype(auto) disable_run_as_child(Executor&& exec) +{ + auto hint = hpx::execution::experimental::get_hint(exec); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + + return hpx::experimental::prefer(hpx::execution::experimental::with_hint, + HPX_FORWARD(Executor, exec), hint); +} + void test(hpx::threads::thread_stacksize stacksize) { hpx::execution::parallel_executor exec(stacksize); hpx::execution::parallel_executor exec_current( hpx::threads::thread_stacksize::current); - hpx::async(exec, [&exec_current, stacksize]() { + hpx::async(disable_run_as_child(exec), [&exec_current, stacksize]() { // This thread should have the stack size stacksize; it has been // explicitly set in the executor. hpx::threads::thread_stacksize const self_stacksize = @@ -34,7 +46,7 @@ void test(hpx::threads::thread_stacksize stacksize) HPX_TEST_EQ(self_stacksize, stacksize); HPX_TEST_NEQ(self_stacksize, hpx::threads::thread_stacksize::current); - hpx::async(exec_current, [stacksize]() { + hpx::async(disable_run_as_child(exec_current), [stacksize]() { // This thread should also have the stack size stacksize; it has // been inherited size from the parent thread. hpx::threads::thread_stacksize const self_stacksize = diff --git a/libs/core/timed_execution/tests/unit/minimal_timed_async_executor.cpp b/libs/core/timed_execution/tests/unit/minimal_timed_async_executor.cpp index 3a12631aad5d..b6bb345a6668 100644 --- a/libs/core/timed_execution/tests/unit/minimal_timed_async_executor.cpp +++ b/libs/core/timed_execution/tests/unit/minimal_timed_async_executor.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 @@ -39,7 +39,7 @@ void apply_test(hpx::latch& l, hpx::thread::id& id, int passed_through) /////////////////////////////////////////////////////////////////////////////// template -void test_timed_apply(Executor& exec) +void test_timed_apply(Executor&& exec) { { hpx::latch l(2); @@ -73,7 +73,7 @@ void test_timed_apply(Executor& exec) } template -void test_timed_sync(Executor& exec) +void test_timed_sync(Executor&& exec) { { hpx::parallel::execution::timed_executor timed_exec( @@ -93,7 +93,7 @@ void test_timed_sync(Executor& exec) } template -void test_timed_async(Executor& exec) +void test_timed_async(Executor&& exec) { { hpx::parallel::execution::timed_executor timed_exec( @@ -124,11 +124,11 @@ std::atomic count_async_at(0); template void test_timed_executor(std::array expected) { - typedef typename hpx::traits::executor_execution_category::type - execution_category; + using execution_category = + typename hpx::traits::executor_execution_category::type; - HPX_TEST((std::is_same::value)); + HPX_TEST((std::is_same_v) ); count_sync.store(0); count_apply.store(0); @@ -154,15 +154,20 @@ void test_timed_executor(std::array expected) /////////////////////////////////////////////////////////////////////////////// struct test_async_executor1 { - typedef hpx::execution::parallel_execution_tag execution_category; + using execution_category = hpx::execution::parallel_execution_tag; template friend decltype(auto) tag_invoke(hpx::parallel::execution::async_execute_t, test_async_executor1 const&, F&& f, Ts&&... ts) { ++count_async; - return hpx::async( - hpx::launch::async, std::forward(f), std::forward(ts)...); + + auto policy = hpx::launch::async; + auto hint = policy.hint(); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + policy.set_hint(hint); + + return hpx::async(policy, std::forward(f), std::forward(ts)...); } }; @@ -175,9 +180,14 @@ struct test_timed_async_executor1 : test_async_executor1 hpx::chrono::steady_time_point const& abs_time, F&& f, Ts&&... ts) { ++count_async_at; + + auto policy = hpx::launch::async; + auto hint = policy.hint(); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + policy.set_hint(hint); + hpx::this_thread::sleep_until(abs_time); - return hpx::async( - hpx::launch::async, std::forward(f), std::forward(ts)...); + return hpx::async(policy, std::forward(f), std::forward(ts)...); } }; @@ -200,8 +210,13 @@ struct test_timed_async_executor2 : test_async_executor1 test_timed_async_executor2 const&, F&& f, Ts&&... ts) { ++count_sync; - return hpx::async( - hpx::launch::async, std::forward(f), std::forward(ts)...) + + auto policy = hpx::launch::async; + auto hint = policy.hint(); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + policy.set_hint(hint); + + return hpx::async(policy, std::forward(f), std::forward(ts)...) .get(); } }; @@ -216,8 +231,13 @@ struct test_timed_async_executor3 : test_timed_async_executor2 { ++count_sync_at; hpx::this_thread::sleep_until(abs_time); - return hpx::async( - hpx::launch::async, std::forward(f), std::forward(ts)...) + + auto policy = hpx::launch::async; + auto hint = policy.hint(); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + policy.set_hint(hint); + + return hpx::async(policy, std::forward(f), std::forward(ts)...) .get(); } }; @@ -285,7 +305,7 @@ int hpx_main() int main(int argc, char* argv[]) { - // By default this test should run on all available cores + // By default, this test should run on all available cores std::vector const cfg = {"hpx.os_threads=all"}; // Initialize and run HPX diff --git a/libs/full/performance_counters/include/hpx/performance_counters/counter_interface.hpp b/libs/full/performance_counters/include/hpx/performance_counters/counter_interface.hpp index 8a39be09115a..240a85a189db 100644 --- a/libs/full/performance_counters/include/hpx/performance_counters/counter_interface.hpp +++ b/libs/full/performance_counters/include/hpx/performance_counters/counter_interface.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Hartmut Kaiser +// Copyright (c) 2021-2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -16,10 +16,10 @@ namespace hpx { namespace performance_counters { /////////////////////////////////////////////////////////////////////////// HPX_EXPORT hpx::future create_performance_counter_async( - id_type target_id, counter_info const& info); + id_type const& target_id, counter_info const& info); - inline id_type create_performance_counter( - id_type target_id, counter_info const& info, error_code& ec = throws) + inline id_type create_performance_counter(id_type const& target_id, + counter_info const& info, error_code& ec = throws) { return create_performance_counter_async(target_id, info).get(ec); } diff --git a/libs/full/performance_counters/include/hpx/performance_counters/detail/counter_interface_functions.hpp b/libs/full/performance_counters/include/hpx/performance_counters/detail/counter_interface_functions.hpp index 89e0d417bbed..f552df63374b 100644 --- a/libs/full/performance_counters/include/hpx/performance_counters/detail/counter_interface_functions.hpp +++ b/libs/full/performance_counters/include/hpx/performance_counters/detail/counter_interface_functions.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Hartmut Kaiser +// Copyright (c) 2021-2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -11,9 +11,9 @@ #include #include -namespace hpx { namespace performance_counters { namespace detail { +namespace hpx::performance_counters::detail { /////////////////////////////////////////////////////////////////////////// extern HPX_EXPORT hpx::future (*create_performance_counter_async)( - id_type target_id, counter_info const& info); -}}} // namespace hpx::performance_counters::detail + id_type const& target_id, counter_info const& info); +} // namespace hpx::performance_counters::detail diff --git a/libs/full/performance_counters/src/counter_interface.cpp b/libs/full/performance_counters/src/counter_interface.cpp index 736170ad1398..dfb2719af186 100644 --- a/libs/full/performance_counters/src/counter_interface.cpp +++ b/libs/full/performance_counters/src/counter_interface.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Hartmut Kaiser +// Copyright (c) 2021-2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -11,12 +11,12 @@ #include #include -namespace hpx { namespace performance_counters { +namespace hpx::performance_counters { /////////////////////////////////////////////////////////////////////////// hpx::future create_performance_counter_async( - id_type target_id, counter_info const& info) + id_type const& target_id, counter_info const& info) { return detail::create_performance_counter_async(target_id, info); } -}} // namespace hpx::performance_counters +} // namespace hpx::performance_counters diff --git a/libs/full/performance_counters/src/counters.cpp b/libs/full/performance_counters/src/counters.cpp index 2fefc351b9ab..f7388592b43d 100644 --- a/libs/full/performance_counters/src/counters.cpp +++ b/libs/full/performance_counters/src/counters.cpp @@ -1199,7 +1199,7 @@ namespace hpx::performance_counters { if (ec) return {}; - // Take target locality from base counter if if this is an + // Take target locality from base counter if this is an // aggregating counter (the instance name is a base counter). if (p.parentinstance_is_basename_) { diff --git a/libs/full/performance_counters/src/detail/counter_interface_functions.cpp b/libs/full/performance_counters/src/detail/counter_interface_functions.cpp index cb76bdf1c6d9..447a3537a4f9 100644 --- a/libs/full/performance_counters/src/detail/counter_interface_functions.cpp +++ b/libs/full/performance_counters/src/detail/counter_interface_functions.cpp @@ -1,17 +1,16 @@ -// Copyright (c) 2021 Hartmut Kaiser +// Copyright (c) 2021-2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#include #include #include #include #include -namespace hpx { namespace performance_counters { namespace detail { +namespace hpx::performance_counters::detail { hpx::future (*create_performance_counter_async)( - id_type target_id, counter_info const& info) = nullptr; -}}} // namespace hpx::performance_counters::detail + id_type const& target_id, counter_info const& info) = nullptr; +} // namespace hpx::performance_counters::detail diff --git a/libs/full/runtime_distributed/include/hpx/runtime_distributed/stubs/runtime_support.hpp b/libs/full/runtime_distributed/include/hpx/runtime_distributed/stubs/runtime_support.hpp index 673d7c864812..68e597659df2 100644 --- a/libs/full/runtime_distributed/include/hpx/runtime_distributed/stubs/runtime_support.hpp +++ b/libs/full/runtime_distributed/include/hpx/runtime_distributed/stubs/runtime_support.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2021 Hartmut Kaiser +// Copyright (c) 2007-2024 Hartmut Kaiser // Copyright (c) 2011 Bryce Lelbach // // SPDX-License-Identifier: BSL-1.0 @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -25,7 +24,7 @@ #include #include -namespace hpx { namespace components { namespace stubs { +namespace hpx::components::stubs { /////////////////////////////////////////////////////////////////////////// // The \a runtime_support class is the client side representation of a @@ -47,12 +46,10 @@ namespace hpx { namespace components { namespace stubs { "stubs::runtime_support::create_component_async", "The id passed as the first argument is not representing" " a locality"); - return hpx::make_ready_future(hpx::invalid_id); } - typedef server::create_component_action::type...> - action_type; + using action_type = + server::create_component_action...>; return hpx::async(gid, HPX_FORWARD(Ts, vs)...); } @@ -75,9 +72,8 @@ namespace hpx { namespace components { namespace stubs { bulk_create_component_colocated_async( hpx::id_type const& gid, std::size_t count, Ts&&... vs) { - typedef server::bulk_create_component_action::type...> - action_type; + using action_type = server::bulk_create_component_action...>; return hpx::detail::async_colocated( gid, count, HPX_FORWARD(Ts, vs)...); @@ -108,12 +104,10 @@ namespace hpx { namespace components { namespace stubs { "stubs::runtime_support::bulk_create_component_async", "The id passed as the first argument is not representing" " a locality"); - return hpx::make_ready_future(std::vector()); } - typedef server::bulk_create_component_action::type...> - action_type; + using action_type = server::bulk_create_component_action...>; return hpx::async(gid, count, HPX_FORWARD(Ts, vs)...); } @@ -136,9 +130,8 @@ namespace hpx { namespace components { namespace stubs { static hpx::future create_component_colocated_async( hpx::id_type const& gid, Ts&&... vs) { - typedef server::create_component_action::type...> - action_type; + using action_type = + server::create_component_action...>; return hpx::detail::async_colocated( gid, HPX_FORWARD(Ts, vs)...); } @@ -167,11 +160,9 @@ namespace hpx { namespace components { namespace stubs { "stubs::runtime_support::copy_create_component_async", "The id passed as the first argument is not representing" " a locality"); - return hpx::make_ready_future(hpx::invalid_id); } - typedef typename server::copy_create_component_action - action_type; + using action_type = server::copy_create_component_action; return hpx::async(gid, p, local_op); } @@ -198,11 +189,10 @@ namespace hpx { namespace components { namespace stubs { "stubs::runtime_support::migrate_component_async", "The id passed as the first argument is not representing" " a locality"); - return hpx::make_ready_future(hpx::invalid_id); } - typedef typename server::migrate_component_here_action - action_type; + using action_type = + server::migrate_component_here_action; return hpx::async(target_locality, p, to_migrate); } @@ -211,8 +201,8 @@ namespace hpx { namespace components { namespace stubs { DistPolicy const& policy, std::shared_ptr const& p, hpx::id_type const& to_migrate) { - typedef typename server::migrate_component_here_action - action_type; + using action_type = + server::migrate_component_here_action; return hpx::async(policy, p, to_migrate); } @@ -269,9 +259,10 @@ namespace hpx { namespace components { namespace stubs { /////////////////////////////////////////////////////////////////////// static hpx::future create_performance_counter_async( - hpx::id_type targetgid, + hpx::id_type const& targetgid, performance_counters::counter_info const& info); - static hpx::id_type create_performance_counter(hpx::id_type targetgid, + static hpx::id_type create_performance_counter( + hpx::id_type const& targetgid, performance_counters::counter_info const& info, error_code& ec = throws); @@ -287,4 +278,4 @@ namespace hpx { namespace components { namespace stubs { hpx::id_type const& target, naming::gid_type const& gid, parcelset::endpoints_type const& endpoints); }; -}}} // namespace hpx::components::stubs +} // namespace hpx::components::stubs diff --git a/libs/full/runtime_distributed/src/runtime_support.cpp b/libs/full/runtime_distributed/src/runtime_support.cpp index 124ced88a2ca..c18522630b3c 100644 --- a/libs/full/runtime_distributed/src/runtime_support.cpp +++ b/libs/full/runtime_distributed/src/runtime_support.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2021 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 @@ -17,7 +17,7 @@ HPX_PLUGIN_EXPORT_LIST(HPX_PLUGIN_COMPONENT_PREFIX, factory) HPX_REGISTER_REGISTRY_MODULE() -namespace hpx { namespace components { namespace server { +namespace hpx::components::server { void runtime_support::add_pre_startup_function(startup_function_type f) { @@ -54,9 +54,9 @@ namespace hpx { namespace components { namespace server { shutdown_functions_.push_back(HPX_MOVE(f)); } } -}}} // namespace hpx::components::server +} // namespace hpx::components::server -namespace hpx { namespace agas { namespace detail { namespace impl { +namespace hpx::agas::detail::impl { /// \brief Invoke an asynchronous garbage collection step on the given target /// locality. @@ -90,9 +90,9 @@ namespace hpx { namespace agas { namespace detail { namespace impl { ec = make_error_code(e.get_error(), e.what()); } } -}}}} // namespace hpx::agas::detail::impl +} // namespace hpx::agas::detail::impl -namespace hpx { namespace agas { +namespace hpx::agas { // initialize AGAS interface function pointers in components_base module struct HPX_EXPORT runtime_components_init_interface_functions @@ -111,9 +111,9 @@ namespace hpx { namespace agas { runtime_components_init_; return runtime_components_init_; } -}} // namespace hpx::agas +} // namespace hpx::agas -namespace hpx { namespace components { +namespace hpx::components { // some compilers try to invoke this function, even if it's actually not // needed @@ -140,4 +140,4 @@ namespace hpx { namespace components { static counter_interface_functions counter_init_; return counter_init_; } -}} // namespace hpx::components +} // namespace hpx::components diff --git a/libs/full/runtime_distributed/src/server/runtime_support_server.cpp b/libs/full/runtime_distributed/src/server/runtime_support_server.cpp index 03526483d60f..c5098b9c0241 100644 --- a/libs/full/runtime_distributed/src/server/runtime_support_server.cpp +++ b/libs/full/runtime_distributed/src/server/runtime_support_server.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -307,8 +308,11 @@ namespace hpx { namespace components { namespace server { } // We need the lock here to ensure the mutual exclusion of - // hpx::latch::count_down and and hpx::latch::~latch - std::lock_guard l(dijkstra_mtx_); + // hpx::latch::count_down and hpx::latch::~latch + std::unique_lock l(dijkstra_mtx_); + [[maybe_unused]] hpx::util::ignore_while_checking< + std::lock_guard> + il(&l); dijkstra_cond_->count_down(1); return; } @@ -397,8 +401,11 @@ namespace hpx { namespace components { namespace server { } while (dijkstra_color_); // We need the lock here to ensure the mutual exclusion of - // hpx::latch::count_down and and hpx::latch::~latch - std::lock_guard l(dijkstra_mtx_); + // hpx::latch::count_down and hpx::latch::~latch + std::unique_lock l(dijkstra_mtx_); + [[maybe_unused]] hpx::util::ignore_while_checking< + std::lock_guard> + il(&l); dijkstra_cond_.reset(); } @@ -861,7 +868,7 @@ namespace hpx { namespace components { namespace server { // working around non-copy-ability of packaged_task struct indirect_packaged_task { - typedef hpx::packaged_task packaged_task_type; + using packaged_task_type = hpx::packaged_task; indirect_packaged_task() : pt(std::make_shared([]() {})) @@ -894,8 +901,8 @@ namespace hpx { namespace components { namespace server { std::vector locality_ids = find_remote_localities(); - typedef server::runtime_support::remove_from_connection_cache_action - action_type; + using action_type = + server::runtime_support::remove_from_connection_cache_action; std::vector> callbacks; callbacks.reserve(locality_ids.size()); @@ -928,8 +935,8 @@ namespace hpx { namespace components { namespace server { if (rtd == nullptr) return; - typedef server::runtime_support::remove_from_connection_cache_action - action_type; + using action_type = + server::runtime_support::remove_from_connection_cache_action; action_type act; indirect_packaged_task ipt; @@ -953,7 +960,7 @@ namespace hpx { namespace components { namespace server { char const* message_handler_type, char const* action, error_code& ec) { // locate the factory for the requested plugin type - typedef std::unique_lock plugin_map_scoped_lock; + using plugin_map_scoped_lock = std::unique_lock; plugin_map_scoped_lock l(p_mtx_); plugin_map_type::const_iterator it = @@ -1015,7 +1022,7 @@ namespace hpx { namespace components { namespace server { std::size_t interval, error_code& ec) { // locate the factory for the requested plugin type - typedef std::unique_lock plugin_map_scoped_lock; + using plugin_map_scoped_lock = std::unique_lock; plugin_map_scoped_lock l(p_mtx_); plugin_map_type::const_iterator it = @@ -1076,7 +1083,7 @@ namespace hpx { namespace components { namespace server { serialization::binary_filter* next_filter, error_code& ec) { // locate the factory for the requested plugin type - typedef std::unique_lock plugin_map_scoped_lock; + using plugin_map_scoped_lock = std::unique_lock; plugin_map_scoped_lock l(p_mtx_); plugin_map_type::const_iterator it = plugins_.find(binary_filter_type); @@ -1224,7 +1231,7 @@ namespace hpx { namespace components { namespace server { } util::section::section_map const& s = (*sec).get_sections(); - typedef util::section::section_map::const_iterator iterator; + using iterator = util::section::section_map::const_iterator; iterator end = s.end(); for (iterator i = s.begin(); i != end; ++i) { @@ -1725,7 +1732,7 @@ namespace hpx { namespace components { namespace server { } util::section::section_map const& s = (*sec).get_sections(); - typedef util::section::section_map::const_iterator iterator; + using iterator = util::section::section_map::const_iterator; iterator end = s.end(); for (iterator i = s.begin(); i != end; ++i) { diff --git a/libs/full/runtime_distributed/src/stubs/runtime_support_stubs.cpp b/libs/full/runtime_distributed/src/stubs/runtime_support_stubs.cpp index bd752703169e..e7dd24987bb4 100644 --- a/libs/full/runtime_distributed/src/stubs/runtime_support_stubs.cpp +++ b/libs/full/runtime_distributed/src/stubs/runtime_support_stubs.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2016 Hartmut Kaiser +// Copyright (c) 2007-2024 Hartmut Kaiser // Copyright (c) 2011 Bryce Lelbach // // SPDX-License-Identifier: BSL-1.0 @@ -19,24 +19,32 @@ #include #include #include -#include #include #include #include -#include -namespace hpx { namespace components { namespace stubs { +namespace hpx::components::stubs { + + template + auto disable_run_as_child(Policy&& p) + { + auto policy = p; + auto hint = policy.get_hint(); + hint.runs_as_child_mode(hpx::threads::thread_execution_hint::none); + policy.set_hint(hint); + return policy; + } hpx::future runtime_support::load_components_async( - hpx::id_type const& gid) + [[maybe_unused]] hpx::id_type const& gid) { #if !defined(HPX_COMPUTE_DEVICE_CODE) - typedef server::runtime_support::load_components_action action_type; - return hpx::async(gid); + using action_type = server::runtime_support::load_components_action; + return hpx::async( + disable_run_as_child(hpx::launch::async), gid); #else HPX_ASSERT(false); - HPX_UNUSED(gid); return hpx::make_ready_future(0); #endif } @@ -47,16 +55,17 @@ namespace hpx { namespace components { namespace stubs { } hpx::future runtime_support::call_startup_functions_async( - hpx::id_type const& gid, bool pre_startup) + [[maybe_unused]] hpx::id_type const& gid, + [[maybe_unused]] bool pre_startup) { #if !defined(HPX_COMPUTE_DEVICE_CODE) - typedef server::runtime_support::call_startup_functions_action - action_type; - return hpx::async(gid, pre_startup); + using action_type = + server::runtime_support::call_startup_functions_action; + + return hpx::async( + disable_run_as_child(hpx::launch::async), gid, pre_startup); #else HPX_ASSERT(false); - HPX_UNUSED(gid); - HPX_UNUSED(pre_startup); return ::hpx::make_ready_future(); #endif } @@ -69,13 +78,14 @@ namespace hpx { namespace components { namespace stubs { /// \brief Shutdown the given runtime system hpx::future runtime_support::shutdown_async( - hpx::id_type const& targetgid, double timeout) + [[maybe_unused]] hpx::id_type const& targetgid, + [[maybe_unused]] double timeout) { #if !defined(HPX_COMPUTE_DEVICE_CODE) // Create a promise directly and execute the required action. // This action has implemented special response handling as the // back-parcel is sent explicitly (and synchronously). - typedef server::runtime_support::shutdown_action action_type; + using action_type = server::runtime_support::shutdown_action; hpx::distributed::promise value; auto f = value.get_future(); @@ -88,8 +98,6 @@ namespace hpx { namespace components { namespace stubs { return f; #else HPX_ASSERT(false); - HPX_UNUSED(targetgid); - HPX_UNUSED(timeout); return ::hpx::make_ready_future(); #endif } @@ -104,19 +112,18 @@ namespace hpx { namespace components { namespace stubs { /// \brief Shutdown the runtime systems of all localities void runtime_support::shutdown_all( - hpx::id_type const& targetgid, double timeout) + [[maybe_unused]] hpx::id_type const& targetgid, + [[maybe_unused]] double timeout) { #if !defined(HPX_COMPUTE_DEVICE_CODE) hpx::post( targetgid, timeout); #else HPX_ASSERT(false); - HPX_UNUSED(targetgid); - HPX_UNUSED(timeout); #endif } - void runtime_support::shutdown_all(double timeout) + void runtime_support::shutdown_all([[maybe_unused]] double timeout) { #if !defined(HPX_COMPUTE_DEVICE_CODE) hpx::post( @@ -126,7 +133,6 @@ namespace hpx { namespace components { namespace stubs { timeout); #else HPX_ASSERT(false); - HPX_UNUSED(timeout); #endif } @@ -134,13 +140,13 @@ namespace hpx { namespace components { namespace stubs { /// \brief Retrieve configuration information /// \brief Terminate the given runtime system hpx::future runtime_support::terminate_async( - hpx::id_type const& targetgid) + [[maybe_unused]] hpx::id_type const& targetgid) { #if !defined(HPX_COMPUTE_DEVICE_CODE) // Create a future directly and execute the required action. // This action has implemented special response handling as the // back-parcel is sent explicitly (and synchronously). - typedef server::runtime_support::terminate_action action_type; + using action_type = server::runtime_support::terminate_action; hpx::distributed::promise value; auto f = value.get_future(); @@ -149,7 +155,6 @@ namespace hpx { namespace components { namespace stubs { return f; #else HPX_ASSERT(false); - HPX_UNUSED(targetgid); return ::hpx::make_ready_future(); #endif } @@ -162,13 +167,13 @@ namespace hpx { namespace components { namespace stubs { } /// \brief Terminate the runtime systems of all localities - void runtime_support::terminate_all(hpx::id_type const& targetgid) + void runtime_support::terminate_all( + [[maybe_unused]] hpx::id_type const& targetgid) { #if !defined(HPX_COMPUTE_DEVICE_CODE) hpx::post(targetgid); #else HPX_ASSERT(false); - HPX_UNUSED(targetgid); #endif } @@ -185,44 +190,46 @@ namespace hpx { namespace components { namespace stubs { /////////////////////////////////////////////////////////////////////// void runtime_support::garbage_collect_non_blocking( - hpx::id_type const& targetgid) + [[maybe_unused]] hpx::id_type const& targetgid) { #if !defined(HPX_COMPUTE_DEVICE_CODE) - typedef server::runtime_support::garbage_collect_action action_type; + using action_type = server::runtime_support::garbage_collect_action; hpx::post(targetgid); #else HPX_ASSERT(false); - HPX_UNUSED(targetgid); #endif } hpx::future runtime_support::garbage_collect_async( - hpx::id_type const& targetgid) + [[maybe_unused]] hpx::id_type const& targetgid) { #if !defined(HPX_COMPUTE_DEVICE_CODE) - typedef server::runtime_support::garbage_collect_action action_type; - return hpx::async(targetgid); + using action_type = server::runtime_support::garbage_collect_action; + return hpx::async( + disable_run_as_child(hpx::launch::async), targetgid); #else HPX_ASSERT(false); - HPX_UNUSED(targetgid); return ::hpx::make_ready_future(); #endif } - void runtime_support::garbage_collect(hpx::id_type const& targetgid) + void runtime_support::garbage_collect( + [[maybe_unused]] hpx::id_type const& targetgid) { #if !defined(HPX_COMPUTE_DEVICE_CODE) - typedef server::runtime_support::garbage_collect_action action_type; - hpx::async(targetgid).get(); + using action_type = server::runtime_support::garbage_collect_action; + hpx::async( + disable_run_as_child(hpx::launch::async), targetgid) + .get(); #else HPX_ASSERT(false); - HPX_UNUSED(targetgid); #endif } /////////////////////////////////////////////////////////////////////// hpx::future runtime_support::create_performance_counter_async( - hpx::id_type targetgid, performance_counters::counter_info const& info) + [[maybe_unused]] hpx::id_type const& targetgid, + [[maybe_unused]] performance_counters::counter_info const& info) { #if !defined(HPX_COMPUTE_DEVICE_CODE) if (!naming::is_locality(targetgid)) @@ -231,23 +238,21 @@ namespace hpx { namespace components { namespace stubs { "stubs::runtime_support::create_performance_counter_async", "The id passed as the first argument is not representing" " a locality"); - return make_ready_future(hpx::invalid_id); } - typedef server::runtime_support::create_performance_counter_action - action_type; - return hpx::async(targetgid, info); + using action_type = + server::runtime_support::create_performance_counter_action; + return hpx::async( + disable_run_as_child(hpx::launch::async), targetgid, info); #else HPX_ASSERT(false); - HPX_UNUSED(targetgid); - HPX_UNUSED(info); return ::hpx::make_ready_future(hpx::invalid_id); #endif } hpx::id_type runtime_support::create_performance_counter( - hpx::id_type targetgid, performance_counters::counter_info const& info, - error_code& ec) + hpx::id_type const& targetgid, + performance_counters::counter_info const& info, error_code& ec) { return create_performance_counter_async(targetgid, info).get(ec); } @@ -255,17 +260,17 @@ namespace hpx { namespace components { namespace stubs { /////////////////////////////////////////////////////////////////////// /// \brief Retrieve configuration information hpx::future runtime_support::get_config_async( - hpx::id_type const& targetgid) + [[maybe_unused]] hpx::id_type const& targetgid) { #if !defined(HPX_COMPUTE_DEVICE_CODE) // Create a future, execute the required action, // we simply return the initialized future, the caller needs // to call get() on the return value to obtain the result - typedef server::runtime_support::get_config_action action_type; - return hpx::async(targetgid); + using action_type = server::runtime_support::get_config_action; + return hpx::async( + disable_run_as_child(hpx::launch::async), targetgid); #else HPX_ASSERT(false); - HPX_UNUSED(targetgid); return ::hpx::make_ready_future(util::section{}); #endif } @@ -280,18 +285,16 @@ namespace hpx { namespace components { namespace stubs { /////////////////////////////////////////////////////////////////////// void runtime_support::remove_from_connection_cache_async( - hpx::id_type const& target, naming::gid_type const& gid, - parcelset::endpoints_type const& endpoints) + [[maybe_unused]] hpx::id_type const& target, + [[maybe_unused]] naming::gid_type const& gid, + [[maybe_unused]] parcelset::endpoints_type const& endpoints) { #if !defined(HPX_COMPUTE_DEVICE_CODE) - typedef server::runtime_support::remove_from_connection_cache_action - action_type; + using action_type = + server::runtime_support::remove_from_connection_cache_action; hpx::post(target, gid, endpoints); #else HPX_ASSERT(false); - HPX_UNUSED(target); - HPX_UNUSED(gid); - HPX_UNUSED(endpoints); #endif } -}}} // namespace hpx::components::stubs +} // namespace hpx::components::stubs diff --git a/tests/regressions/threads/main_thread_exit_callbacks.cpp b/tests/regressions/threads/main_thread_exit_callbacks.cpp index 4a6451236cd0..629fa256a9bd 100644 --- a/tests/regressions/threads/main_thread_exit_callbacks.cpp +++ b/tests/regressions/threads/main_thread_exit_callbacks.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2023 Panos Syskakis +// Copyright (c) 2024 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -18,7 +19,7 @@ int hpx_main() { hpx::threads::thread_id_type id = hpx::threads::get_self_id(); hpx::threads::add_thread_exit_callback(id, [id]() { - hpx::threads::thread_id_type id1 = hpx::threads::get_self_id(); + hpx::threads::thread_id_type const id1 = hpx::threads::get_self_id(); HPX_TEST_EQ(id1, id); callback_called = true;