Work Items / tmc::post()#

Work Item Types#

A work item is any type that can be submitted for execution to a TMC executor.

The first-class work item type of TMC is the coroutine tmc::task. However, the TMC executors / utility functions offer support for a variety of other work item types. Generally, any type that implements operator()() can be submitted to any of TMC’s executors. This includes functors, tasks, and external coroutines.

Functors as Work Items#

Any object that exposes operator()() is a Functor. This includes:

  • std::function<Result()> / std::function<void()>

  • lambda functions (value or void-returning)

  • functors (value or void-returning)

  • free functions (value or void-returning)

  • external (non-TMC) coroutines

tmc::task as a Work Item#

The post() family of functions have overloads that detect when a tmc::task is passed and allow you to synchronously wait for the task to complete and/or retrieve a result, as if it were awaited.

(tasks are technically functors, but this special handling allows them to be “awaited” in a sync context)

External Coroutines as Work Items#

Unlike tmc::task, external coroutine types aren’t handled specially by the post functions. They will be treated as if they were any other void-returning functor.

They will only be resumed 1 time (by calling operator()()) after which post_waitable() will return. If they return a result, it cannot be retrieved, and storage for it may not be properly available, depending on the coroutine implementation.

Because of this, you can safely use them with tmc::post() / tmc::post_bulk(), but don’t try to wait for them to finish with the waitable() variants - it won’t behave as expected.

External coroutines are often awaitables, and would behave as expected when co_await ed or with the tmc::spawn() family of functions. Therefore it is generally recommended to await external coroutines from within a tmc::task, in order to ensure that they complete successfully.

post() functions: the sync-to-async bridge#

tmc::task<void> and void-returning functors may be submitted directly to an executor with:

tmc::task<Result> and Result-returning functors may only be submitted with:

The quickstart function tmc::async_main() is provided to easily enter the TMC execution context at the beginning of the program. If your application is coroutine-based, it is recommended to call this function first, and then use tmc::spawn() to create additional work instead of using the tmc::post() family of functions.