RTOS Scheduling and Concurrency
RTOS concurrency design connects tasks, priorities, communication, shared resources, and progress monitoring to explicit timing requirements. Choosing a high priority does not establish that a task meets a deadline: it can still wait for data, a lock, interrupt handling, or another dependency.
Begin with the work that must complete, the resources it needs, and the behavior required when it cannot progress. Verify scheduling and synchronization on the actual kernel, configuration, port, and hardware. A small scheduler model is useful for reasoning, but it cannot certify real-time behavior or physical safety.
TL;DR
- Tie tasks, priorities, communication, shared resources, and progress monitoring to explicit timing requirements.
- A high priority doesn't guarantee a deadline: the task can still wait on data, a lock, interrupts, or another dependency.
- Bound queues and track message age; a bigger queue only delays overload.
- Use priority inheritance against unbounded priority inversion, but analyze execution, blocking, and interference for deadlines.
- Feed a watchdog only after real work completes, and verify timing on the actual kernel, port, and hardware.
Quick Example
This original Python model executes finite jobs on one fictional CPU in unit ticks. In this model only, a higher numeric priority wins and equal priorities follow the input order. Real RTOS priority numbering and scheduling rules must be checked independently.
In the model, a control job released at tick one preempts the background job and finishes at tick two. The background job then finishes at tick four. A second scenario leaves a lower-priority job unfinished within the selected horizon. Idle time, delayed releases, and equal-priority ordering are worth testing the same way.
No RTOS API, interrupt, queue, mutex, watchdog, context-switch overhead, clock jitter, SMP, device, or deadline proof was tested. Jobs must have unique names and the stated finite positive costs. The trace demonstrates the model's chosen rules, not the behavior of an installed kernel or a recommended task priority.
Core Concepts
Priority applies to eligible work
Zephyr's scheduling documentation describes priority-based selection among ready threads and distinguishes rescheduling points, interrupt execution, and cooperative behavior. The important design question is whether a task is ready, waiting, or otherwise unable to run, not simply which priority number it has. Zephyr scheduling.
Map each task's release condition, work, deadline where applicable, and dependencies. Include interrupt activity, critical sections, shared resources, and lower-priority services that higher-priority work needs. A task that waits for a peripheral or mutex cannot solve that wait merely by being assigned a more urgent priority.
Use the actual kernel configuration when analyzing equal-priority and cooperative/preemptive behavior. The example's input-order tie rule is a declared simplification. Do not transfer it to a kernel whose time slicing, priorities, or scheduling configuration differs.
Queues require ownership and capacity policies
FreeRTOS documentation describes queues carrying copied messages and allowing tasks to block when data or space is unavailable. A copied pointer is still a pointer: ownership and lifetime of the referenced buffer need their own contract. FreeRTOS intertask coordination.
Define what a message means, who owns its storage, when it can be reused, and what happens when a queue is full. Dropping an old observation, rejecting new work, waiting with a bound, or signaling overload produces different application behavior. Choose deliberately and measure the workload that can fill the queue.
Record observation age as well as queue depth. A consumer that eventually processes every old sample can still make an outdated decision. A queue capacity large enough to hide bursts may also hide an overloaded consumer until the backlog becomes unacceptable.
Synchronization changes scheduling
FreeRTOS mutex documentation describes priority inheritance when a higher-priority task blocks on a mutex owned by a lower-priority task. It is a mechanism for a particular dependency, not a general cure for every missed deadline or deadlock. Binary semaphores and mutexes should not be assumed interchangeable. FreeRTOS synchronization primitives.
Keep critical sections focused and establish a consistent resource-ordering policy where multiple locks are needed. Identify operations that may block while a resource is held. Review interrupt-context restrictions in the selected kernel and port before using an API; an ordinary task call is not automatically valid from an ISR.
For each timing claim, include blocking and interference assumptions. A task's isolated execution time omits time spent waiting and being preempted. A measured best case is useful data, but it is not a worst-case response guarantee.
Watchdogs should supervise meaningful progress
Zephyr's task-watchdog documentation describes supervising multiple task channels, with an optional hardware watchdog fallback. It explains why a single regularly fed watchdog can be insufficient to represent the progress of multiple tasks. Zephyr task watchdog.
Define what progress means for each critical activity. A loop can remain alive while failing to acquire data or complete a required operation. Feeding a watchdog from an unrelated high-priority loop may conceal that condition. Connect health evidence to the work that matters, with a reviewed policy for startup, overload, maintenance, and recovery.
Also define what happens after a watchdog action. A reset can repeat the original fault or leave equipment in a state that requires separate handling. Keep physical-safety mechanisms and operating authority in the qualified system design; a watchdog feature alone does not establish a safe recovery.
Best Practices
Write a dependency-aware timing budget
List execution work, release uncertainty, shared-resource blocking, interrupt interference, and communication delays relevant to the requirement. Keep measured values and analytical assumptions distinct. Use the project's qualified real-time review process when deadlines or equipment behavior have consequential requirements.
Collect representative kernel and hardware evidence under the intended configuration, including logging and instrumentation overhead. Test startup, steady operation, burst load, and degraded dependencies. A quiet bench run cannot establish the behavior of a loaded system.
Exercise overload and partial failure
In an isolated test environment, delay a consumer, fill a queue, hold a resource longer than expected, or stall a monitored activity. State the expected indication and recovery before the test. Verify which work is dropped, delayed, or rejected and whether the system returns to a coherent state.
Keep those experiments separate from operational equipment unless explicitly authorized through the responsible process. The teaching model runs no hardware and supplies no authority to create faults in a working system.
Review changes as system changes
Adding a task, changing a priority, increasing queue capacity, or moving work into an interrupt can alter other tasks' behavior. Revisit the relevant dependencies and timing evidence instead of testing only the edited component. A local improvement can move blocking or overload somewhere less visible.
Common Mistakes
Making every task high priority
Using a large queue to absorb overload
Treating priority inheritance as a deadline proof
Feeding the watchdog unconditionally
FAQ
Does real-time mean the fastest average execution?
The relevant requirement is timely behavior under stated conditions, including deadlines where applicable. A good average does not establish an acceptable worst case. Define and verify the requirement for the actual system.
Does copying a pointer into a queue copy its buffer?
No. The queue can copy the pointer value while the referenced storage still needs explicit ownership and lifetime rules. Test producer reuse and delayed consumption.
Can this scheduler model select production priorities?
No. It omits the kernel and hardware behavior that determine real response times. Use it to expose a basic preemption or starvation question, then analyze and test the deployed configuration with qualified owners.