Priority Levels#
TooManyCooks offers priority configuration for work items that run on tmc::ex_cpu
. When resuming work,
higher priority work will be chosen first. The default number of priorities is 1. You can increase the number of priorities by calling
tmc::ex_cpu::set_priority_count()
or configuring TMC_PRIORITY_COUNT
.
The maximum possible number of priorities is 16.
The highest priority level is always 0. The lowest priority level is tmc::ex_cpu::priority_count()
- 1.
So if the priority count was set to 5, the highest priority would be 0 and the lowest priority would be 4.
Setting Task Priority#
When submitting work from an external thread using the tmc::post()
family of functions,
the priority defaults to 0 (highest priority) unless specified explicitly.
When submitting work from within a coroutine using
the tmc::spawn()
family of functions, the child task will inherit the parent’s priority.
To change the priority of a child task, you can call the
tmc::with_priority()
awaitable customizer before awaiting it.
This will not affect the priority of the parent task after it resumes.
To get/set the priority of the currently executing task, see tmc::current_priority()
/ tmc::change_priority()
.
Yielding To Higher Priority Tasks#
Executor threads will choose the highest priority available task in their queue whenever they enter the run loop. This will happen any time the current task suspends while waiting on an awaitable. However, if the current task performs a symmetric transfer to another coroutine, the queue will not be checked. Similarly, long-running loops without a suspend point could prevent an executor thread from checking the queue for a higher priority task.
Several utility awaitables are provided to allow user code to detect that a higher priority
task is waiting to run, and yield to the executor. The simplest of these is tmc::yield_if_requested()
.
If your application makes use of long-running CPU-bound background tasks, you should use these
functions in order to yield in a timely manner. Short-running tasks do not need to call these.
Non-Priority Executors And Awaitables#
Some executors (such as tmc::ex_braid
and tmc::ex_asio) don’t inherently support priority.
They only have a single work queue and items will be processed in FIFO order, regardless of their priority. However,
the priority will still be tracked and the following invariants will hold true at all times:
tmc::current_priority()
will always report the correct assigned priority of the tasknewly created child tasks will always inherit the correct assigned priority of their parents
when exiting the non-priority executor back to a priority executor, they will be assigned to the correct priority queue