distortos  v0.7.0
object-oriented C++ RTOS for microcontrollers
distortos::internal::Scheduler Class Reference

Scheduler class is a system's scheduler. More...

#include "distortos/internal/scheduler/Scheduler.hpp"

Collaboration diagram for distortos::internal::Scheduler:
[legend]

Public Member Functions

constexpr Scheduler ()
 Scheduler's constructor. More...
 
int add (ThreadControlBlock &threadControlBlock)
 Adds new ThreadControlBlock to scheduler. More...
 
int block (ThreadList &container, ThreadState state, const UnblockFunctor *unblockFunctor={})
 Blocks current thread, transferring it to provided container. More...
 
int block (ThreadList &container, ThreadList::iterator iterator, ThreadState state, const UnblockFunctor *unblockFunctor={})
 Blocks thread, transferring it to provided container. More...
 
int blockUntil (ThreadList &container, ThreadState state, TickClock::time_point timePoint, const UnblockFunctor *unblockFunctor={})
 Blocks current thread with timeout, transferring it to provided container. More...
 
uint64_t getContextSwitchCount () const
 
ThreadControlBlockgetCurrentThreadControlBlock () const
 
SoftwareTimerSupervisorgetSoftwareTimerSupervisor ()
 
const SoftwareTimerSupervisorgetSoftwareTimerSupervisor () const
 
uint64_t getTickCount () const
 
int initialize (ThreadControlBlock &mainThreadControlBlock)
 Scheduler's initialization. More...
 
void maybeRequestContextSwitch () const
 Requests context switch if it is needed. More...
 
int remove ()
 Removes current thread from Scheduler's control. More...
 
int resume (ThreadList::iterator iterator)
 Resumes suspended thread. More...
 
int suspend ()
 Suspends current thread. More...
 
int suspend (ThreadList::iterator iterator)
 Suspends thread. More...
 
void * switchContext (void *stackPointer)
 Called by architecture-specific code to do final context switch. More...
 
bool tickInterruptHandler ()
 Handler of "tick" interrupt. More...
 
void unblock (ThreadList::iterator iterator, UnblockReason unblockReason=UnblockReason::unblockRequest)
 Unblocks provided thread, transferring it from it's current container to "runnable" container. More...
 
void yield ()
 Yields time slot of the scheduler to next thread. More...
 

Private Member Functions

int addInternal (ThreadControlBlock &threadControlBlock)
 Adds new ThreadControlBlock to scheduler. More...
 
int blockInternal (ThreadList &container, ThreadList::iterator iterator, ThreadState state, const UnblockFunctor *unblockFunctor)
 Blocks thread, transferring it to provided container. More...
 
bool isContextSwitchRequired () const
 Tests whether context switch is required or not. More...
 
void unblockInternal (ThreadList::iterator iterator, UnblockReason unblockReason)
 Unblocks provided thread, transferring it from it's current container to "runnable" container. More...
 

Private Attributes

ThreadList::iterator currentThreadControlBlock_
 iterator to the currently active ThreadControlBlock More...
 
ThreadList runnableList_
 list of ThreadControlBlock elements in "runnable" state, sorted by priority in descending order More...
 
ThreadList suspendedList_
 list of ThreadControlBlock elements in "suspended" state, sorted by priority in descending order More...
 
SoftwareTimerSupervisor softwareTimerSupervisor_
 internal SoftwareTimerSupervisor object More...
 
uint64_t contextSwitchCount_
 number of context switches More...
 
uint64_t tickCount_
 tick count More...
 

Detailed Description

Scheduler class is a system's scheduler.

Constructor & Destructor Documentation

◆ Scheduler()

constexpr distortos::internal::Scheduler::Scheduler ( )
inline

Scheduler's constructor.

Member Function Documentation

◆ add()

int distortos::internal::Scheduler::add ( ThreadControlBlock threadControlBlock)

Adds new ThreadControlBlock to scheduler.

ThreadControlBlock's state is changed to "runnable".

Parameters
[in]threadControlBlockis a reference to added ThreadControlBlock object
Returns
0 on success, error code otherwise:
Here is the call graph for this function:
Here is the caller graph for this function:

◆ addInternal()

int distortos::internal::Scheduler::addInternal ( ThreadControlBlock threadControlBlock)
private

Adds new ThreadControlBlock to scheduler.

Internal version - without interrupt masking and call to Scheduler::maybeRequestContextSwitch()

Parameters
[in]threadControlBlockis a reference to added ThreadControlBlock object
Returns
0 on success, error code otherwise:
Here is the call graph for this function:
Here is the caller graph for this function:

◆ block() [1/2]

int distortos::internal::Scheduler::block ( ThreadList container,
ThreadState  state,
const UnblockFunctor unblockFunctor = {} 
)

Blocks current thread, transferring it to provided container.

Warning
This function must not be called from interrupt context!
Parameters
[in]containeris a reference to destination container to which the thread will be transferred
[in]stateis the new state of thread that will be blocked
[in]unblockFunctoris a pointer to UnblockFunctor which will be executed in ThreadControlBlock::unblockHook(), default - nullptr (no functor will be executed)
Returns
0 on success, error code otherwise:
Here is the caller graph for this function:

◆ block() [2/2]

int distortos::internal::Scheduler::block ( ThreadList container,
ThreadList::iterator  iterator,
ThreadState  state,
const UnblockFunctor unblockFunctor = {} 
)

Blocks thread, transferring it to provided container.

The thread must be on "runnable" list - trying to block thread in other state is an error.

Parameters
[in]containeris a reference to destination container to which the thread will be transferred
[in]iteratoris the iterator to the thread that will be blocked
[in]stateis the new state of thread that will be blocked
[in]unblockFunctoris a pointer to UnblockFunctor which will be executed in ThreadControlBlock::unblockHook(), default - nullptr (no functor will be executed)
Returns
0 on success, error code otherwise:
  • EINTR - thread was unblocked with UnblockReason::signal (possible only when blocking current thread);
  • EINVAL - provided thread is not on "runnable" list;
  • ETIMEDOUT - thread was unblocked with UnblockReason::timeout (possible only when blocking current thread);
Here is the call graph for this function:

◆ blockInternal()

int distortos::internal::Scheduler::blockInternal ( ThreadList container,
ThreadList::iterator  iterator,
ThreadState  state,
const UnblockFunctor unblockFunctor 
)
private

Blocks thread, transferring it to provided container.

Internal version - without interrupt masking and forced context switch.

Parameters
[in]containeris a reference to destination container to which the thread will be transferred
[in]iteratoris the iterator to the thread that will be blocked
[in]stateis the new state of thread that will be blocked
[in]unblockFunctoris a pointer to UnblockFunctor which will be executed in ThreadControlBlock::unblockHook()
Returns
0 on success, error code otherwise:
  • EINVAL - provided thread is not on "runnable" list;
Here is the call graph for this function:
Here is the caller graph for this function:

◆ blockUntil()

int distortos::internal::Scheduler::blockUntil ( ThreadList container,
ThreadState  state,
TickClock::time_point  timePoint,
const UnblockFunctor unblockFunctor = {} 
)

Blocks current thread with timeout, transferring it to provided container.

Warning
This function must not be called from interrupt context!
Parameters
[in]containeris a reference to destination container to which the thread will be transferred
[in]stateis the new state of thread that will be blocked
[in]timePointis the time point at which the thread will be unblocked (if not already unblocked)
[in]unblockFunctoris a pointer to UnblockFunctor which will be executed in ThreadControlBlock::unblockHook(), default - nullptr (no functor will be executed)
Returns
0 on success, error code otherwise:
  • EINTR - thread was unblocked with UnblockReason::signal;
  • ETIMEDOUT - thread was unblocked because timePoint was reached;
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getContextSwitchCount()

uint64_t distortos::internal::Scheduler::getContextSwitchCount ( ) const
Returns
number of context switches
Here is the caller graph for this function:

◆ getCurrentThreadControlBlock()

ThreadControlBlock& distortos::internal::Scheduler::getCurrentThreadControlBlock ( ) const
inline
Returns
reference to currently active ThreadControlBlock
Here is the caller graph for this function:

◆ getSoftwareTimerSupervisor() [1/2]

SoftwareTimerSupervisor& distortos::internal::Scheduler::getSoftwareTimerSupervisor ( )
inline
Returns
reference to internal SoftwareTimerSupervisor object

◆ getSoftwareTimerSupervisor() [2/2]

const SoftwareTimerSupervisor& distortos::internal::Scheduler::getSoftwareTimerSupervisor ( ) const
inline
Returns
const reference to internal SoftwareTimerSupervisor object

◆ getTickCount()

uint64_t distortos::internal::Scheduler::getTickCount ( ) const
Returns
current value of tick count
Here is the caller graph for this function:

◆ initialize()

int distortos::internal::Scheduler::initialize ( ThreadControlBlock mainThreadControlBlock)

Scheduler's initialization.

Attention
This must be called after constructor, before enabling any scheduling. Priority of main thread must be higher than priority of idle thread
Parameters
[in]mainThreadControlBlockis a reference to ThreadControlBlock object of main() thread
Returns
0 on success, error code otherwise:
Here is the call graph for this function:

◆ isContextSwitchRequired()

bool distortos::internal::Scheduler::isContextSwitchRequired ( ) const
private

Tests whether context switch is required or not.

Context switch is required in following situations:

  • current thread is no longer on "runnable" list,
  • current thread is no longer on the beginning of the "runnable" list (because higher-priority thread is available or current thread was "rotated" due to round-robin scheduling policy).
Returns
true if context switch is required
Here is the call graph for this function:
Here is the caller graph for this function:

◆ maybeRequestContextSwitch()

void distortos::internal::Scheduler::maybeRequestContextSwitch ( ) const

Requests context switch if it is needed.

Attention
This function must be called with interrupt masking enabled.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove()

int distortos::internal::Scheduler::remove ( )

Removes current thread from Scheduler's control.

Thread's state is changed to "terminated".

Note
This function must be called with masked interrupts.
This function can be used only after thread's function returns an all cleanup is done.
Warning
This function must not be called from interrupt context!
Returns
0 on success, error code otherwise:
  • EINVAL - provided thread is not on "runnable" list and cannot be removed/terminated;
Here is the call graph for this function:
Here is the caller graph for this function:

◆ resume()

int distortos::internal::Scheduler::resume ( ThreadList::iterator  iterator)

Resumes suspended thread.

The thread must be on the "suspended" list - trying to resume thread that is not suspended is an error.

Parameters
[in]iteratoris the iterator to the thread that will be resumed
Returns
0 on success, error code otherwise:
  • EINVAL - provided thread is not on "suspended" list;
Here is the call graph for this function:

◆ suspend() [1/2]

int distortos::internal::Scheduler::suspend ( )

Suspends current thread.

Warning
This function must not be called from interrupt context!
Returns
0 on success, error code otherwise:

◆ suspend() [2/2]

int distortos::internal::Scheduler::suspend ( ThreadList::iterator  iterator)

Suspends thread.

The thread must be on "runnable" list - trying to suspend thread in other state is an error.

Parameters
[in]iteratoris the iterator to the thread that will be suspended
Returns
0 on success, error code otherwise:
  • EINTR - thread was unblocked with UnblockReason::signal;
  • EINVAL - provided thread is not on "runnable" list;
Here is the call graph for this function:

◆ switchContext()

void * distortos::internal::Scheduler::switchContext ( void *  stackPointer)

Called by architecture-specific code to do final context switch.

Current task is suspended and the next available task is started. This function also checks "stack guard" when this functionality is enabled - if the check fails, FATAL_ERROR() is called.

Parameters
[in]stackPointeris the current value of current thread's stack pointer
Returns
new thread's stack pointer
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tickInterruptHandler()

bool distortos::internal::Scheduler::tickInterruptHandler ( )

Handler of "tick" interrupt.

This function also checks "stack guard" when this functionality is enabled - if the check fails, FATAL_ERROR() is called.

Note
this must not be called by user code
Returns
true if context switch is required, false otherwise
Here is the call graph for this function:

◆ unblock()

void distortos::internal::Scheduler::unblock ( ThreadList::iterator  iterator,
UnblockReason  unblockReason = UnblockReason::unblockRequest 
)

Unblocks provided thread, transferring it from it's current container to "runnable" container.

Current container of the thread is obtained with ThreadControlBlock::getList().

Parameters
[in]iteratoris the iterator which points to unblocked thread
[in]unblockReasonis the reason of unblocking of the thread, default - UnblockReason::unblockRequest
Here is the call graph for this function:
Here is the caller graph for this function:

◆ unblockInternal()

void distortos::internal::Scheduler::unblockInternal ( ThreadList::iterator  iterator,
UnblockReason  unblockReason 
)
private

Unblocks provided thread, transferring it from it's current container to "runnable" container.

Current container of the thread is obtained with ThreadControlBlock::getList(). Round-robin quantum of thread is reset.

Note
Internal version - without interrupt masking and yield()
Parameters
[in]iteratoris the iterator which points to unblocked thread
[in]unblockReasonis the reason of unblocking of the thread
Here is the call graph for this function:
Here is the caller graph for this function:

◆ yield()

void distortos::internal::Scheduler::yield ( )

Yields time slot of the scheduler to next thread.

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ contextSwitchCount_

uint64_t distortos::internal::Scheduler::contextSwitchCount_
private

number of context switches

◆ currentThreadControlBlock_

ThreadList::iterator distortos::internal::Scheduler::currentThreadControlBlock_
private

iterator to the currently active ThreadControlBlock

◆ runnableList_

ThreadList distortos::internal::Scheduler::runnableList_
private

list of ThreadControlBlock elements in "runnable" state, sorted by priority in descending order

◆ softwareTimerSupervisor_

SoftwareTimerSupervisor distortos::internal::Scheduler::softwareTimerSupervisor_
private

internal SoftwareTimerSupervisor object

◆ suspendedList_

ThreadList distortos::internal::Scheduler::suspendedList_
private

list of ThreadControlBlock elements in "suspended" state, sorted by priority in descending order

◆ tickCount_

uint64_t distortos::internal::Scheduler::tickCount_
private

tick count


The documentation for this class was generated from the following files: