tmc::spawn_group::add_clang()

tmc::spawn_group::add_clang()#

tmc::spawn_group::add_clang() is a HALO-optimized method for adding awaitables to a spawn_group. It uses the [[clang::coro_await_elidable_argument]] attribute when compiled with Clang 20+.

For HALO to work, add_clang() must be awaited directly as a prvalue in a co_await expression.

// HALO: add_clang() is directly awaited for each task
auto sg = tmc::spawn_group<3, tmc::task<int>>();
co_await sg.add_clang(task_int(11));
co_await sg.add_clang(task_int(22));
co_await sg.add_clang(task_int(33));
auto results = co_await std::move(sg);

// Non-HALO: add() without HALO attributes
auto sg = tmc::spawn_group<3, tmc::task<int>>();
sg.add(task_int(44));
sg.add(task_int(55));
sg.add(task_int(66));
auto results = co_await std::move(sg);

WARNING: Do not use spawn_group::add_clang() in a loop, as Clang will try to reuse the same allocation for multiple active coroutines, causing crashes.

// spawn_group::add_clang() in a loop will cause a segfault!
// Clang erroneously tries to use the same allocation for all subtasks
auto sg = tmc::spawn_group<3, tmc::task<int>>();
for (size_t i = 0; i < sg.capacity(); i++) {
  co_await sg.add_clang(task_int(i));
}
auto results = co_await std::move(sg);

// Correct: Use add() without HALO attributes in a loop - works fine
auto sg = tmc::spawn_group<3, tmc::task<int>>();
for (size_t i = 0; i < sg.capacity(); i++) {
  sg.add(task_int(i));
}
auto results = co_await std::move(sg);

Main Documentation#

For full documentation on tmc::spawn_group, including the non-HALO .add() method, see tmc::spawn_group.