Lazuli
Functions | Variables
scheduler.c File Reference

Lazuli scheduler implementation. More...

#include <stdint.h>
#include <Lazuli/common.h>
#include <Lazuli/config.h>
#include <Lazuli/lazuli.h>
#include <Lazuli/list.h>
#include <Lazuli/mutex.h>
#include <Lazuli/sys/arch/AVR/interrupts.h>
#include <Lazuli/sys/arch/arch.h>
#include <Lazuli/sys/clock_24.h>
#include <Lazuli/sys/compiler.h>
#include <Lazuli/sys/kernel.h>
#include <Lazuli/sys/memory.h>
#include <Lazuli/sys/scheduler.h>

Go to the source code of this file.

Functions

static void IdleTask (void)
 The scheduler idle task. More...
 
static void PrepareTaskContext (Task *const task)
 Prepare the first context of the task so it will be ready when switching context for the first time (i.e. More...
 
static bool PeriodComparer (const Task *const task1, const Task *const task2)
 Compare the "period" property of 2 tasks. More...
 
static bool PriorityComparer (const Task *const task1, const Task *const task2)
 Compare the "priority" property of 2 tasks. More...
 
static void InsertTaskByPriority (Lz_LinkedList *const list, Task *const taskToInsert, bool(*compareByProperty)(const Task *const, const Task *const))
 Insert a task in a list, keeping priorities ordered. More...
 
static TaskPickTaskToRun (void)
 Pick the task ready to run with the highest priority. More...
 
static void UpdateCyclicRealTimeTasks (void)
 Update all registered cyclic RT tasks. More...
 
static void UpdateTasksWaitingSoftwareTimer (void)
 Update all tasks waiting for the expiration of a software timer. More...
 
static void ManageCyclicRealTimeTask (void)
 Manage cyclic real-time tasks.
 
static void ManagePriorityRealTimeTask (void)
 Manage priority real-time tasks.
 
static void Schedule (void)
 Elect the new current task. More...
 
static TaskCallbackRegisterUserTask (const Lz_TaskConfiguration *const taskConfiguration)
 Callback of SchedulerOperations.registerTask() for registering a user task. More...
 
static TaskCallbackRegisterIdleTask (void)
 Callback of SchedulerOperations.registerTask() for registering the scheduler idle task. More...
 
static bool RegisterTask (void(*const taskEntryPoint)(void), Lz_TaskConfiguration *taskConfiguration, const bool isIdleTask)
 Register a new task. More...
 
static bool RegisterIdleTask (void)
 Register the idle task. More...
 
Kernel API
void Scheduler_Init (void)
 Initialize the scheduler prior to running it. More...
 
void Scheduler_AbortTask (void *const sp)
 Call the appropriate scheduler to abort the curent running task. More...
 
void Scheduler_HandleInterrupt (const uint8_t interruptCode)
 This function is called by arch-specific interrupt handling routine. More...
 
void Scheduler_HandleClockTick (void *const sp)
 This function is called when a clock tick occured, catch by the interrupt handler. More...
 
void Scheduler_WakeupTasksWaitingMutex (Lz_Mutex *const mutex)
 Wake up all tasks waiting for a mutex. More...
 
TaskScheduler_GetCurrentTask (void)
 Get a pointer to the current running task. More...
 
void Scheduler_SleepUntilEndOfTimeSlice (void)
 Put the current task to sleep until the end of its time slice.
 
User API
void Lz_TaskConfiguration_Init (Lz_TaskConfiguration *const taskConfiguration)
 Initialize an Lz_TaskConfiguration with default values for all parameters. More...
 
bool Lz_RegisterTask (void(*const taskEntryPoint)(void), Lz_TaskConfiguration *taskConfiguration)
 Register a new task. More...
 
void Lz_Run (void)
 Run the scheduler. More...
 
const char * Lz_Task_GetName (void)
 Get the name of the calling task. More...
 
void Lz_Task_WaitActivation (void)
 Set the calling task to wait for its next activation. More...
 
void Lz_Task_WaitInterrupt (uint8_t interruptCode)
 Wait for a specific interrupt to occur. More...
 
void Lz_WaitTimer (lz_u_resolution_unit_t units)
 Set the calling task to wait for the specified number of time resolution units (time slices), using the software timer. More...
 
void Lz_Task_Terminate (void)
 Terminate the calling task. More...
 

Variables

static TaskcurrentTask
 A pointer to the current running task.
 
static Lz_LinkedList readyTasks [__LZ_SCHEDULING_POLICY_ENUM_END]
 The queues of ready tasks for each scheduling policy. More...
 
static Lz_LinkedList waitingActivationTasks = LINKED_LIST_INIT
 The queue of tasks waiting activation. More...
 
static Lz_LinkedList waitingInterruptsTasks [INT_TOTAL]
 The table of waiting queues for interrupts. More...
 
static Lz_LinkedList waitingTimerTasks = LINKED_LIST_INIT
 The queue of tasks waiting for their software timer to reach expiration.
 
static Lz_LinkedList terminatedTasks = LINKED_LIST_INIT
 The queue of terminated tasks.
 
static Lz_LinkedList abortedTasks = LINKED_LIST_INIT
 The queue of aborted tasks.
 
static TaskidleTask
 The idle task. More...
 
static const Lz_TaskConfiguration DefaultTaskConfiguration
 Contains default values for Lz_TaskConfiguration. More...
 

Detailed Description

Lazuli scheduler implementation.

This file describes the implementation of the Lazuli scheduler.

Definition in file scheduler.c.

Function Documentation

◆ IdleTask()

static void IdleTask ( void  )
static

The scheduler idle task.

This task is executed when no other task is ready for execution.

Definition at line 100 of file scheduler.c.

◆ PrepareTaskContext()

static void PrepareTaskContext ( Task *const  task)
static

Prepare the first context of the task so it will be ready when switching context for the first time (i.e.

run the scheduler).

Parameters
taskA pointer to the Task to prepare.

Definition at line 116 of file scheduler.c.

◆ PeriodComparer()

static bool PeriodComparer ( const Task *const  task1,
const Task *const  task2 
)
static

Compare the "period" property of 2 tasks.

Parameters
task1A valid pointer to the first Task.
task2A valid pointer to the second Task.
Returns
  • true if task1 has a bigger period than task2.
  • false if task1 has a lower period than task2.

Definition at line 140 of file scheduler.c.

◆ PriorityComparer()

static bool PriorityComparer ( const Task *const  task1,
const Task *const  task2 
)
static

Compare the "priority" property of 2 tasks.

Parameters
task1A valid pointer to the first Task.
task2A valid pointer to the second Task.
Returns
  • true if task1 has a bigger priority than task2.
  • false if task1 has a lower priority than task2.

Definition at line 156 of file scheduler.c.

◆ InsertTaskByPriority()

static void InsertTaskByPriority ( Lz_LinkedList *const  list,
Task *const  taskToInsert,
bool(*)(const Task *const, const Task *const)  compareByProperty 
)
static

Insert a task in a list, keeping priorities ordered.

The priority is determined using the function pointer compareByProperty.

If tasks with the same priority than the taskToInsert already exist in the list, the taskToInsert will be inserted after existing tasks of the same priority.

Parameters
listThe list in which to insert the task.
taskToInsertThe task to insert in the list.
compareByPropertyA function pointer to the appropriate property comparer.

Definition at line 175 of file scheduler.c.

◆ PickTaskToRun()

static Task* PickTaskToRun ( void  )
static

Pick the task ready to run with the highest priority.

To perform that operation, we iterate ready tasks in each policy, from the highest priority to the lowest until we find a task that is ready to run.

If no task is ready to run, we pick the idle task.

Returns
A valid pointer to the next task to run.

Definition at line 217 of file scheduler.c.

◆ UpdateCyclicRealTimeTasks()

static void UpdateCyclicRealTimeTasks ( void  )
static

Update all registered cyclic RT tasks.

This is to be done at every clock tick.

Definition at line 243 of file scheduler.c.

◆ UpdateTasksWaitingSoftwareTimer()

static void UpdateTasksWaitingSoftwareTimer ( void  )
static

Update all tasks waiting for the expiration of a software timer.

This is to be done at every clock tick.

Definition at line 285 of file scheduler.c.

◆ Schedule()

static void Schedule ( void  )
static

Elect the new current task.

The election is done by setting the currentTask pointer to the elected task.

This function is called at each clock tick (triggered by the timer at the rate of the system time resolution).

This function updates all tasks lists accordingly to the different real-time parameters and status of each task.

Definition at line 379 of file scheduler.c.

◆ CallbackRegisterUserTask()

static Task* CallbackRegisterUserTask ( const Lz_TaskConfiguration *const  taskConfiguration)
static

Callback of SchedulerOperations.registerTask() for registering a user task.

Parameters
taskConfigurationA pointer to an Lz_TaskConfiguration containing the configuration of the task being registered. This parameter can never be NULL, but some of its fields can contain default configuration values.
Returns
A pointer to the newly allocated and initialized Task.

Definition at line 421 of file scheduler.c.

◆ CallbackRegisterIdleTask()

static Task* CallbackRegisterIdleTask ( void  )
static

Callback of SchedulerOperations.registerTask() for registering the scheduler idle task.

Returns
A pointer to the allocated and initialized idle Task.

Definition at line 474 of file scheduler.c.

◆ RegisterTask()

static bool RegisterTask ( void(*)(void)  taskEntryPoint,
Lz_TaskConfiguration taskConfiguration,
const bool  isIdleTask 
)
static

Register a new task.

Parameters
taskEntryPointThe entry point of the task to register. i.e. A pointer to the function representing the task.
taskConfigurationA pointer to an Lz_TaskConfiguration containing the configuration of the task being registered. If NULL is passed, then default values are applied for all parameters.
isIdleTaskA boolean value indicating that the task to register is the scheduler idle task.
Returns
  • true if the task has been registered without error.
  • false if an error occured during registration.

Definition at line 503 of file scheduler.c.

◆ RegisterIdleTask()

static bool RegisterIdleTask ( void  )
static

Register the idle task.

Returns
  • true if the task has been registered without error.
  • false if an error occured during registration.

Definition at line 563 of file scheduler.c.

◆ Scheduler_Init()

void Scheduler_Init ( void  )

Initialize the scheduler prior to running it.

This function is called by kernel initialization.

Definition at line 613 of file scheduler.c.

◆ Scheduler_AbortTask()

void Scheduler_AbortTask ( void *const  sp)

Call the appropriate scheduler to abort the curent running task.

Parameters
spThe stack pointer of the running task after saving its context.

Definition at line 632 of file scheduler.c.

◆ Scheduler_HandleInterrupt()

void Scheduler_HandleInterrupt ( const uint8_t  interruptCode)

This function is called by arch-specific interrupt handling routine.

This function is executed in the context of the current running task, i.e. on its stack.

Parameters
interruptCodeThe code of the interrupt being handled.

Definition at line 657 of file scheduler.c.

◆ Scheduler_HandleClockTick()

void Scheduler_HandleClockTick ( void *const  sp)

This function is called when a clock tick occured, catch by the interrupt handler.

Parameters
spThe stack pointer of the current running task after saving its context.

Definition at line 680 of file scheduler.c.

◆ Scheduler_WakeupTasksWaitingMutex()

void Scheduler_WakeupTasksWaitingMutex ( Lz_Mutex *const  mutex)

Wake up all tasks waiting for a mutex.

Parameters
mutexA pointer to the mutex the tasks are waiting for.

Definition at line 694 of file scheduler.c.

◆ Scheduler_GetCurrentTask()

Task* Scheduler_GetCurrentTask ( void  )

Get a pointer to the current running task.

Returns
A valid pointer to the current running task.

Definition at line 720 of file scheduler.c.

◆ Lz_TaskConfiguration_Init()

void Lz_TaskConfiguration_Init ( Lz_TaskConfiguration *const  taskConfiguration)

Initialize an Lz_TaskConfiguration with default values for all parameters.

No function is provided for allocating a new Lz_TaskConfiguration. So it is strongly advised to allocate the Lz_TaskConfiguration parameter on the stack before calling this function.

Parameters
taskConfigurationA pointer to the Lz_TaskConfiguration to initialize.

Definition at line 746 of file scheduler.c.

◆ Lz_RegisterTask()

bool Lz_RegisterTask ( void(*)(void)  taskEntryPoint,
Lz_TaskConfiguration taskConfiguration 
)

Register a new task.

If an error occured during registration of the task false is returned and the task is not included in the set of tasks that will be run.

Parameters
taskEntryPointThe entry point of the task to register. i.e. A pointer to the function representing the task.
taskConfigurationA pointer to an Lz_TaskConfiguration containing the configuration of the task being registered. If NULL is passed, then default values are applied for all parameters.
Returns
  • true if the task has been registered without error.
  • false if an error occured during registration.

Definition at line 758 of file scheduler.c.

◆ Lz_Run()

void Lz_Run ( void  )

Run the scheduler.

Start scheduling tasks.

Definition at line 765 of file scheduler.c.

◆ Lz_Task_GetName()

const char* Lz_Task_GetName ( void  )

Get the name of the calling task.

Returns
A pointer to a string containing the name of the current running task, or NULL if the task has no name.

Definition at line 779 of file scheduler.c.

◆ Lz_Task_WaitActivation()

void Lz_Task_WaitActivation ( void  )

Set the calling task to wait for its next activation.

May be used if the task finnished its work without consuming all of its completion time.

Attention
Only tasks with scheduling policy CYCLIC_RT can wait for next activation.

Definition at line 785 of file scheduler.c.

◆ Lz_Task_WaitInterrupt()

void Lz_Task_WaitInterrupt ( uint8_t  interruptCode)

Wait for a specific interrupt to occur.

Puts the calling task to sleep until the specified interrupt occurs.

Parameters
interruptCodeThe code of the interrupt to wait for.
Attention
Only tasks with scheduling policy PRIORITY_RT can wait for interrupts.

Definition at line 793 of file scheduler.c.

◆ Lz_WaitTimer()

void Lz_WaitTimer ( lz_u_resolution_unit_t  units)

Set the calling task to wait for the specified number of time resolution units (time slices), using the software timer.

As Lazuli is a time sliced operating system, the effective waiting will start at the end of the current time slice. This means that the real waiting time starting from the calling of this function will be:

units / clock resolution frequency <= waiting time AND waiting time < (units + 1) / clock resolution frequency

See the configuration option LZ_CONFIG_SYSTEM_CLOCK_RESOLUTION_FREQUENCY.

Parameters
unitsThe number of time slices to wait.
Warning
Only works for tasks with PRIORITY_RT policy.

Definition at line 804 of file scheduler.c.

◆ Lz_Task_Terminate()

void Lz_Task_Terminate ( void  )

Terminate the calling task.

The context of the task will be saved on its stack.

Calling this function has the same effect than returning from the task's main function.

The terminated task will never be scheduled again.

Definition at line 815 of file scheduler.c.

Variable Documentation

◆ readyTasks

Lz_LinkedList readyTasks[__LZ_SCHEDULING_POLICY_ENUM_END]
static

The queues of ready tasks for each scheduling policy.

Attention
Indexed from highest priority policy to lowest.

Definition at line 40 of file scheduler.c.

◆ waitingActivationTasks

Lz_LinkedList waitingActivationTasks = LINKED_LIST_INIT
static

The queue of tasks waiting activation.

i.e. Tasks that have come to completion for their period.

Next status for these tasks is: READY.

Definition at line 49 of file scheduler.c.

◆ waitingInterruptsTasks

Lz_LinkedList waitingInterruptsTasks[INT_TOTAL]
static

The table of waiting queues for interrupts.

This table contains one entry per interrupt type. In each entry is the queue of tasks waiting for that particular interrupt. This table is indexed by the codes defined in interrupts.h.

Definition at line 58 of file scheduler.c.

◆ idleTask

Task* idleTask
static

The idle task.

This task is run when no other task is ready to run.

Definition at line 80 of file scheduler.c.

◆ DefaultTaskConfiguration

const Lz_TaskConfiguration DefaultTaskConfiguration
static
Initial value:
= {
NULL ,
0 ,
0 ,
0
}
const size_t LZ_CONFIG_DEFAULT_TASK_STACK_SIZE
Default stack size in bytes for a new task.
#define NULL
NULL pointer.
Definition: common.h:68
Priority time sliced real-time scheduling.
Definition: lazuli.h:65

Contains default values for Lz_TaskConfiguration.

Definition at line 85 of file scheduler.c.