From c88ed72047ed78a66a2726d74d24f24dd2e69b7e Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Mon, 6 Apr 2026 15:33:39 -0700 Subject: [PATCH 1/6] fix a circular dependence of `static_thread_pool.hpp` fixes #1990 --- examples/benchmark/common.hpp | 2 + include/exec/sequence/iterate.hpp | 9 +++- include/exec/sequence_senders.hpp | 24 +++++++--- include/exec/static_thread_pool.hpp | 48 ++++++++++---------- include/exec/trampoline_scheduler.hpp | 9 +++- include/stdexec/__detail/__execution_fwd.hpp | 3 +- 6 files changed, 63 insertions(+), 32 deletions(-) diff --git a/examples/benchmark/common.hpp b/examples/benchmark/common.hpp index f80cbef74..30ebc10f4 100644 --- a/examples/benchmark/common.hpp +++ b/examples/benchmark/common.hpp @@ -14,6 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include + #include #include diff --git a/include/exec/sequence/iterate.hpp b/include/exec/sequence/iterate.hpp index 6f397600b..907d6fca8 100644 --- a/include/exec/sequence/iterate.hpp +++ b/include/exec/sequence/iterate.hpp @@ -20,8 +20,15 @@ #if !STDEXEC_NO_STDCPP_RANGES() +# include "../../stdexec/__detail/__concepts.hpp" +# include "../../stdexec/__detail/__connect.hpp" +# include "../../stdexec/__detail/__env.hpp" # include "../../stdexec/__detail/__optional.hpp" -# include "../../stdexec/execution.hpp" +# include "../../stdexec/__detail/__operation_states.hpp" +# include "../../stdexec/__detail/__receivers.hpp" +# include "../../stdexec/__detail/__schedulers.hpp" +# include "../../stdexec/__detail/__sender_concepts.hpp" +# include "../../stdexec/__detail/__execution_fwd.hpp" # include "../detail/basic_sequence.hpp" # include "../sender_for.hpp" diff --git a/include/exec/sequence_senders.hpp b/include/exec/sequence_senders.hpp index 4296777ac..7a396f00c 100644 --- a/include/exec/sequence_senders.hpp +++ b/include/exec/sequence_senders.hpp @@ -16,11 +16,25 @@ */ #pragma once -#include "../stdexec/execution.hpp" +#include "../stdexec/__detail/__execution_fwd.hpp" +#include "../stdexec/__detail/__completion_signatures.hpp" #include "../stdexec/__detail/__concepts.hpp" +#include "../stdexec/__detail/__connect.hpp" +#include "../stdexec/__detail/__debug.hpp" #include "../stdexec/__detail/__diagnostics.hpp" +#include "../stdexec/__detail/__env.hpp" +#include "../stdexec/__detail/__just.hpp" #include "../stdexec/__detail/__meta.hpp" +#include "../stdexec/__detail/__receivers.hpp" +#include "../stdexec/__detail/__senders.hpp" +#include "../stdexec/__detail/__stop_token.hpp" +#include "../stdexec/__detail/__tag_invoke.hpp" +#include "../stdexec/__detail/__transform_sender.hpp" +#include "../stdexec/__detail/__type_traits.hpp" +#include "../stdexec/__detail/__utility.hpp" +#include "../stdexec/stop_token.hpp" + #include "completion_signatures.hpp" STDEXEC_PRAGMA_PUSH() @@ -565,7 +579,7 @@ namespace experimental::execution struct __sequence_type_check_failure // : STDEXEC::__compile_time_error<__sequence_type_check_failure<_Data, _What...>> { - static_assert(std::is_nothrow_move_constructible_v<_Data>, + static_assert(STDEXEC::__nothrow_move_constructible<_Data>, "The data member of sender_type_check_failure must be nothrow move " "constructible."); @@ -783,11 +797,9 @@ namespace experimental::execution static_assert(sequence_sender<_Sequence> || has_sequence_item_types<_Sequence, env_of_t<_Receiver>>, - "The first argument to " STDEXEC_PP_STRINGIZE(STDEXEC) "::subscribe must be " - "a sequence sender"); + "The first argument to exec::subscribe must be a sequence sender"); static_assert(receiver<_Receiver>, - "The second argument to " STDEXEC_PP_STRINGIZE(STDEXEC) "::subscribe must be " - "a receiver"); + "The second argument to exec::subscribe must be a receiver"); #if STDEXEC_ENABLE_EXTRA_TYPE_CHECKING() static_assert(__type_check_arguments<__tfx_seq_t, _Receiver>()); #endif diff --git a/include/exec/static_thread_pool.hpp b/include/exec/static_thread_pool.hpp index 9143279aa..cbb4b4a84 100644 --- a/include/exec/static_thread_pool.hpp +++ b/include/exec/static_thread_pool.hpp @@ -18,11 +18,23 @@ #pragma once #include "../stdexec/__detail/__atomic.hpp" +#include "../stdexec/__detail/__bulk.hpp" +#include "../stdexec/__detail/__completion_signatures.hpp" +#include "../stdexec/__detail/__concepts.hpp" #include "../stdexec/__detail/__config.hpp" +#include "../stdexec/__detail/__domain.hpp" +#include "../stdexec/__detail/__execution_fwd.hpp" +#include "../stdexec/__detail/__execution_legacy.hpp" +#include "../stdexec/__detail/__get_completion_signatures.hpp" #include "../stdexec/__detail/__intrusive_queue.hpp" #include "../stdexec/__detail/__manual_lifetime.hpp" // IWYU pragma: keep #include "../stdexec/__detail/__meta.hpp" // IWYU pragma: keep -#include "../stdexec/execution.hpp" +#include "../stdexec/__detail/__receivers.hpp" +#include "../stdexec/__detail/__transform_completion_signatures.hpp" +#include "../stdexec/__detail/__tuple.hpp" +#include "../stdexec/__detail/__type_traits.hpp" +#include "../stdexec/__detail/__variant.hpp" + #include "detail/atomic_intrusive_queue.hpp" #include "detail/bwos_lifo_queue.hpp" #include "detail/numa.hpp" @@ -37,7 +49,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -1416,12 +1430,10 @@ namespace experimental::execution } }; - using variant_t = __value_types_of_t, - __q<__decayed_std_tuple>, - __q<__nullable_std_variant>>; + using variant_t = + __value_types_of_t, __q<__decayed_tuple>, __q<__variant>>; - variant_t data_; + variant_t data_{STDEXEC::__no_init}; _static_thread_pool& pool_; Receiver rcvr_; Shape shape_; @@ -1440,7 +1452,7 @@ namespace experimental::execution if constexpr (Parallelize) { return static_cast( - (std::min) (shape_, static_cast(pool_.available_parallelism()))); + __umin({shape_, static_cast(pool_.available_parallelism())})); } else { @@ -1451,19 +1463,8 @@ namespace experimental::execution template void apply(F f) { - std::visit( - [&](Tuple& tupl) -> void - { - if constexpr (__std::same_as) - { - STDEXEC_TERMINATE(); - } - else - { - std::apply([&](auto&... args) -> void { f(args...); }, tupl); - } - }, - data_); + STDEXEC_ASSERT(!data_.__is_valueless()); + __visit([&](auto& tupl) -> void { __apply(std::move(f), tupl); }, data_); } //! Construct from a pool, receiver, shape, and function. @@ -1501,7 +1502,7 @@ namespace experimental::execution template void set_value(As&&... as) noexcept { - using tuple_t = __decayed_std_tuple; + using tuple_t = __decayed_tuple; shared_state& state = shared_state_; @@ -1514,6 +1515,7 @@ namespace experimental::execution if constexpr (MayThrow) { STDEXEC::set_error(std::move(state.rcvr_), std::current_exception()); + return; } } @@ -1523,7 +1525,7 @@ namespace experimental::execution } else { - state.apply([&](auto&... args) + state.apply([&](auto&... args) noexcept -> void { STDEXEC::set_value(std::move(state.rcvr_), std::move(args)...); }); } } @@ -1761,7 +1763,7 @@ namespace experimental::execution std::size_t nthreads = this->pool_.available_parallelism(); bwos_params params = this->pool_.params(); std::size_t local_size = params.blockSize * params.numBlocks; - std::size_t chunk_size = (std::min) (size / nthreads, local_size * nthreads); + std::size_t chunk_size = __umin({size / nthreads, local_size * nthreads}); auto& remote_queue = *this->pool_.get_remote_queue(); auto it = std::ranges::begin(this->range_); std::size_t i0 = 0; diff --git a/include/exec/trampoline_scheduler.hpp b/include/exec/trampoline_scheduler.hpp index 250ddaaa5..9972f8b62 100644 --- a/include/exec/trampoline_scheduler.hpp +++ b/include/exec/trampoline_scheduler.hpp @@ -16,7 +16,14 @@ */ #pragma once -#include "../stdexec/execution.hpp" +#include "../stdexec/__detail/__execution_fwd.hpp" + +#include "../stdexec/__detail/__concepts.hpp" +#include "../stdexec/__detail/__domain.hpp" +#include "../stdexec/__detail/__env.hpp" +#include "../stdexec/__detail/__receivers.hpp" +#include "../stdexec/stop_token.hpp" + #include "completion_behavior.hpp" #include diff --git a/include/stdexec/__detail/__execution_fwd.hpp b/include/stdexec/__detail/__execution_fwd.hpp index 67689e6fc..38e8408c7 100644 --- a/include/stdexec/__detail/__execution_fwd.hpp +++ b/include/stdexec/__detail/__execution_fwd.hpp @@ -15,8 +15,9 @@ */ #pragma once -#include "__concepts.hpp" #include "__config.hpp" // IWYU pragma: export + +#include "__concepts.hpp" #include "__meta.hpp" #include "__type_traits.hpp" #include "__utility.hpp" From c4f4e55dad7730cbbd12cd5f89b30ea734a98f65 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Mon, 6 Apr 2026 16:05:41 -0700 Subject: [PATCH 2/6] fix includes of `thread_pool_base.hpp` --- include/exec/thread_pool_base.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/exec/thread_pool_base.hpp b/include/exec/thread_pool_base.hpp index 824a53e55..a0824f9cd 100644 --- a/include/exec/thread_pool_base.hpp +++ b/include/exec/thread_pool_base.hpp @@ -17,9 +17,29 @@ */ #pragma once + +#include "../stdexec/__detail/__execution_fwd.hpp" + +#include "../stdexec/__detail/__connect.hpp" +#include "../stdexec/__detail/__env.hpp" +#include "../stdexec/__detail/__meta.hpp" +#include "../stdexec/__detail/__operation_states.hpp" +#include "../stdexec/__detail/__receivers.hpp" +#include "../stdexec/__detail/__schedulers.hpp" +#include "../stdexec/__detail/__transform_completion_signatures.hpp" +#include "../stdexec/__detail/__type_traits.hpp" + #include "sender_for.hpp" #include "static_thread_pool.hpp" +#include +#include +#include +#include +#include +#include +#include + namespace experimental::execution { struct CANNOT_DISPATCH_BULK_ALGORITHM_TO_THE_POOL_SCHEDULER; From a44a4dba29040a7876716fbf96263ea508dc358f Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Mon, 6 Apr 2026 16:11:33 -0700 Subject: [PATCH 3/6] format --- include/exec/thread_pool_base.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/exec/thread_pool_base.hpp b/include/exec/thread_pool_base.hpp index a0824f9cd..9181f18c9 100644 --- a/include/exec/thread_pool_base.hpp +++ b/include/exec/thread_pool_base.hpp @@ -17,7 +17,6 @@ */ #pragma once - #include "../stdexec/__detail/__execution_fwd.hpp" #include "../stdexec/__detail/__connect.hpp" From ca78abe7165409eaa19cddd36e9f647f0a3815d1 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Mon, 6 Apr 2026 16:20:26 -0700 Subject: [PATCH 4/6] format harder --- include/exec/sequence/iterate.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/exec/sequence/iterate.hpp b/include/exec/sequence/iterate.hpp index 907d6fca8..f026d562a 100644 --- a/include/exec/sequence/iterate.hpp +++ b/include/exec/sequence/iterate.hpp @@ -23,12 +23,12 @@ # include "../../stdexec/__detail/__concepts.hpp" # include "../../stdexec/__detail/__connect.hpp" # include "../../stdexec/__detail/__env.hpp" -# include "../../stdexec/__detail/__optional.hpp" +# include "../../stdexec/__detail/__execution_fwd.hpp" # include "../../stdexec/__detail/__operation_states.hpp" +# include "../../stdexec/__detail/__optional.hpp" # include "../../stdexec/__detail/__receivers.hpp" # include "../../stdexec/__detail/__schedulers.hpp" # include "../../stdexec/__detail/__sender_concepts.hpp" -# include "../../stdexec/__detail/__execution_fwd.hpp" # include "../detail/basic_sequence.hpp" # include "../sender_for.hpp" From a148d88162631a400f0871ddba46ce16f1614238 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Mon, 6 Apr 2026 16:56:10 -0700 Subject: [PATCH 5/6] use `__optional` instead of `std::optional` --- include/exec/static_thread_pool.hpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/include/exec/static_thread_pool.hpp b/include/exec/static_thread_pool.hpp index cbb4b4a84..c0d5cc6e0 100644 --- a/include/exec/static_thread_pool.hpp +++ b/include/exec/static_thread_pool.hpp @@ -27,8 +27,9 @@ #include "../stdexec/__detail/__execution_legacy.hpp" #include "../stdexec/__detail/__get_completion_signatures.hpp" #include "../stdexec/__detail/__intrusive_queue.hpp" -#include "../stdexec/__detail/__manual_lifetime.hpp" // IWYU pragma: keep -#include "../stdexec/__detail/__meta.hpp" // IWYU pragma: keep +#include "../stdexec/__detail/__manual_lifetime.hpp" +#include "../stdexec/__detail/__meta.hpp" +#include "../stdexec/__detail/__optional.hpp" #include "../stdexec/__detail/__receivers.hpp" #include "../stdexec/__detail/__transform_completion_signatures.hpp" #include "../stdexec/__detail/__tuple.hpp" @@ -704,12 +705,12 @@ namespace experimental::execution alignas(64) __std::atomic num_active_{}; alignas(64) remote_queue_list remotes_; - std::uint32_t thread_count_; - std::uint32_t max_steals_{thread_count_ + 1}; - bwos_params params_; - std::vector threads_; - std::vector> thread_states_; - numa_policy numa_; + std::uint32_t thread_count_; + std::uint32_t max_steals_{thread_count_ + 1}; + bwos_params params_; + std::vector threads_; + std::vector<__optional> thread_states_; + numa_policy numa_; struct thread_index_by_numa_node { From 41aa8eb3281b1abcd2507f52c9c4271b629bfacb Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Mon, 6 Apr 2026 17:35:31 -0700 Subject: [PATCH 6/6] fix narrowing conversion --- include/exec/static_thread_pool.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/exec/static_thread_pool.hpp b/include/exec/static_thread_pool.hpp index c0d5cc6e0..0dd7ce14d 100644 --- a/include/exec/static_thread_pool.hpp +++ b/include/exec/static_thread_pool.hpp @@ -1453,7 +1453,7 @@ namespace experimental::execution if constexpr (Parallelize) { return static_cast( - __umin({shape_, static_cast(pool_.available_parallelism())})); + __umin({std::size_t(shape_), std::size_t(pool_.available_parallelism())})); } else {