The RIOT scheduler.
More...
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.
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.
|
file | sched.h |
| Scheduler API definition.
|
|
|
Keep in sync with OpenOCD src/rtos/riot.c
|
enum | thread_status_t {
STATUS_STOPPED
, STATUS_ZOMBIE
, STATUS_SLEEPING
, STATUS_MUTEX_BLOCKED
,
STATUS_RECEIVE_BLOCKED
, STATUS_SEND_BLOCKED
, STATUS_REPLY_BLOCKED
, STATUS_FLAG_BLOCKED_ANY
,
STATUS_FLAG_BLOCKED_ALL
, STATUS_MBOX_BLOCKED
, STATUS_COND_BLOCKED
, STATUS_RUNNING
,
STATUS_PENDING
, STATUS_NUMOF
} |
|
◆ KERNEL_PID_FIRST
The first valid PID (inclusive).
Definition at line 115 of file sched.h.
◆ KERNEL_PID_LAST
The last valid PID (inclusive).
Definition at line 120 of file sched.h.
◆ KERNEL_PID_UNDEF
#define KERNEL_PID_UNDEF 0 |
Canonical identifier for an invalid PID.
Definition at line 110 of file sched.h.
◆ MAXTHREADS
The maximum number of threads to be scheduled.
Definition at line 103 of file sched.h.
◆ PRIkernel_pid
#define PRIkernel_pid PRIi16 |
Macro for printing formatter.
Definition at line 125 of file sched.h.
◆ SCHED_PRIO_LEVELS
#define SCHED_PRIO_LEVELS 16 |
The number of thread priority levels.
Definition at line 194 of file sched.h.
◆ SCHED_TEST_STACK
#define SCHED_TEST_STACK 1 |
Enables detection of stack overflows and measures stack usage when != 0.
Definition at line 132 of file sched.h.
◆ STATUS_NOT_FOUND
Describes an illegal thread status.
Definition at line 187 of file sched.h.
◆ STATUS_ON_RUNQUEUE
to check if on run queue: st >= STATUS_ON_RUNQUEUE
Definition at line 186 of file sched.h.
◆ kernel_pid_t
Unique process identifier.
Definition at line 139 of file sched.h.
◆ sched_callback_t
Scheduler run callback.
- Note
- Both
active
and next
can be KERNEL_PID_UNDEF, but not at the same time.
- Parameters
-
active | Pid of the active thread pid |
next | Pid of the next scheduled thread |
Definition at line 298 of file sched.h.
◆ thread_t
forward declaration for thread_t, defined in thread.h
Definition at line 155 of file sched.h.
◆ thread_status_t
Enumerator |
---|
STATUS_STOPPED | has terminated
|
STATUS_ZOMBIE | has terminated & keeps thread's thread_t
|
STATUS_SLEEPING | sleeping
|
STATUS_MUTEX_BLOCKED | waiting for a locked mutex
|
STATUS_RECEIVE_BLOCKED | waiting for a message
|
STATUS_SEND_BLOCKED | waiting for message to be delivered
|
STATUS_REPLY_BLOCKED | waiting for a message response
|
STATUS_FLAG_BLOCKED_ANY | waiting for any flag from flag_mask
|
STATUS_FLAG_BLOCKED_ALL | waiting for all flags in flag_mask
|
STATUS_MBOX_BLOCKED | waiting for get/put on mbox
|
STATUS_COND_BLOCKED | waiting for a condition variable
|
STATUS_RUNNING | currently running
|
STATUS_PENDING | waiting to be scheduled to run
|
STATUS_NUMOF | number of supported thread states
|
Definition at line 163 of file sched.h.
◆ pid_is_valid()
Determine if the given pid is valid.
- Parameters
-
- Returns
- true if the pid is valid, false otherwise
Definition at line 148 of file sched.h.
◆ sched_arch_idle()
void sched_arch_idle |
( |
void |
| ) |
|
Set CPU to idle mode (CPU dependent)
Only used when there's no idle thread.
This function will be called by the scheduler when there's no runnable thread. It will be called from ISR context, and must allow other ISR handlers to be run. E.g., on Cortex-M, the PendSV priority is temporarily lowered (set to higher value) in order to enable other exceptions to be run.
This function should also invoke setting a low power mode, e.g., by calling 'pm_set_lowest()'.
◆ sched_change_priority()
void sched_change_priority |
( |
thread_t * |
thread, |
|
|
uint8_t |
priority |
|
) |
| |
Change the priority of the given thread.
- Note
- This functions expects interrupts to be disabled when called!
- Precondition
- (thread != NULL)
-
(priority < SCHED_PRIO_LEVELS)
- Parameters
-
[in,out] | thread | target thread |
[in] | priority | new priority to assign to thread |
◆ sched_register_cb()
Register a callback that will be called on every scheduler run.
- Parameters
-
[in] | callback | The callback functions that will be called |
◆ sched_run()
Triggers the scheduler to schedule the next thread.
- Returns
- The new thread to schedule if sched_active_thread/sched_active_pid was changed,
-
NULL if the active thread was not changed.
◆ sched_runq_advance()
static void sched_runq_advance |
( |
uint8_t |
prio | ) |
|
|
inlinestatic |
Advance a runqueue.
Advances the runqueue of that priority by one step to the next thread in that priority. Next time that priority is scheduled the now first thread will get activated. Calling this will not start the scheduler.
- Warning
- This API is not intended for out of tree users. Breaking API changes will be done without notice and without deprecation. Consider yourself warned!
- Parameters
-
prio | The priority of the runqueue to advance |
Definition at line 323 of file sched.h.
◆ sched_runq_callback()
void sched_runq_callback |
( |
uint8_t |
prio | ) |
|
|
extern |
Scheduler runqueue (change) callback.
Function has to be provided by the user of this API. It will be called:
- when the scheduler is run,
- when a thread enters the active queue or
- when the last thread leaves a queue
- Warning
- This API is not intended for out of tree users. Breaking API changes will be done without notice and without deprecation. Consider yourself warned!
- Parameters
-
prio | the priority of the runqueue that changed |
◆ sched_runq_exactly_one()
static int sched_runq_exactly_one |
( |
uint8_t |
prio | ) |
|
|
inlinestatic |
Tell if the number of threads in a runqueue is 1.
- Parameters
-
[in] | prio | The priority of the runqueue to get information of |
- Returns
- Truth value for that information
- Warning
- This API is not intended for out of tree users.
Definition at line 367 of file sched.h.
◆ sched_runq_is_empty()
static int sched_runq_is_empty |
( |
uint8_t |
prio | ) |
|
|
inlinestatic |
Tell if the number of threads in a runqueue is 0.
- Parameters
-
[in] | prio | The priority of the runqueue to get information of |
- Returns
- Truth value for that information
- Warning
- This API is not intended for out of tree users.
Definition at line 355 of file sched.h.
◆ sched_runq_more_than_one()
static int sched_runq_more_than_one |
( |
uint8_t |
prio | ) |
|
|
inlinestatic |
Tell if the number of threads in a runqueue greater than 1.
- Parameters
-
[in] | prio | The priority of the runqueue to get information of |
- Returns
- Truth value for that information
- Warning
- This API is not intended for out of tree users.
Definition at line 379 of file sched.h.
◆ sched_set_status()
Set the status of the specified process.
- Parameters
-
[in] | process | Pointer to the thread control block of the targeted process |
[in] | status | The new status of this thread |
◆ sched_switch()
void sched_switch |
( |
uint16_t |
other_prio | ) |
|
Yield if appropriate.
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_is_in()), thread_yield_higher() is called or sched_context_switch_request is set, respectively.
- Parameters
-
[in] | other_prio | The priority of the target thread. |
◆ sched_context_switch_request
volatile unsigned int sched_context_switch_request |
|
extern |
Flag indicating whether a context switch is necessary after handling an interrupt.
Supposed to be set in an ISR.