Program Listing for File spawn.hpp¶
↰ Return to documentation for file (include/concore/spawn.hpp)
#pragma once
#include "task.hpp"
#include "detail/exec_context_if.hpp"
#include "detail/library_data.hpp"
#include <initializer_list>
namespace concore {
inline namespace v1 {
inline void spawn(task&& t, bool wake_workers = true) {
detail::do_spawn(detail::get_exec_context(), std::move(t), wake_workers);
}
template <typename F>
inline void spawn(F&& ftor, bool wake_workers = true) {
auto grp = task_group::current_task_group();
detail::do_spawn(detail::get_exec_context(), task(std::forward<F>(ftor), grp), wake_workers);
}
template <typename F>
inline void spawn(F&& ftor, task_group grp, bool wake_workers = true) {
detail::do_spawn(
detail::get_exec_context(), task(std::forward<F>(ftor), std::move(grp)), wake_workers);
}
inline void spawn(std::initializer_list<task_function>&& ftors, bool wake_workers = true) {
auto grp = task_group::current_task_group();
int count = static_cast<int>(ftors.size());
for (const auto& ftor : ftors) {
// wake_workers applies only to the last element; otherwise pass true
bool cur_wake_workers = (count-- > 0 || wake_workers);
detail::do_spawn(detail::get_exec_context(), task(ftor, grp), cur_wake_workers);
}
}
inline void spawn(
std::initializer_list<task_function>&& ftors, task_group grp, bool wake_workers = true) {
int count = static_cast<int>(ftors.size());
for (const auto& ftor : ftors) {
// wake_workers applies only to the last element; otherwise pass true
bool cur_wake_workers = (count-- > 0 || wake_workers);
detail::do_spawn(detail::get_exec_context(), task(ftor, grp), cur_wake_workers);
}
}
template <typename F>
inline void spawn_and_wait(F&& ftor) {
auto& ctx = detail::get_exec_context();
auto worker_data = detail::enter_worker(ctx);
auto grp = task_group::create(task_group::current_task_group());
detail::do_spawn(ctx, task(std::forward<F>(ftor), grp), false);
detail::busy_wait_on(ctx, grp);
detail::exit_worker(ctx, worker_data);
}
inline void spawn_and_wait(std::initializer_list<task_function>&& ftors, bool wake_workers = true) {
auto& ctx = detail::get_exec_context();
auto worker_data = detail::enter_worker(ctx);
auto grp = task_group::create(task_group::current_task_group());
int count = static_cast<int>(ftors.size());
for (const auto& ftor : ftors) {
bool cur_wake_workers = count-- > 0; // don't wake on the last task
detail::do_spawn(ctx, task(ftor, grp), cur_wake_workers);
}
detail::busy_wait_on(ctx, grp);
detail::exit_worker(ctx, worker_data);
}
inline void wait(task_group& grp) {
auto& ctx = detail::get_exec_context();
auto worker_data = detail::enter_worker(ctx);
detail::busy_wait_on(ctx, grp);
detail::exit_worker(ctx, worker_data);
}
struct spawn_executor {
template <typename F>
void execute(F&& f) const {
do_spawn(detail::get_exec_context(), task{std::forward<F>(f)});
}
void execute(task t) { do_spawn(detail::get_exec_context(), std::move(t)); }
friend inline bool operator==(spawn_executor, spawn_executor) { return true; }
friend inline bool operator!=(spawn_executor, spawn_executor) { return false; }
};
struct spawn_continuation_executor {
template <typename F>
void execute(F&& f) const {
do_spawn(detail::get_exec_context(), task{std::forward<F>(f)}, false);
}
void execute(task t) { do_spawn(detail::get_exec_context(), std::move(t), false); }
friend inline bool operator==(spawn_continuation_executor, spawn_continuation_executor) {
return true;
}
friend inline bool operator!=(spawn_continuation_executor, spawn_continuation_executor) {
return false;
}
};
} // namespace v1
} // namespace concore