In a preemptive RTOS scheduler, when does a running thread stop running, and what does time-slice scheduling add?
A running thread keeps the processor until it finishes, a higher-priority thread becomes ready, or it gives up the processor to wait for something (e.g. calls sleep). Time slicing additionally guarantees that threads of equal priority each get a turn.
The scheduler decides which thread runs. Preemptive scheduling is the most common type of RTOS scheduler, and it has exactly three reasons to switch away from the running thread:
- It finishes.
- A higher-priority thread becomes ready, for example because an interrupt delivered the data it was waiting for. The running thread is preempted immediately.
- It gives up the processor while waiting for a resource or a delay, for example by calling
sleep()orvTaskDelay(), or waiting on a queue.
Notice what is not on the list: running for a long time. Under pure priority scheduling, a high-priority task stuck in a loop starves everything below it.
Time-slice scheduling addresses threads of the same priority. A timer tick divides time into slots, and at each tick the scheduler rotates among equal-priority ready threads, so each is guaranteed a slot to execute. FreeRTOS combines both: preemptive by priority, with time slicing among equals.
Tip: higher priority wins immediately; equal priority takes turns.
Go deeper:
FreeRTOS — Scheduling — fixed-priority preemptive scheduling with time slicing, and the single-core vs SMP variants.
DigiKey — Introduction to RTOS Part 3: Task Scheduling — preemption and time slicing demonstrated with two tasks on an ESP32.