Scheduling

The scheduler is a part of the Sirius RTOS kernel that decides which task should run. It is a preemptive, priority-based, round-robin scheduler.

Priority-based scheduling

Priority scheduling ensures that only the highest priority tasks, in ready state, can be executed. So, only the most important tasks in the system are performed.

Round-robin scheduling

When many tasks are in ready state and have the same priority, the Round-Robin algorithm is used to activate a task that has not been used from the longest time. This ensures a fair assignation of CPU time for each ready to run task.

The tasks are not simply stored at the end of the ready-to-run queue (like most of the current RTOS do). The scheduler ensures that it is started task that has not been run from the longest time. For example when osSleep(25) is performed, the task is blocked for specified amount of time and then it will be released when all other ready tasks with the same priority have been executed at least once. This time the task will run immediately. This applies to all Sirius RTOS features beside task creating and resuming by osCreateTask and osResumeTask functions. They are designed for special purposes, such as tasks creation, or task renewal after interrupt reception. It may be decided during system configuration whether tasks in this case should be addend into the end or the beginning of the ready-to-run tasks queue. If in the beginning of the queue the OS_RESUME_IMMEDIATELY constant should be set to 1, otherwise to 0.

Time quanta

Each task can have assigned an individual number of CPU time slices (called a time quanta), during every single cycle of the Round-Robin algorithm. When several tasks with the same priority are performed, every time, when the preemption occurs, the scheduler assigns to the task a specified number of the CPU time slices. This allows to decide which task should run more often. This feature is available only, when the OS_TASK_QUANTUM_FUNC constant is set to 1. It also makes available osSetTaskQuantum and osGetTaskQuantum functions that allow modifying a number of time quanta that are assigned to a task.

Yielding task execution

Each task can voluntarily yields its execution to another task, by calling osSleep(0) function. When a running (current) task changes the object state into signaled and if any task with the higher priority is waiting for this object, the current task will yields its execution to immediately run task with higher priority. In case, that described situation occurs in an ISR (after call of osEnterISR function), the yielding will be delayed until osLeaveISR function is executed.

System time

Each system operation that depends on specified time is performed only when the scheduler is called. It applies to wait timeouts, sleeping and timer objects. By default, the scheduler is called on every millisecond, so after calling the osSleep for one millisecond, the task will become ready after less than one millisecond.

The time is specified in a time units that depends on AR_TICKS_PER_SECOND constant specific for used architecture. When port files provided by SpaceShadow are used, it is always set to 1000 that respond to one millisecond interval. In this case the time passed to each system function is specified in milliseconds.

System uses arGetTickCount function, to obtain the current system time. It provides the time in time units, counted from the system startup. This function often returns a 32-bit value, that allow to count up to 322-1 and then roll over to 0. For one millisecond interval, the roll over will happen after circa 49,7 days. When the roll over occurs, the system may become unstable. It can be avoided by using 64-bit wide integer.

Power saving (the idle task)

Every time, when CPU is not used (all tasks are blocked or wait for an event) the idle task is started. It performs an arSavePower function that switches the CPU to power-save mode. The CPU is resumed on every interrupt. The idle task, like other tasks has his own stack, which size is determined by OS_IDLE_STACK_SIZE.

System statistics

System provides basic information on the CPU load. This feature is only enabled, when the OS_GET_SYSTEM_STAT_FUNC or OS_GET_TASK_STAT_FUNCconstants are set for 1. They enable osGetSystemStat or osGetTaskStatfunctions, that returns a total CPU load or for each task separately. The OS_STAT_SAMPLE_RATE constant defines sampling rate for calculating a statistics. It is defined in time units, and by default it is set to 100 time units.

SpaceShadow documentation