Yielding
YieldTask gives up the processor without suspending the calling task: the task stays runnable and continues as soon as it is its turn again.
| YieldFlags | Effect |
|---|---|
Default |
The task goes to the end of its priority's queue. If nothing else is runnable, it continues at once. |
HigherPriority |
The task gives way only to waiting High work. If there is none, or the task is High itself, it continues at once. |
When to yield
Tasks are not preempted. A task that computes for a long time without waiting keeps its thread until it is done. That is usually what you want — but if other tasks need to make progress in the meantime, yield at natural points of the loop:
for (std::size_t block = 0; block < blocks; ++block) {
Process(block);
TC::YieldTask(TC::YieldFlags::HigherPriority); // let the critical path through
}HigherPriority is the cheap choice in hot loops: it costs almost nothing when no high-priority
work is waiting.
Yield is not a wait
Do not yield in a loop to wait for a condition ("spin-yield"). The task stays runnable and keeps coming back. Wait on a primitive instead; the task is then suspended until the condition is true.