Why CPU Scheduling Matters in Embedded Linux
Not all embedded tasks have equal importance.
For example:
A motor control loop must execute within strict timing deadlines.
A logging or display task can tolerate delays.
Linux scheduling policies ensure that time-critical tasks preempt less critical ones,
making Linux suitable for both real-time and non-real-time embedded workloads.
First Come First Serve (FCFS) in Linux – SCHED_FIFO
First Come First Serve (FCFS) is one of the simplest scheduling concepts.
The first process that enters the ready queue is the first one to execute.
Each process runs until it finishes or blocks.
In embedded Linux, FCFS behavior is implemented using the SCHED_FIFO real-time scheduling policy.
Tasks execute in priority order and continue running until they voluntarily yield the CPU
or block for I/O.
This approach is ideal for deterministic real-time applications where interruptions
must be avoided.

Characteristics
- Highest-priority runnable task executes first
- Runs until it blocks or exits
- No time slicing
- Lower-priority tasks can starve if not carefully designed
Example: SCHED_FIFO in Embedded Linux
#include
#include
#include
int main() {
struct sched_param param;
param.sched_priority = 80;
sched_setscheduler(0, SCHED_FIFO, ¶m);
while (1) {
printf("SCHED_FIFO task running\n");
sleep(1);
}
}
Best Use Cases
- Motor control
- Hard real-time signal handling
- Deterministic control loops
Shortest Job First vs Linux CFS Scheduler
Shortest Job First (SJF) selects the task with the smallest execution time to minimize
average waiting time. While efficient in theory, it is impractical in real systems
because execution time is not known in advance.
Linux instead uses the Completely Fair Scheduler (CFS), which approximates this idea
by tracking how much CPU time each task has received and favoring tasks that have
used less CPU recently.
In embedded systems, this improves responsiveness for short tasks such as user input
handlers or lightweight sensor reads.
How CFS Works
- Tracks per-task virtual runtime
- Attempts to give all tasks a fair share of CPU time
- Optimized for fairness and responsiveness, not determinism
Example: Default CFS Scheduler
#include
#include
int main() {
while (1) {
printf("Running under CFS scheduler\n");
usleep(100000);
}
}
Best Use Cases
- User interfaces
- Networking stacks
- Background services

Priority Scheduling in Linux Real-Time Systems
Priority scheduling assigns each task a priority, and the scheduler always selects
the highest-priority runnable task.
Linux real-time policies support priorities from 1 to 99, where higher numbers
indicate higher priority.
When a high-priority task becomes runnable, it immediately preempts lower-priority tasks.
This behavior is essential for time-critical embedded workloads.
Example: Checking Real-Time Priority
#include
#include
int main() {
struct sched_param param;
sched_getparam(0, ¶m);
printf("Current Priority: %d\n", param.sched_priority);
}
Use Cases
- Time-critical embedded operations
- Interrupt-adjacent user-space tasks
Round Robin Scheduling – SCHED_RR
Round Robin scheduling improves fairness by giving each task a fixed time slice (quantum).
When the time slice expires, the task is moved to the end of the queue.
In Linux, this is implemented using SCHED_RR. Tasks with the same priority are scheduled
in a round-robin manner, preventing starvation while maintaining real-time behavior.
Characteristics
- Fixed time quantum
- Prevents starvation among equal-priority tasks
- Fully preemptive
Example: SCHED_RR
#include
#include
#include
int main() {
struct sched_param param;
param.sched_priority = 60;
sched_setscheduler(0, SCHED_RR, ¶m);
while (1) {
printf("SCHED_RR task running\n");
sleep(1);
}
}
Best Use Cases
- Multiple sensor-processing threads
- Equal-priority real-time workloads
SCHED_FIFO vs SCHED_RR Comparison
| Feature | SCHED_FIFO | SCHED_RR |
|---|
| Time slicing | No | Yes |
| Fairness | Low | Medium |
| Starvation risk | High | Lower |
| Determinism | Very High | High |
| Best use case | Hard real-time | Equal-priority RT |
Combining Scheduling Policies in Embedded Linux
A common and effective embedded Linux design uses multiple scheduling policies simultaneously:
- SCHED_FIFO → Motor and actuator control
- SCHED_RR → Sensor data processing
- CFS → Networking, UI, logging
This hybrid approach provides real-time determinism without sacrificing system flexibility.
Advanced Note: Priority Inversion (Important)
Priority inversion occurs when a low-priority task holds a resource needed by a
high-priority task.
Mitigation strategies include:
- Priority inheritance mutexes
- Careful resource locking
- PREEMPT_RT kernel patches for tighter latency guarantees
Ignoring priority inversion can break real-time behavior—even with correct scheduler selection.
Key Takeaways
- Linux supports both real-time and non-real-time scheduling
- SCHED_FIFO and SCHED_RR enable deterministic embedded behavior
- CFS is best for non-critical system tasks
- Scheduler selection is a system design decision, not just configuration
