.. _external_executors:

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.

.. doxygenfunction:: set_default_executor(tmc::ex_any* Executor)

.. doxygenfunction:: set_default_executor(Exec&& Executor)

.. doxygenfunction:: set_default_executor(Exec* Executor)


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 :literal_ref:`tmc::work_item<work_item>`.

.. code-block:: cpp

   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<> dispatch(
         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 <https://github.com/tzcnt/tmc-examples/blob/main/examples/external_executor.cpp#L68>`_.

