tmc::ex_cpu_st#

ex_cpu_st is a single-threaded executor. It behaves the same as an ex_cpu with .set_thread_count(1). However, it has better round-trip latency and better internal execution performance, as it does not need the thread tracking and synchronization systems that are present in the multi-threaded executor.

This single-threaded executor may be useful to manage communication with certain systems that require all calls to come from the same thread (e.g. SDL/OpenGL).

You must call .init() on each executor instance before you use it. Before calling init(), you may configure it by calling any of the member functions that begin with set_.

Usage Example#

#define TMC_IMPL
#include "tmc/all_headers.hpp"

int main() {
  // Run async_main on the global (multi-threaded) ex_cpu
  tmc::cpu_executor().init();
  return tmc::async_main([]() -> tmc::task<int> {

    // Configure and run a single-threaded executor
    tmc::ex_cpu_st single_threaded_exec;
    single_threaded_exec.init();

    // This child task will be executed on single_threaded_exec
    co_await tmc::spawn(some_task()).run_on(single_threaded_exec);
    // After it completes, the main task will resume back on the global ex_cpu

    co_return 0;
  }());
}

API Reference#

class ex_cpu_st#

Public Functions

ex_cpu_st &set_priority_count(size_t PriorityCount)#

Builder func to set the number of priority levels before calling init(). The value must be in the range [1, 16]. The default is 1.

size_t priority_count()#

Gets the number of priority levels. Only useful after init() has been called.

size_t thread_count()#

Gets the number of worker threads. Always returns 1.

ex_cpu_st &set_thread_init_hook(std::function<void(size_t)> Hook)#

Hook will be invoked at the startup of each thread owned by this executor, and passed the ordinal index (0..thread_count()-1) of the thread.

ex_cpu_st &set_thread_teardown_hook(std::function<void(size_t)> Hook)#

Hook will be invoked before destruction of each thread owned by this executor, and passed the ordinal index (0..thread_count()-1) of the thread.

void init()#

Initializes the executor. If you want to customize the behavior, call the set_X() functions before calling init(). By default, uses hwloc to automatically generate threads, and creates 1 (or TMC_PRIORITY_COUNT) priority levels.

If the executor is already initialized, calling init() will do nothing.

void teardown()#

Stops the executor, joins the worker thread, and destroys resources. Does not wait for any queued work to complete. teardown() must not be called from this executor’s thread.

Restores the executor to an uninitialized state. After calling teardown(), you may call set_X() to reconfigure the executor and call init() again.

If the executor is not initialized, calling teardown() will do nothing.

ex_cpu_st()#

After constructing, you must call init() before use.

~ex_cpu_st()#

Invokes teardown(). Must not be called from this executor’s thread.

void post(work_item &&Item, size_t Priority = 0, size_t ThreadHint = NO_HINT)#

Submits a single work_item to the executor.

Rather than calling this directly, it is recommended to use the tmc::post() free function template.

tmc::ex_any *type_erased()#

Returns a pointer to the type erased ex_any version of this executor. This object shares a lifetime with this executor, and can be used for pointer-based equality comparison against the thread-local tmc::current_executor().

template<typename It>
inline void post_bulk(It &&Items, size_t Count, size_t Priority = 0, size_t ThreadHint = NO_HINT)#

Submits count items to the executor. It is expected to be an iterator type that implements operator*() and It& operator++().

Rather than calling this directly, it is recommended to use the tmc::post_bulk() free function template.