Integrating External Executors#
Setting the Default Executor#
When tmc::spawn*() is called, the work is typically submitted to the current thread’s executor (tmc::detail::this_thread::executor).
If the current thread is an external thread, it won’t be configured with an executor.
You can set a default executor which will be used as a fallback in this situation.
You only need to call tmc::set_default_executor() once to enable this globally.
-
inline void tmc::set_default_executor(tmc::ex_any *Executor)#
You only need to set this if you are planning to integrate TMC with external threads of execution that don’t configure
tmc::detail::this_thread::executor.If a TMC function that submits work to the current executor implicitly, such as
spawn(), is invoked:on a non-TMC thread that has not set
tmc::detail::this_thread::executorwithout explicitly specifying an executor via
.run_on()/.resume_on()
then that function will use this default executor (instead of deferencing nullptr and crashing).
-
template<typename Exec>
inline void tmc::set_default_executor(Exec &Executor)# You only need to set this if you are planning to integrate TMC with external threads of execution that don’t configure
tmc::detail::this_thread::executor.If a TMC function that submits work to the current executor implicitly, such as
spawn(), is invoked:on a non-TMC thread that has not set
tmc::detail::this_thread::executorwithout explicitly specifying an executor via
.run_on()/.resume_on()
then that function will use this default executor (instead of deferencing nullptr and crashing).
-
template<typename Exec>
inline void tmc::set_default_executor(Exec *Executor)# You only need to set this if you are planning to integrate TMC with external threads of execution that don’t configure
tmc::detail::this_thread::executor.If a TMC function that submits work to the current executor implicitly, such as
spawn(), is invoked:on a non-TMC thread that has not set
tmc::detail::this_thread::executorwithout explicitly specifying an executor via
.run_on()/.resume_on()
then that function will use this default executor (instead of deferencing nullptr and crashing).
Fully Integrating#
External libraries or users may provide a type that fully satisfies the concept of an “executor” by
implementing a specialization of the tmc::detail::executor_traits struct.
Additionally, they must implement the following behaviors:
Threads that participate in the executor should set the value of
tmc::detail::this_thread::executor.
If all threads of execution implement this behavior, then tmc::external::set_default_executor() is not necessary.
The members of the tmc::detail::executor_traits struct are described below.
Also see the docs for tmc::work_item.
template <> struct tmc::detail::executor_traits<your_executor> {
static void post(your_executor& ex, tmc::work_item&& Item, size_t Priority);
// Iter will be a forward iterator of tmc::work_item.
template <typename Iter>
static void post_bulk(your_executor& ex, Iter&& Items, size_t Count, size_t Priority);
static tmc::ex_any* type_erased(your_executor& ex);
static std::coroutine_handle<> task_enter_context(
your_executor& ex, std::coroutine_handle<> Outer, size_t Priority
);
};
Example Implementation#
A complete, minimal implementation of tmc::detail::executor_traits is available in the external_executor example.