tmc::ex_cpu#

ex_cpu is the primary executor of TooManyCooks. It provides a high-performance work-stealing thread pool with the option for multiple priority levels.

It is recommended to use a single instance of ex_cpu for general work submission across your entire application. This maximizes the efficiency of the work-stealing architecture. However, you can create additional ex_cpu ‘s if your application requires it. For example, a separate single-threaded executor may be useful to process calls to certain external libraries.

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_.

A global instance of ex_cpu is available from tmc::cpu_executor(). This is provided as a convenience so that you can access the executor without needing to explicitly inject it. However, if you don’t want to use the global instance, just don’t init() it, and it won’t consume any resources.

Usage Example#

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

int main() {
  // Configure and init the global CPU executor
  tmc::cpu_executor().set_thread_count(8).set_priority_count(1).init();

  return tmc::async_main(main_task());
}
#define TMC_IMPL
#include "tmc/all_headers.hpp"

int main() {
  // Create a standalone instance of the CPU executor
  tmc::ex_cpu my_executor;
  my_executor.set_thread_count(8).set_priority_count(1).init();

  tmc::post_waitable(my_executor, main_task()).wait();
}

API Reference#

constexpr ex_cpu &tmc::cpu_executor()#

Returns a reference to the global instance of tmc::ex_cpu.

class ex_cpu#

Public Functions

ex_cpu &set_thread_count(size_t ThreadCount)#

Builder func to set the number of threads before calling init(). The default is 0, which will cause init() to automatically create 1 thread per physical core (with hwloc), or create std::thread::hardware_concurrency() threads (without hwloc).

ex_cpu &set_priority_count(size_t PriorityCount)#

Builder func to set the number of priority levels before calling init(). The default is 1.

size_t thread_count()#

Gets the number of worker threads. Only useful after init() has been called.

size_t priority_count()#

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

ex_cpu &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 &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 threads, and destroys resources. 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()#

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

~ex_cpu()#

Invokes teardown().

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.