Preemptive scheduling behavior in FreeRTOS - Time & Space Complexity
When FreeRTOS uses preemptive scheduling, tasks can be paused and resumed based on priority.
We want to understand how the time spent switching tasks grows as more tasks run.
Analyze the time complexity of the following code snippet.
void vTask1(void *pvParameters) {
for(;;) {
// Task 1 work
vTaskDelay(10);
}
}
void vTask2(void *pvParameters) {
for(;;) {
// Task 2 work
vTaskDelay(5);
}
}
int main() {
xTaskCreate(vTask1, "Task1", 1000, NULL, 2, NULL);
xTaskCreate(vTask2, "Task2", 1000, NULL, 3, NULL);
vTaskStartScheduler();
return 0;
}
This code creates two tasks with different priorities and starts the scheduler that switches between them.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The scheduler repeatedly selects the highest priority ready task.
- How many times: The selection happens on each potential context switch (timer tick, delay end, etc.).
As the number of tasks increases, the scheduler selects the next task in constant time using an array of ready lists per priority level (fixed small number of priorities).
| Input Size (number of tasks) | Time per Scheduling Decision |
|---|---|
| 2 | O(1) - checks priority lists |
| 10 | O(1) - same, independent of tasks |
| 100 | O(1) - scans at most configMAX_PRIORITIES (~32) |
Pattern observation: Scheduling decision time is constant (O(1)) regardless of number of tasks, as it doesn't scan all tasks.
Time Complexity: O(1)
This means the time the scheduler spends deciding which task to run is constant with respect to the number of tasks.
[X] Wrong: "The scheduler must check all tasks linearly, so O(n)."
[OK] Correct: FreeRTOS uses an array of lists (one per priority level, constant size), finds highest non-empty list in O(1) time.
Understanding scheduler efficiency (O(1) selection) shows knowledge of real-time OS design and why FreeRTOS scales well with many tasks.
"What if the scheduler used a single priority queue for all tasks instead of per-priority lists? How would the time complexity change?"
Practice
Solution
Step 1: Understand preemptive scheduling behavior
In preemptive scheduling, the system always runs the highest priority task that is ready.Step 2: Apply to the scenario
When a higher priority task becomes ready, it interrupts the lower priority task immediately.Final Answer:
The higher priority task immediately preempts the lower priority task and starts running. -> Option DQuick Check:
Preemptive scheduling = immediate switch to higher priority task [OK]
- Thinking tasks run simultaneously on a single core
- Believing lower priority tasks finish before switching
- Confusing preemptive with cooperative scheduling
Solution
Step 1: Recall FreeRTOS config option for preemption
The correct macro to enable preemption is configUSE_PREEMPTION.Step 2: Identify correct value to enable preemption
Setting configUSE_PREEMPTION to 1 enables preemptive scheduling.Final Answer:
#define configUSE_PREEMPTION 1 -> Option AQuick Check:
configUSE_PREEMPTION = 1 enables preemption [OK]
- Using 0 instead of 1 to enable preemption
- Using wrong macro names
- Using boolean true instead of 1
Solution
Step 1: Identify task priorities and running state
TaskA has priority 2 and is running; TaskB has higher priority 3 and becomes ready.Step 2: Apply preemptive scheduling rules
TaskB will preempt TaskA immediately and run first, printing its name.Final Answer:
TaskB prints immediately, preempting TaskA. -> Option BQuick Check:
Higher priority task runs first = TaskB prints first [OK]
- Assuming lower priority task finishes before switching
- Thinking tasks run at the same time
- Ignoring task priorities
#define configUSE_PREEMPTION 0
void Task1(void *pvParameters) {
while(1) {
// Task code
}
}
void Task2(void *pvParameters) {
while(1) {
// Task code
}
}Solution
Step 1: Check configUSE_PREEMPTION value
The macro is set to 0, which disables preemptive scheduling.Step 2: Understand effect on scheduling
With preemption disabled, tasks will not be interrupted automatically by higher priority tasks.Final Answer:
configUSE_PREEMPTION is set to 0, disabling preemption. -> Option AQuick Check:
configUSE_PREEMPTION = 0 disables preemption [OK]
- Thinking tasks must return int
- Assuming missing priorities cause preemption failure
- Believing vTaskDelay is required for preemption
Solution
Step 1: Identify task priorities and ready state
TaskX priority 2 is running; TaskY and TaskZ both have priority 3 and become ready simultaneously.Step 2: Understand FreeRTOS behavior with equal priority tasks
FreeRTOS uses time slicing (round-robin) between tasks of equal highest priority.Step 3: Determine which task runs first
Either TaskY or TaskZ can run first; the scheduler switches between them fairly.Final Answer:
Either TaskY or TaskZ runs first; FreeRTOS uses time slicing between equal priorities. -> Option CQuick Check:
Equal priority tasks share CPU time via time slicing [OK]
- Assuming creation order decides first run
- Thinking lower priority task continues running
- Believing one equal priority task always runs first
Ready to prove it?
Pass the test and this pattern moves unknown
