Skip to content

Task allocation#74

Merged
dietmarkuehl merged 14 commits intomainfrom
task-allocation
Mar 23, 2026
Merged

Task allocation#74
dietmarkuehl merged 14 commits intomainfrom
task-allocation

Conversation

@dietmarkuehl
Copy link
Member

No description provided.

Copilot AI review requested due to automatic review settings March 23, 2026 02:50
@coveralls
Copy link

coveralls commented Mar 23, 2026

Coverage Status

coverage: 94.212% (+0.09%) from 94.118%
when pulling e657f74 on task-allocation
into 70fa90d on main.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces allocator propagation into the task state/promise plumbing by adding an allocator query to state_base and routing promise_type::get_allocator() through the active state, with corresponding updates to core task state types and unit tests.

Changes:

  • Add allocator_type, get_allocator(), and pure-virtual do_get_allocator() to state_base.
  • Implement allocator retrieval in detail::state (operation state) and detail::awaiter.
  • Update tests/mocks to satisfy the new state_base vtable requirement.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/beman/task/state_base.test.cpp Updates mock state to implement do_get_allocator() (no assertions added yet).
tests/beman/task/promise_type.test.cpp Updates test task state to implement do_get_allocator() (no allocator behavior asserted).
tests/beman/task/promise_base.test.cpp Updates mock state to implement do_get_allocator() (no allocator behavior asserted).
include/beman/task/detail/state.hpp Adds allocator plumbing to operation-state implementation.
include/beman/task/detail/state_base.hpp Introduces allocator API and new pure virtual do_get_allocator().
include/beman/task/detail/promise_type.hpp Changes allocator lookup to defer to the active state_base.
include/beman/task/detail/awaiter.hpp Adds allocator plumbing for awaited coroutines.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +51 to +52
if constexpr (requires { ::beman::execution::get_allocator(this->receiver); })
return ::beman::execution::get_allocator(this->receiver);
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do_get_allocator() is querying get_allocator(this->receiver), but other environment queries in this type (e.g. stop token) correctly go through get_env(receiver). With the current code, receivers that provide an allocator via their environment (query(get_allocator_t) on env) will be ignored and the default allocator will be returned instead. Consider querying ::beman::execution::get_allocator(::beman::execution::get_env(this->receiver)) (and adjusting the requires accordingly) to match the established pattern in this file.

Suggested change
if constexpr (requires { ::beman::execution::get_allocator(this->receiver); })
return ::beman::execution::get_allocator(this->receiver);
if constexpr (requires {
::beman::execution::get_allocator(
::beman::execution::get_env(this->receiver));
})
return ::beman::execution::get_allocator(
::beman::execution::get_env(this->receiver));

Copilot uses AI. Check for mistakes.
Comment on lines +92 to +93
if constexpr (requires { ::beman::execution::get_allocator(::beman::execution::get_env(this->parent)); })
return ::beman::execution::get_allocator(::beman::execution::get_env(this->parent));
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do_get_allocator() uses ::beman::execution::get_env(this->parent) where this->parent is a std::coroutine_handle<ParentPromise>. Elsewhere in this file the environment is obtained from this->parent.promise(). As written, this is inconsistent and is likely ill-formed or will select the wrong overload, breaking allocator propagation for awaited coroutines. Consider using ::beman::execution::get_env(this->parent.promise()) (and matching it in the requires) to align with the scheduler logic above.

Suggested change
if constexpr (requires { ::beman::execution::get_allocator(::beman::execution::get_env(this->parent)); })
return ::beman::execution::get_allocator(::beman::execution::get_env(this->parent));
if constexpr (requires {
::beman::execution::get_allocator(::beman::execution::get_env(this->parent.promise()));
})
return ::beman::execution::get_allocator(::beman::execution::get_env(this->parent.promise()));

Copilot uses AI. Check for mistakes.

auto get_scheduler() const noexcept -> scheduler_type { return this->get_state()->get_scheduler(); }
auto get_allocator() const noexcept -> allocator_type { return this->allocator; }
auto get_allocator() const noexcept -> allocator_type { return this->get_state()->get_allocator(); }
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

promise_type::get_allocator() now forwards to this->get_state()->get_allocator() but unlike get_environment() it doesn't assert that get_state() is non-null. If get_allocator is queried before start()/set_state() (e.g. via get_env()), this will dereference a null state pointer. Consider adding an assert(this->get_state()) (or a safe fallback allocator) similar to get_environment().

Suggested change
auto get_allocator() const noexcept -> allocator_type { return this->get_state()->get_allocator(); }
auto get_allocator() const noexcept -> allocator_type {
assert(this);
assert(this->get_state());
return this->get_state()->get_allocator();
}

Copilot uses AI. Check for mistakes.
Comment on lines 19 to 32
@@ -26,6 +28,7 @@ struct state : beman::task::detail::state_base<int, environment> {
this->completed = true;
return std::noop_coroutine();
}
allocator_type do_get_allocator() override { return allocator_type{}; }
stop_token_type do_get_stop_token() override {
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new state_base::get_allocator() API was added, but this test only implements do_get_allocator() to satisfy the vtable and doesn't actually exercise the new get_allocator() behavior. Consider adding an assertion that s.get_allocator() returns the expected allocator instance/type to prevent regressions.

Copilot uses AI. Check for mistakes.
Comment on lines 130 to 160
@@ -153,6 +155,7 @@ struct test_task : beman::task::detail::state_base<int, environment> {
this->latch.count_down();
return std::noop_coroutine();
}
allocator_type do_get_allocator() override { return allocator_type{}; }
stop_token_type do_get_stop_token() override { return this->source.get_token(); }
environment& do_get_environment() override { return this->env; }
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test adds do_get_allocator() to compile with the new state_base interface, but it doesn't validate that promise_type::get_allocator() (or env get_allocator queries) are correctly routed through the state. Consider extending the test to query the allocator and assert the expected propagation/defaulting behavior.

Copilot uses AI. Check for mistakes.
Comment on lines 50 to 70
@@ -62,6 +64,7 @@ struct state : bt::state_base<T, env<E...>> {
this->completed = true;
return std::noop_coroutine();
}
allocator_type do_get_allocator() override { return allocator_type{}; }
stop_token_type do_get_stop_token() override {
this->token = true;
return this->source.get_token();
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test updates the mock state to implement do_get_allocator(), but it doesn't verify that promise_base/state interactions for the new allocator API work as intended (e.g. calling get_allocator() on the state). Consider adding an assertion that the allocator query path is exercised.

Copilot uses AI. Check for mistakes.
@dietmarkuehl dietmarkuehl merged commit 1ac1fdf into main Mar 23, 2026
36 checks passed
@dietmarkuehl dietmarkuehl deleted the task-allocation branch March 23, 2026 03:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants