Scheduler¶
The RIOT scheduler.
RIOT features a tickless, preemptive, priority based scheduler. Context switches can occur either preemptively (i.e. on interrupts), voluntarily, or when a blocking operation (like msg_receive()
) is executed. Being tickless means it does not have a timer that fires periodically in order to emulate concurrent execution by switching threads continuously.
Priorities:¶
Every thread is given a priority on creation. The priority values are “order” or “nice” values, i.e. a higher value means a lower priority.
Example:¶
Given threads with priorities A=6, B=1, and C=3, B has the highest priority.
A higher priority means that the scheduler will run this thread whenever it becomes runnable instead of a thread with a lower priority. In case of equal priorities, the threads are scheduled in a semi-cooperative fashion. That means that unless an interrupt happens, threads with the same priority will only switch due to voluntary or implicit context switches.
Example:¶
Given threads with priorities A=6, B=1, and C=3, B has the highest priority.
A higher priority means that the scheduler will run this thread whenever it becomes runnable instead of a thread with a lower priority. In case of equal priorities, the threads are scheduled in a semi-cooperative fashion. That means that unless an interrupt happens, threads with the same priority will only switch due to voluntary or implicit context switches.
Interrupts:¶
When an interrupt occurs, e.g. because a timer fired or a network packet was received, the active context is saved and an interrupt service routine (ISR) that handles the interrupt is executed in another context. When the ISR is finished, the sched_context_switch_request
flag can be checked. In case it is set, the sched_run()
function is called to determine the next active thread. (In the special case that the ISR knows that it can not enable a thread switch, this check can of course be omitted.) If the flag is not set, the original context is being restored and the thread resumes immediately.
Voluntary Context Switches:¶
There are two function calls that can lead to a voluntary context switch: thread_yield()
and thread_sleep()
. While the latter disables (think blocks) the thread until it is woken (think unblocked) again via thread_wakeup()
, the former only leads to a context switch in case there is another runnable thread with at least the same priority.
Implicit Context Switches:¶
Some functions that unblock another thread, e.g. msg_send()
or mutex_unlock()
, can cause a thread switch, if the target had a higher priority.
-
unsigned int
sched_context_switch_request
¶ Flag indicating whether a context switch is necessary after handling an interrupt.
Supposed to be set in an ISR.
-
sched.h::thread_t
*sched_threads
()¶ Thread table.
-
sched.h::thread_t
*sched_active_thread
¶ Currently active thread.
-
int
sched_num_threads
¶ Number of running (non-terminated) threads.
-
kernel_types.h::kernel_pid_t
sched_active_pid
¶ Process ID of active thread.
-
clist.h::clist_node_t
sched_runqueues
()¶ List of runqueues per priority level.
-
int
sched_yield
(void)¶ Compilation with g++ may require the declaration of this function.
If implementation of this function is required, it can be realized in thread_arch.c.
-
int
sched_run
(void)¶ Triggers the scheduler to schedule the next thread.
Return values
- 1 if sched_active_thread/sched_active_pid was changed, 0 otherwise.
-
void
sched_set_status
(sched.h::thread_t
* process, unsigned int status)¶ Set the status of the specified process.
Parameters
process: Pointer to the thread control block of the targeted process status: The new status of this thread
-
void
sched_switch
(uint16_t other_prio)¶ Yield if approriate.
Either yield if other_prio is higher than the current priority, or if the current thread is not on the runqueue.
Depending on whether the current execution is in an ISR (
irq.h::irq_is_in()
),thread.h::thread_yield_higher()
is called orsched.h::sched_context_switch_request
is set, respectively.Parameters
other_prio: The priority of the target thread.
-
kernel_defines.h::NORETURN
voidcpu_switch_context_exit
(void)¶ Call context switching at thread exit.
-
kernel_defines.h::NORETURN
voidsched_task_exit
(void)¶ Removes thread from scheduler and set status to
thread.h::STATUS_STOPPED
.
-
SCHED_PRIO_LEVELS
¶ The number of thread priority levels.
1
16