Proposal: optional preemption-threshold scheduling

I would like feedback on adding optional preemption-threshold scheduling to the FreeRTOS kernel.

Motivation

FreeRTOS currently supports preemptive and cooperative scheduling. A preemption threshold provides an intermediate model for fixed-priority tasks. Each task has its normal priority P and an optional threshold T, where T is at least P. While the task runs, another task may preempt it only if the other task’s priority is greater than T. The running task still relinquishes the processor normally when it blocks, suspends, or yields.

This can reduce context switches and bound selected non-preemptive regions without disabling all preemption. A sufficiently urgent task can still preempt a threshold-protected task.

Proposed interface

The feature would be disabled by default using a configuration option. When enabled, a task’s threshold would initially equal its priority, preserving existing scheduling behavior until the application explicitly raises it.

The initial prototype used these APIs:

void vTaskPreemptionThresholdSet( TaskHandle_t xTask,
                                  UBaseType_t uxNewThreshold );

UBaseType_t uxTaskPreemptionThresholdGet( TaskHandle_t xTask );

For example, a task with priority 3 and threshold 4 cannot be preempted by a priority-4 task, but a priority-5 task can preempt it.

Questions

  1. Is preemption-threshold scheduling a feature the project would consider?
  2. Should the initial implementation support only single-core scheduling, or must it include SMP semantics in the first contribution?
  3. Would maintainers prefer a task-creation parameter, setter and getter APIs, or a different interface?
  4. How should a threshold interact with inherited priority and runtime priority changes?
  5. Should equal-priority time slicing remain independent of the threshold?

Implementation and validation plan

I have a proof of concept against an older FreeRTOS kernel copy, but I will not submit that patch directly. If the feature is considered suitable, I will implement it against the current FreeRTOS-Kernel main branch and include CMock unit tests covering task creation, wakeups, notifications, event-list removal, runtime priority changes, static allocation, and unchanged behavior when the feature is disabled.

I would appreciate guidance on the desired semantics and scope before opening a kernel pull request.

We do provide an API to alter a task’s priority at runtime: FreeRTOS-Kernel/include/task.h at main · FreeRTOS/FreeRTOS-Kernel · GitHub.

Would you please elaborate on what problem this proposal solves and how it is not solved by dynamically changing priority?

I don’t think that this is a useful feature. Among other things, it introduces obfuscated unexpected behavior. Consider the following use case:

  • A pre-build library or a third party code set such as a HAL uses the feature, allowing only tasks of priority T to preempt its internally operating task(s).
  • An application encounters the situation where one of its tasks runs at a priority < T and thus does not meet its expected deadlines but does at the moment its priority is raised > T.

Of course, it can be argued that the same scenario applies to the same libaries/middleware using the legacy API, which is yet another argument to use dynamic priority adjustment only very cautiously, explicitly and sparsely.

Can you sketch a use case in which you think that your feature could be useful?