aboutsummaryrefslogtreecommitdiffstats
path: root/include/distortos/internal/scheduler
diff options
context:
space:
mode:
Diffstat (limited to 'include/distortos/internal/scheduler')
-rw-r--r--include/distortos/internal/scheduler/DynamicThreadBase.hpp231
-rw-r--r--include/distortos/internal/scheduler/MainThread.hpp46
-rw-r--r--include/distortos/internal/scheduler/RoundRobinQuantum.hpp123
-rw-r--r--include/distortos/internal/scheduler/Scheduler.hpp351
-rw-r--r--include/distortos/internal/scheduler/SoftwareTimerControlBlock.hpp111
-rw-r--r--include/distortos/internal/scheduler/SoftwareTimerList.hpp62
-rw-r--r--include/distortos/internal/scheduler/SoftwareTimerListNode.hpp82
-rw-r--r--include/distortos/internal/scheduler/SoftwareTimerSupervisor.hpp66
-rw-r--r--include/distortos/internal/scheduler/ThreadControlBlock.hpp336
-rw-r--r--include/distortos/internal/scheduler/ThreadGroupControlBlock.hpp61
-rw-r--r--include/distortos/internal/scheduler/ThreadList.hpp65
-rw-r--r--include/distortos/internal/scheduler/ThreadListNode.hpp86
-rw-r--r--include/distortos/internal/scheduler/forceContextSwitch.hpp33
-rw-r--r--include/distortos/internal/scheduler/getScheduler.hpp33
-rw-r--r--include/distortos/internal/scheduler/idleThreadFunction.hpp31
-rw-r--r--include/distortos/internal/scheduler/lowLevelInitialization.hpp44
-rw-r--r--include/distortos/internal/scheduler/threadRunner.hpp48
17 files changed, 1809 insertions, 0 deletions
diff --git a/include/distortos/internal/scheduler/DynamicThreadBase.hpp b/include/distortos/internal/scheduler/DynamicThreadBase.hpp
new file mode 100644
index 0000000..5ca3ff8
--- /dev/null
+++ b/include/distortos/internal/scheduler/DynamicThreadBase.hpp
@@ -0,0 +1,231 @@
+/**
+ * \file
+ * \brief DynamicThreadBase class header
+ *
+ * \author Copyright (C) 2015-2016 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_
+
+#include "distortos/DynamicSignalsReceiver.hpp"
+#include "distortos/DynamicThreadParameters.hpp"
+#include "distortos/ThreadCommon.hpp"
+
+#include "distortos/internal/memory/storageDeleter.hpp"
+
+namespace distortos
+{
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+class DynamicThread;
+
+#endif // def CONFIG_THREAD_DETACH_ENABLE
+
+namespace internal
+{
+
+/**
+ * \brief DynamicThreadBase class is a type-erased interface for thread that has dynamic storage for bounded function,
+ * stack and internal DynamicSignalsReceiver object.
+ *
+ * If thread detachment is enabled (CONFIG_THREAD_DETACH_ENABLE is defined) then this class is dynamically allocated by
+ * DynamicThread - which allows it to be "detached". Otherwise - if thread detachment is disabled
+ * (CONFIG_THREAD_DETACH_ENABLE is not defined) - DynamicThread just inherits from this class.
+ */
+
+class DynamicThreadBase : public ThreadCommon
+{
+public:
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+ /**
+ * \brief DynamicThreadBase's constructor
+ *
+ * \tparam Function is the function that will be executed in separate thread
+ * \tparam Args are the arguments for \a Function
+ *
+ * \param [in] stackSize is the size of stack, bytes
+ * \param [in] canReceiveSignals selects whether reception of signals is enabled (true) or disabled (false) for this
+ * thread
+ * \param [in] queuedSignals is the max number of queued signals for this thread, relevant only if
+ * \a canReceiveSignals == true, 0 to disable queuing of signals for this thread
+ * \param [in] signalActions is the max number of different SignalAction objects for this thread, relevant only if
+ * \a canReceiveSignals == true, 0 to disable catching of signals for this thread
+ * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
+ * \param [in] schedulingPolicy is the scheduling policy of the thread
+ * \param [in] owner is a reference to owner DynamicThread object
+ * \param [in] function is a function that will be executed in separate thread
+ * \param [in] args are arguments for \a function
+ */
+
+ template<typename Function, typename... Args>
+ DynamicThreadBase(size_t stackSize, bool canReceiveSignals, size_t queuedSignals, size_t signalActions,
+ uint8_t priority, SchedulingPolicy schedulingPolicy, DynamicThread& owner, Function&& function,
+ Args&&... args);
+
+ /**
+ * \brief Detaches the thread.
+ *
+ * Similar to std::thread::detach() - http://en.cppreference.com/w/cpp/thread/thread/detach
+ * Similar to POSIX pthread_detach() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_detach.html
+ *
+ * Detaches the executing thread from the Thread object, allowing execution to continue independently. All resources
+ * allocated for the thread will be deallocated when the thread terminates.
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - this thread is already detached;
+ */
+
+ int detach() override;
+
+#else // !def CONFIG_THREAD_DETACH_ENABLE
+
+ /**
+ * \brief DynamicThreadBase's constructor
+ *
+ * \tparam Function is the function that will be executed in separate thread
+ * \tparam Args are the arguments for \a Function
+ *
+ * \param [in] stackSize is the size of stack, bytes
+ * \param [in] canReceiveSignals selects whether reception of signals is enabled (true) or disabled (false) for this
+ * thread
+ * \param [in] queuedSignals is the max number of queued signals for this thread, relevant only if
+ * \a canReceiveSignals == true, 0 to disable queuing of signals for this thread
+ * \param [in] signalActions is the max number of different SignalAction objects for this thread, relevant only if
+ * \a canReceiveSignals == true, 0 to disable catching of signals for this thread
+ * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
+ * \param [in] schedulingPolicy is the scheduling policy of the thread
+ * \param [in] function is a function that will be executed in separate thread
+ * \param [in] args are arguments for \a function
+ */
+
+ template<typename Function, typename... Args>
+ DynamicThreadBase(size_t stackSize, bool canReceiveSignals, size_t queuedSignals, size_t signalActions,
+ uint8_t priority, SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args);
+
+ /**
+ * \brief DynamicThreadBase's constructor
+ *
+ * \tparam Function is the function that will be executed in separate thread
+ * \tparam Args are the arguments for \a Function
+ *
+ * \param [in] parameters is a DynamicThreadParameters struct with thread parameters
+ * \param [in] function is a function that will be executed in separate thread
+ * \param [in] args are arguments for \a function
+ */
+
+ template<typename Function, typename... Args>
+ DynamicThreadBase(const DynamicThreadParameters parameters, Function&& function, Args&&... args) :
+ DynamicThreadBase{parameters.stackSize, parameters.canReceiveSignals, parameters.queuedSignals,
+ parameters.signalActions, parameters.priority, parameters.schedulingPolicy,
+ std::forward<Function>(function), std::forward<Args>(args)...}
+ {
+
+ }
+
+#endif // !def CONFIG_THREAD_DETACH_ENABLE
+
+ DynamicThreadBase(const DynamicThreadBase&) = delete;
+ DynamicThreadBase(DynamicThreadBase&&) = default;
+ const DynamicThreadBase& operator=(const DynamicThreadBase&) = delete;
+ DynamicThreadBase& operator=(DynamicThreadBase&&) = delete;
+
+protected:
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+ /**
+ * \brief Pre-termination hook function of thread
+ *
+ * If thread is detached, locks object used for deferred deletion.
+ *
+ * \param [in] thread is a reference to Thread object, this must be DynamicThreadBase!
+ */
+
+ static void preTerminationHook(Thread& thread);
+
+ /**
+ * \brief Termination hook function of thread
+ *
+ * Calls ThreadCommon::terminationHook() and - if thread is detached - schedules itself for deferred deletion.
+ *
+ * \param [in] thread is a reference to Thread object, this must be DynamicThreadBase!
+ */
+
+ static void terminationHook(Thread& thread);
+
+#endif // def CONFIG_THREAD_DETACH_ENABLE
+
+private:
+
+ /**
+ * \brief Thread's "run" function.
+ *
+ * Executes bound function object.
+ *
+ * \param [in] thread is a reference to Thread object, this must be DynamicThreadBase!
+ */
+
+ static void run(Thread& thread);
+
+ /// internal DynamicSignalsReceiver object
+ DynamicSignalsReceiver dynamicSignalsReceiver_;
+
+ /// bound function object
+ std::function<void()> boundFunction_;
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+ /// pointer to owner DynamicThread object, nullptr if thread is detached
+ DynamicThread* owner_;
+
+#endif // def CONFIG_THREAD_DETACH_ENABLE
+};
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+template<typename Function, typename... Args>
+DynamicThreadBase::DynamicThreadBase(const size_t stackSize, const bool canReceiveSignals, const size_t queuedSignals,
+ const size_t signalActions, const uint8_t priority, const SchedulingPolicy schedulingPolicy,
+ DynamicThread& owner, Function&& function, Args&&... args) :
+ ThreadCommon{{{new uint8_t[stackSize], storageDeleter<uint8_t>}, stackSize, *this, run,
+ preTerminationHook, terminationHook}, priority, schedulingPolicy, nullptr,
+ canReceiveSignals == true ? &dynamicSignalsReceiver_ : nullptr},
+ dynamicSignalsReceiver_{canReceiveSignals == true ? queuedSignals : 0,
+ canReceiveSignals == true ? signalActions : 0},
+ boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)},
+ owner_{&owner}
+{
+
+}
+
+#else // !def CONFIG_THREAD_DETACH_ENABLE
+
+template<typename Function, typename... Args>
+DynamicThreadBase::DynamicThreadBase(const size_t stackSize, const bool canReceiveSignals, const size_t queuedSignals,
+ const size_t signalActions, const uint8_t priority, const SchedulingPolicy schedulingPolicy,
+ Function&& function, Args&&... args) :
+ ThreadCommon{{{new uint8_t[stackSize], storageDeleter<uint8_t>}, stackSize, *this, run, nullptr,
+ terminationHook}, priority, schedulingPolicy, nullptr,
+ canReceiveSignals == true ? &dynamicSignalsReceiver_ : nullptr},
+ dynamicSignalsReceiver_{canReceiveSignals == true ? queuedSignals : 0,
+ canReceiveSignals == true ? signalActions : 0},
+ boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)}
+{
+
+}
+
+#endif // !def CONFIG_THREAD_DETACH_ENABLE
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_
diff --git a/include/distortos/internal/scheduler/MainThread.hpp b/include/distortos/internal/scheduler/MainThread.hpp
new file mode 100644
index 0000000..2eadab6
--- /dev/null
+++ b/include/distortos/internal/scheduler/MainThread.hpp
@@ -0,0 +1,46 @@
+/**
+ * \file
+ * \brief MainThread class header
+ *
+ * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_MAINTHREAD_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_MAINTHREAD_HPP_
+
+#include "distortos/UndetachableThread.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// MainThread class is a Thread for main()
+class MainThread : public UndetachableThread
+{
+public:
+
+ /**
+ * \brief MainThread's constructor.
+ *
+ * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
+ * \param [in] threadGroupControlBlock is a reference to ThreadGroupControlBlock to which this object will be added
+ * \param [in] signalsReceiver is a pointer to SignalsReceiver object for main thread, nullptr to disable reception
+ * of signals for main thread
+ */
+
+ MainThread(uint8_t priority, ThreadGroupControlBlock& threadGroupControlBlock, SignalsReceiver* signalsReceiver);
+
+ using UndetachableThread::getThreadControlBlock;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_MAINTHREAD_HPP_
diff --git a/include/distortos/internal/scheduler/RoundRobinQuantum.hpp b/include/distortos/internal/scheduler/RoundRobinQuantum.hpp
new file mode 100644
index 0000000..e0a443e
--- /dev/null
+++ b/include/distortos/internal/scheduler/RoundRobinQuantum.hpp
@@ -0,0 +1,123 @@
+/**
+ * \file
+ * \brief RoundRobinQuantum class header
+ *
+ * \author Copyright (C) 2014-2016 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_ROUNDROBINQUANTUM_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_ROUNDROBINQUANTUM_HPP_
+
+#include "distortos/TickClock.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// RoundRobinQuantum class is a quantum of time for round-robin scheduling
+class RoundRobinQuantum
+{
+public:
+
+ /// type of quantum counter
+ using Representation = uint8_t;
+
+ /// duration type used for quantum
+ using Duration = std::chrono::duration<Representation, TickClock::period>;
+
+ /**
+ * \return initial value for round-robin quantum
+ */
+
+ constexpr static Duration getInitial()
+ {
+ return Duration{quantumRawInitializer_};
+ }
+
+ /**
+ * \brief RoundRobinQuantum's constructor
+ *
+ * Initializes quantum value to initial value - just like after call to reset().
+ */
+
+ constexpr RoundRobinQuantum() :
+ quantum_{getInitial()}
+ {
+
+ }
+
+ /**
+ * \brief Decrements round-robin's quantum.
+ *
+ * This function should be called from tick interrupt for the currently running thread. Underflow of quantum after
+ * this decrement is not possible.
+ *
+ * \note this function must be called with enabled interrupt masking
+ */
+
+ void decrement()
+ {
+ if (isZero() == false)
+ --quantum_;
+ }
+
+ /**
+ * \brief Gets current value of round-robin's quantum.
+ *
+ * \return current value of round-robin's quantum of the thread
+ */
+
+ Duration get() const
+ {
+ return quantum_;
+ }
+
+ /**
+ * \brief Convenience function to test whether the quantum is already at 0.
+ *
+ * \return true if quantum is zero, false otherwise
+ */
+
+ bool isZero() const
+ {
+ return quantum_ == Duration{0};
+ }
+
+ /**
+ * \brief Resets value of round-robin's quantum.
+ *
+ * This function should be called from context switcher after selecting new task that will be run.
+ */
+
+ void reset()
+ {
+ quantum_ = getInitial();
+ }
+
+private:
+
+ static_assert(CONFIG_TICK_FREQUENCY > 0, "CONFIG_TICK_FREQUENCY must be positive and non-zero!");
+ static_assert(CONFIG_ROUND_ROBIN_FREQUENCY > 0, "CONFIG_ROUND_ROBIN_FREQUENCY must be positive and non-zero!");
+
+ /// raw initializer value for round-robin quantum, calculated with rounding to nearest
+ constexpr static auto quantumRawInitializer_ = (CONFIG_TICK_FREQUENCY + CONFIG_ROUND_ROBIN_FREQUENCY / 2) /
+ CONFIG_ROUND_ROBIN_FREQUENCY;
+
+ static_assert(quantumRawInitializer_ > 0 || quantumRawInitializer_ <= UINT8_MAX,
+ "CONFIG_TICK_FREQUENCY and CONFIG_ROUND_ROBIN_FREQUENCY values produce invalid round-robin quantum!");
+
+ /// round-robin quantum
+ Duration quantum_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_ROUNDROBINQUANTUM_HPP_
diff --git a/include/distortos/internal/scheduler/Scheduler.hpp b/include/distortos/internal/scheduler/Scheduler.hpp
new file mode 100644
index 0000000..42037f2
--- /dev/null
+++ b/include/distortos/internal/scheduler/Scheduler.hpp
@@ -0,0 +1,351 @@
+/**
+ * \file
+ * \brief Scheduler class header
+ *
+ * \author Copyright (C) 2014-2016 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SCHEDULER_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SCHEDULER_HPP_
+
+#include "distortos/internal/scheduler/ThreadControlBlock.hpp"
+#include "distortos/internal/scheduler/ThreadList.hpp"
+#include "distortos/internal/scheduler/SoftwareTimerSupervisor.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class MainThread;
+
+/// Scheduler class is a system's scheduler
+class Scheduler
+{
+public:
+
+ /**
+ * \brief Scheduler's constructor
+ */
+
+ constexpr Scheduler() :
+ currentThreadControlBlock_{},
+ runnableList_{},
+ suspendedList_{},
+ softwareTimerSupervisor_{},
+ contextSwitchCount_{},
+ tickCount_{}
+ {
+
+ }
+
+ /**
+ * \brief Adds new ThreadControlBlock to scheduler.
+ *
+ * ThreadControlBlock's state is changed to "runnable".
+ *
+ * \param [in] threadControlBlock is a reference to added ThreadControlBlock object
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - thread is already started;
+ * - error codes returned by Scheduler::addInternal();
+ */
+
+ int add(ThreadControlBlock& threadControlBlock);
+
+ /**
+ * \brief Blocks current thread, transferring it to provided container.
+ *
+ * \param [in] container is a reference to destination container to which the thread will be transferred
+ * \param [in] state is the new state of thread that will be blocked
+ * \param [in] unblockFunctor is a pointer to ThreadControlBlock::UnblockFunctor which will be executed in
+ * ThreadControlBlock::unblockHook(), default - nullptr (no functor will be executed)
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINTR - thread was unblocked with ThreadControlBlock::UnblockReason::signal;
+ * - ETIMEDOUT - thread was unblocked with ThreadControlBlock::UnblockReason::timeout;
+ */
+
+ int block(ThreadList& container, ThreadState state, const ThreadControlBlock::UnblockFunctor* unblockFunctor = {});
+
+ /**
+ * \brief Blocks thread, transferring it to provided container.
+ *
+ * The thread must be on "runnable" list - trying to block thread in other state is an error.
+ *
+ * \param [in] container is a reference to destination container to which the thread will be transferred
+ * \param [in] iterator is the iterator to the thread that will be blocked
+ * \param [in] state is the new state of thread that will be blocked
+ * \param [in] unblockFunctor is a pointer to ThreadControlBlock::UnblockFunctor which will be executed in
+ * ThreadControlBlock::unblockHook(), default - nullptr (no functor will be executed)
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINTR - thread was unblocked with ThreadControlBlock::UnblockReason::signal (possible only when blocking
+ * current thread);
+ * - EINVAL - provided thread is not on "runnable" list;
+ * - ETIMEDOUT - thread was unblocked with ThreadControlBlock::UnblockReason::timeout (possible only when blocking
+ * current thread);
+ */
+
+ int block(ThreadList& container, ThreadList::iterator iterator, ThreadState state,
+ const ThreadControlBlock::UnblockFunctor* unblockFunctor = {});
+
+ /**
+ * \brief Blocks current thread with timeout, transferring it to provided container.
+ *
+ * \param [in] container is a reference to destination container to which the thread will be transferred
+ * \param [in] state is the new state of thread that will be blocked
+ * \param [in] timePoint is the time point at which the thread will be unblocked (if not already unblocked)
+ * \param [in] unblockFunctor is a pointer to ThreadControlBlock::UnblockFunctor which will be executed in
+ * ThreadControlBlock::unblockHook(), default - nullptr (no functor will be executed)
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINTR - thread was unblocked with ThreadControlBlock::UnblockReason::signal;
+ * - ETIMEDOUT - thread was unblocked because timePoint was reached;
+ */
+
+ int blockUntil(ThreadList& container, ThreadState state, TickClock::time_point timePoint,
+ const ThreadControlBlock::UnblockFunctor* unblockFunctor = {});
+
+ /**
+ * \return number of context switches
+ */
+
+ uint64_t getContextSwitchCount() const;
+
+ /**
+ * \return reference to currently active ThreadControlBlock
+ */
+
+ ThreadControlBlock& getCurrentThreadControlBlock() const
+ {
+ return *currentThreadControlBlock_;
+ }
+
+ /**
+ * \return reference to internal SoftwareTimerSupervisor object
+ */
+
+ SoftwareTimerSupervisor& getSoftwareTimerSupervisor()
+ {
+ return softwareTimerSupervisor_;
+ }
+
+ /**
+ * \return const reference to internal SoftwareTimerSupervisor object
+ */
+
+ const SoftwareTimerSupervisor& getSoftwareTimerSupervisor() const
+ {
+ return softwareTimerSupervisor_;
+ }
+
+ /**
+ * \return current value of tick count
+ */
+
+ uint64_t getTickCount() const;
+
+ /**
+ * \brief 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
+ *
+ * \param [in] mainThread is a reference to main thread
+ *
+ * \return 0 on success, error code otherwise:
+ * - error codes returned by Scheduler::addInternal();
+ */
+
+ int initialize(MainThread& mainThread);
+
+ /**
+ * \brief Requests context switch if it is needed.
+ *
+ * \attention This function must be called with interrupt masking enabled.
+ */
+
+ void maybeRequestContextSwitch() const;
+
+ /**
+ * \brief Removes current thread from Scheduler's control.
+ *
+ * Thread's state is changed to "terminated".
+ *
+ * \note This function must be called with masked interrupts.
+ *
+ * \note This function can be used only after thread's function returns an all cleanup is done.
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - provided thread is not on "runnable" list and cannot be removed/terminated;
+ */
+
+ int remove();
+
+ /**
+ * \brief Resumes suspended thread.
+ *
+ * The thread must be on the "suspended" list - trying to resume thread that is not suspended is an error.
+ *
+ * \param [in] iterator is the iterator to the thread that will be resumed
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - provided thread is not on "suspended" list;
+ */
+
+ int resume(ThreadList::iterator iterator);
+
+ /**
+ * \brief Suspends current thread.
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINTR - thread was unblocked with ThreadControlBlock::UnblockReason::signal;
+ */
+
+ int suspend();
+
+ /**
+ * \brief Suspends thread.
+ *
+ * The thread must be on "runnable" list - trying to suspend thread in other state is an error.
+ *
+ * \param [in] iterator is the iterator to the thread that will be suspended
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINTR - thread was unblocked with ThreadControlBlock::UnblockReason::signal;
+ * - EINVAL - provided thread is not on "runnable" list;
+ */
+
+ int suspend(ThreadList::iterator iterator);
+
+ /**
+ * \brief Called by architecture-specific code to do final context switch.
+ *
+ * Current task is suspended and the next available task is started.
+ *
+ * \param [in] stackPointer is the current value of current thread's stack pointer
+ *
+ * \return new thread's stack pointer
+ */
+
+ void* switchContext(void* stackPointer);
+
+ /**
+ * \brief Handler of "tick" interrupt.
+ *
+ * \note this must not be called by user code
+ *
+ * \return true if context switch is required, false otherwise
+ */
+
+ bool tickInterruptHandler();
+
+ /**
+ * \brief Unblocks provided thread, transferring it from it's current container to "runnable" container.
+ *
+ * Current container of the thread is obtained with ThreadControlBlock::getList().
+ *
+ * \param [in] iterator is the iterator which points to unblocked thread
+ * \param [in] unblockReason is the reason of unblocking of the thread, default -
+ * ThreadControlBlock::UnblockReason::unblockRequest
+ */
+
+ void unblock(ThreadList::iterator iterator,
+ ThreadControlBlock::UnblockReason unblockReason = ThreadControlBlock::UnblockReason::unblockRequest);
+
+ /**
+ * \brief Yields time slot of the scheduler to next thread.
+ */
+
+ void yield();
+
+private:
+
+ /**
+ * \brief Adds new ThreadControlBlock to scheduler.
+ *
+ * Internal version - without interrupt masking and call to Scheduler::maybeRequestContextSwitch()
+ *
+ * \param [in] threadControlBlock is a reference to added ThreadControlBlock object
+ *
+ * \return 0 on success, error code otherwise:
+ * - error codes returned by ThreadControlBlock::addHook();
+ */
+
+ int addInternal(ThreadControlBlock& threadControlBlock);
+
+ /**
+ * \brief Blocks thread, transferring it to provided container.
+ *
+ * Internal version - without interrupt masking and forced context switch.
+ *
+ * \param [in] container is a reference to destination container to which the thread will be transferred
+ * \param [in] iterator is the iterator to the thread that will be blocked
+ * \param [in] state is the new state of thread that will be blocked
+ * \param [in] unblockFunctor is a pointer to ThreadControlBlock::UnblockFunctor which will be executed in
+ * ThreadControlBlock::unblockHook()
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - provided thread is not on "runnable" list;
+ */
+
+ int blockInternal(ThreadList& container, ThreadList::iterator iterator, ThreadState state,
+ const ThreadControlBlock::UnblockFunctor* unblockFunctor);
+
+ /**
+ * \brief 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).
+ *
+ * \return true if context switch is required
+ */
+
+ bool isContextSwitchRequired() const;
+
+ /**
+ * \brief 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()
+ *
+ * \param [in] iterator is the iterator which points to unblocked thread
+ * \param [in] unblockReason is the reason of unblocking of the thread
+ */
+
+ void unblockInternal(ThreadList::iterator iterator, ThreadControlBlock::UnblockReason unblockReason);
+
+ /// iterator to the currently active ThreadControlBlock
+ ThreadList::iterator currentThreadControlBlock_;
+
+ /// list of ThreadControlBlock elements in "runnable" state, sorted by priority in descending order
+ ThreadList runnableList_;
+
+ /// list of ThreadControlBlock elements in "suspended" state, sorted by priority in descending order
+ ThreadList suspendedList_;
+
+ /// internal SoftwareTimerSupervisor object
+ SoftwareTimerSupervisor softwareTimerSupervisor_;
+
+ /// number of context switches
+ uint64_t contextSwitchCount_;
+
+ /// tick count
+ uint64_t tickCount_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SCHEDULER_HPP_
diff --git a/include/distortos/internal/scheduler/SoftwareTimerControlBlock.hpp b/include/distortos/internal/scheduler/SoftwareTimerControlBlock.hpp
new file mode 100644
index 0000000..c020d35
--- /dev/null
+++ b/include/distortos/internal/scheduler/SoftwareTimerControlBlock.hpp
@@ -0,0 +1,111 @@
+/**
+ * \file
+ * \brief SoftwareTimerControlBlock class header
+ *
+ * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERCONTROLBLOCK_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERCONTROLBLOCK_HPP_
+
+#include "distortos/internal/scheduler/SoftwareTimerListNode.hpp"
+
+namespace distortos
+{
+
+class SoftwareTimer;
+
+namespace internal
+{
+
+/// SoftwareTimerControlBlock class is a control block of software timer
+class SoftwareTimerControlBlock : public SoftwareTimerListNode
+{
+public:
+
+ /// type of runner for software timer's function
+ using FunctionRunner = void(SoftwareTimer&);
+
+ /**
+ * \brief SoftwareTimerControlBlock's constructor
+ *
+ * \param [in] functionRunner is a reference to runner for software timer's function
+ * \param [in] owner is a reference to SoftwareTimer object that owns this SoftwareTimerControlBlock
+ */
+
+ constexpr SoftwareTimerControlBlock(FunctionRunner& functionRunner, SoftwareTimer& owner) :
+ SoftwareTimerListNode{},
+ functionRunner_{functionRunner},
+ owner_{owner}
+ {
+
+ }
+
+ /**
+ * \brief SoftwareTimerControlBlock's destructor
+ *
+ * If the timer is running it is stopped.
+ */
+
+ ~SoftwareTimerControlBlock()
+ {
+ stop();
+ }
+
+ /**
+ * \return true if the timer is running, false otherwise
+ */
+
+ bool isRunning() const
+ {
+ return node.isLinked();
+ }
+
+ /**
+ * \brief Runs software timer's function.
+ *
+ * \note this should only be called by SoftwareTimerSupervisor::tickInterruptHandler()
+ */
+
+ void run() const
+ {
+ functionRunner_(owner_);
+ }
+
+ /**
+ * \brief Starts the timer.
+ *
+ * \param [in] timePoint is the time point at which the function will be executed
+ */
+
+ void start(TickClock::time_point timePoint);
+
+ /**
+ * \brief Stops the timer.
+ */
+
+ void stop();
+
+ SoftwareTimerControlBlock(const SoftwareTimerControlBlock&) = delete;
+ SoftwareTimerControlBlock(SoftwareTimerControlBlock&&) = default;
+ const SoftwareTimerControlBlock& operator=(const SoftwareTimerControlBlock&) = delete;
+ SoftwareTimerControlBlock& operator=(SoftwareTimerControlBlock&&) = delete;
+
+private:
+
+ /// reference to runner for software timer's function
+ FunctionRunner& functionRunner_;
+
+ /// reference to SoftwareTimer object that owns this SoftwareTimerControlBlock
+ SoftwareTimer& owner_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERCONTROLBLOCK_HPP_
diff --git a/include/distortos/internal/scheduler/SoftwareTimerList.hpp b/include/distortos/internal/scheduler/SoftwareTimerList.hpp
new file mode 100644
index 0000000..5d38f47
--- /dev/null
+++ b/include/distortos/internal/scheduler/SoftwareTimerList.hpp
@@ -0,0 +1,62 @@
+/**
+ * \file
+ * \brief SoftwareTimerList class header
+ *
+ * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERLIST_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERLIST_HPP_
+
+#include "distortos/internal/scheduler/SoftwareTimerListNode.hpp"
+
+#include "estd/SortedIntrusiveList.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class SoftwareTimerControlBlock;
+
+/// functor which gives ascending expiration time point order of elements on the list
+struct SoftwareTimerAscendingTimePoint
+{
+ /**
+ * \brief SoftwareTimerAscendingTimePoint's constructor
+ */
+
+ constexpr SoftwareTimerAscendingTimePoint()
+ {
+
+ }
+
+ /**
+ * \brief SoftwareTimerAscendingTimePoint's function call operator
+ *
+ * \param [in] left is the object on the left side of comparison
+ * \param [in] right is the object on the right side of comparison
+ *
+ * \return true if left's expiration time point is greater than right's expiration time point
+ */
+
+ bool operator()(const SoftwareTimerListNode& left, const SoftwareTimerListNode& right) const
+ {
+ return left.getTimePoint() > right.getTimePoint();
+ }
+};
+
+/// sorted intrusive list of software timers (software timer control blocks)
+using SoftwareTimerList = estd::SortedIntrusiveList<SoftwareTimerAscendingTimePoint, SoftwareTimerListNode,
+ &SoftwareTimerListNode::node, SoftwareTimerControlBlock>;
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERLIST_HPP_
diff --git a/include/distortos/internal/scheduler/SoftwareTimerListNode.hpp b/include/distortos/internal/scheduler/SoftwareTimerListNode.hpp
new file mode 100644
index 0000000..299e078
--- /dev/null
+++ b/include/distortos/internal/scheduler/SoftwareTimerListNode.hpp
@@ -0,0 +1,82 @@
+/**
+ * \file
+ * \brief SoftwareTimerListNode class header
+ *
+ * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERLISTNODE_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERLISTNODE_HPP_
+
+#include "distortos/TickClock.hpp"
+
+#include "estd/IntrusiveList.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/**
+ * \brief SoftwareTimerListNode class is a base for SoftwareTimerControlBlock that serves as a node in intrusive list of
+ * software timers (software timer control blocks)
+ *
+ * This class is needed to break any potential circular dependencies.
+ */
+
+class SoftwareTimerListNode
+{
+public:
+
+ /**
+ * \brief SoftwareTimerListNode's constructor
+ */
+
+ constexpr SoftwareTimerListNode() :
+ node{},
+ timePoint_{}
+ {
+
+ }
+
+ /**
+ * \return const reference to expiration time point
+ */
+
+ const TickClock::time_point& getTimePoint() const
+ {
+ return timePoint_;
+ }
+
+ /// node for intrusive list
+ estd::IntrusiveListNode node;
+
+protected:
+
+ /**
+ * \brief Sets time point of expiration
+ *
+ * \param [in] timePoint is the new time point of expiration
+ */
+
+ void setTimePoint(const TickClock::time_point timePoint)
+ {
+ timePoint_ = timePoint;
+ }
+
+private:
+
+ ///time point of expiration
+ TickClock::time_point timePoint_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERLISTNODE_HPP_
diff --git a/include/distortos/internal/scheduler/SoftwareTimerSupervisor.hpp b/include/distortos/internal/scheduler/SoftwareTimerSupervisor.hpp
new file mode 100644
index 0000000..8367a0a
--- /dev/null
+++ b/include/distortos/internal/scheduler/SoftwareTimerSupervisor.hpp
@@ -0,0 +1,66 @@
+/**
+ * \file
+ * \brief SoftwareTimerSupervisor class header
+ *
+ * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERSUPERVISOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERSUPERVISOR_HPP_
+
+#include "distortos/internal/scheduler/SoftwareTimerList.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// SoftwareTimerSupervisor class is a supervisor of software timers
+class SoftwareTimerSupervisor
+{
+public:
+
+ /**
+ * \brief SoftwareTimerControlBlock's constructor
+ */
+
+ constexpr SoftwareTimerSupervisor() :
+ activeList_{}
+ {
+
+ }
+
+ /**
+ * \brief Adds SoftwareTimerControlBlock to supervisor, effectively starting the software timer.
+ *
+ * \param [in] softwareTimerControlBlock is the SoftwareTimerControlBlock being added/started
+ */
+
+ void add(SoftwareTimerControlBlock& softwareTimerControlBlock);
+
+ /**
+ * \brief Handler of "tick" interrupt.
+ *
+ * \note this must not be called by user code
+ *
+ * \param [in] timePoint is the current time point
+ */
+
+ void tickInterruptHandler(TickClock::time_point timePoint);
+
+private:
+
+ /// list of active software timers (waiting for execution)
+ SoftwareTimerList activeList_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_SOFTWARETIMERSUPERVISOR_HPP_
diff --git a/include/distortos/internal/scheduler/ThreadControlBlock.hpp b/include/distortos/internal/scheduler/ThreadControlBlock.hpp
new file mode 100644
index 0000000..6d6f458
--- /dev/null
+++ b/include/distortos/internal/scheduler/ThreadControlBlock.hpp
@@ -0,0 +1,336 @@
+/**
+ * \file
+ * \brief ThreadControlBlock class header
+ *
+ * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADCONTROLBLOCK_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADCONTROLBLOCK_HPP_
+
+#include "distortos/internal/scheduler/RoundRobinQuantum.hpp"
+#include "distortos/internal/scheduler/ThreadListNode.hpp"
+
+#include "distortos/internal/synchronization/MutexList.hpp"
+
+#include "distortos/architecture/Stack.hpp"
+
+#include "distortos/SchedulingPolicy.hpp"
+#include "distortos/ThreadState.hpp"
+
+#include "estd/TypeErasedFunctor.hpp"
+
+namespace distortos
+{
+
+class SignalsReceiver;
+
+namespace internal
+{
+
+class SignalsReceiverControlBlock;
+class ThreadList;
+class ThreadGroupControlBlock;
+
+/// ThreadControlBlock class is a simple description of a Thread
+class ThreadControlBlock : public ThreadListNode
+{
+public:
+
+ /// reason of thread unblocking
+ enum class UnblockReason : uint8_t
+ {
+ /// explicit request to unblock the thread - normal unblock
+ unblockRequest,
+ /// timeout - unblock via software timer
+ timeout,
+ /// signal handler - unblock to deliver unmasked signal
+ signal,
+ };
+
+ /// UnblockFunctor is a functor executed when unblocking the thread, it receives two parameter - a reference to
+ /// ThreadControlBlock that is being unblocked and the reason of thread unblocking
+ class UnblockFunctor : public estd::TypeErasedFunctor<void(ThreadControlBlock&, UnblockReason)>
+ {
+
+ };
+
+ /**
+ * \brief ThreadControlBlock constructor.
+ *
+ * \param [in] stack is an rvalue reference to architecture::Stack object which will be adopted for this thread
+ * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
+ * \param [in] schedulingPolicy is the scheduling policy of the thread
+ * \param [in] threadGroupControlBlock is a pointer to ThreadGroupControlBlock to which this object will be added,
+ * nullptr to inherit thread group from currently running thread
+ * \param [in] signalsReceiver is a pointer to SignalsReceiver object for this thread, nullptr to disable reception
+ * of signals for this thread
+ * \param [in] owner is a reference to Thread object that owns this ThreadControlBlock
+ */
+
+ ThreadControlBlock(architecture::Stack&& stack, uint8_t priority, SchedulingPolicy schedulingPolicy,
+ ThreadGroupControlBlock* threadGroupControlBlock, SignalsReceiver* signalsReceiver, Thread& owner);
+
+ /**
+ * \brief ThreadControlBlock's destructor
+ */
+
+ ~ThreadControlBlock();
+
+ /**
+ * \brief Hook function executed when thread is added to scheduler.
+ *
+ * If threadGroupControlBlock_ is nullptr, it is inherited from currently running thread. Then this object is added
+ * to the thread group (if it is valid).
+ *
+ * \attention This function should be called only by Scheduler::addInternal().
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - inherited thread group is invalid;
+ */
+
+ int addHook();
+
+ /**
+ * \brief Block hook function of thread
+ *
+ * Saves pointer to UnblockFunctor.
+ *
+ * \attention This function should be called only by Scheduler::blockInternal().
+ *
+ * \param [in] unblockFunctor is a pointer to UnblockFunctor which will be executed in unblockHook()
+ */
+
+ void blockHook(const UnblockFunctor* const unblockFunctor)
+ {
+ unblockFunctor_ = unblockFunctor;
+ }
+
+ /**
+ * \return pointer to list that has this object
+ */
+
+ ThreadList* getList() const
+ {
+ return list_;
+ }
+
+ /**
+ * \return reference to list of mutexes (mutex control blocks) with enabled priority protocol owned by this thread
+ */
+
+ MutexList& getOwnedProtocolMutexList()
+ {
+ return ownedProtocolMutexList_;
+ }
+
+ /**
+ * \return reference to Thread object that owns this ThreadControlBlock
+ */
+
+ Thread& getOwner() const
+ {
+ return owner_;
+ }
+
+ /**
+ * \return reference to internal RoundRobinQuantum object
+ */
+
+ RoundRobinQuantum& getRoundRobinQuantum()
+ {
+ return roundRobinQuantum_;
+ }
+
+ /**
+ * \return scheduling policy of the thread
+ */
+
+ SchedulingPolicy getSchedulingPolicy() const
+ {
+ return schedulingPolicy_;
+ }
+
+ /**
+ * \return pointer to SignalsReceiverControlBlock object for this thread, nullptr if this thread cannot receive
+ * signals
+ */
+
+ SignalsReceiverControlBlock* getSignalsReceiverControlBlock() const
+ {
+ return signalsReceiverControlBlock_;
+ }
+
+ /**
+ * \return reference to internal Stack object
+ */
+
+ architecture::Stack& getStack()
+ {
+ return stack_;
+ }
+
+ /**
+ * \return current state of object
+ */
+
+ ThreadState getState() const
+ {
+ return state_;
+ }
+
+ /**
+ * \brief Sets the list that has this object.
+ *
+ * \param [in] list is a pointer to list that has this object
+ */
+
+ void setList(ThreadList* const list)
+ {
+ list_ = list;
+ }
+
+ /**
+ * \brief Changes priority of thread.
+ *
+ * If the priority really changes, the position in the thread list is adjusted and context switch may be requested.
+ *
+ * \param [in] priority is the new priority of thread
+ * \param [in] alwaysBehind selects the method of ordering when lowering the priority
+ * - false - the thread is moved to the head of the group of threads with the new priority (default),
+ * - true - the thread is moved to the tail of the group of threads with the new priority.
+ */
+
+ void setPriority(uint8_t priority, bool alwaysBehind = {});
+
+ /**
+ * \param [in] priorityInheritanceMutexControlBlock is a pointer to MutexControlBlock (with PriorityInheritance
+ * protocol) that blocks this thread
+ */
+
+ void setPriorityInheritanceMutexControlBlock(const MutexControlBlock* const priorityInheritanceMutexControlBlock)
+ {
+ priorityInheritanceMutexControlBlock_ = priorityInheritanceMutexControlBlock;
+ }
+
+ /**
+ * param [in] schedulingPolicy is the new scheduling policy of the thread
+ */
+
+ void setSchedulingPolicy(SchedulingPolicy schedulingPolicy);
+
+ /**
+ * \param [in] state is the new state of object
+ */
+
+ void setState(const ThreadState state)
+ {
+ state_ = state;
+ }
+
+ /**
+ * \brief Hook function called when context is switched to this thread.
+ *
+ * Sets global _impure_ptr (from newlib) to thread's \a reent_ member variable.
+ *
+ * \attention This function should be called only by Scheduler::switchContext().
+ */
+
+ void switchedToHook()
+ {
+ _impure_ptr = &reent_;
+ }
+
+ /**
+ * \brief Unblock hook function of thread
+ *
+ * Resets round-robin's quantum and executes unblock functor saved in blockHook().
+ *
+ * \attention This function should be called only by Scheduler::unblockInternal().
+ *
+ * \param [in] unblockReason is the new reason of unblocking of the thread
+ */
+
+ void unblockHook(UnblockReason unblockReason);
+
+ /**
+ * \brief Updates boosted priority of the thread.
+ *
+ * This function should be called after all operations involving this thread and a mutex with enabled priority
+ * protocol.
+ *
+ * \param [in] boostedPriority is the initial boosted priority, this should be effective priority of the thread that
+ * is about to be blocked on a mutex owned by this thread, default - 0
+ */
+
+ void updateBoostedPriority(uint8_t boostedPriority = {});
+
+ ThreadControlBlock(const ThreadControlBlock&) = delete;
+ ThreadControlBlock(ThreadControlBlock&&) = default;
+ const ThreadControlBlock& operator=(const ThreadControlBlock&) = delete;
+ ThreadControlBlock& operator=(ThreadControlBlock&&) = delete;
+
+private:
+
+ /**
+ * \brief Repositions the thread on the list it's currently on.
+ *
+ * This function should be called when thread's effective priority changes.
+ *
+ * \attention list_ must not be nullptr
+ *
+ * \param [in] loweringBefore selects the method of ordering when lowering the priority (it must be false when the
+ * priority is raised!):
+ * - true - the thread is moved to the head of the group of threads with the new priority, this is accomplished by
+ * temporarily boosting effective priority by 1,
+ * - false - the thread is moved to the tail of the group of threads with the new priority.
+ */
+
+ void reposition(bool loweringBefore);
+
+ /// internal stack object
+ architecture::Stack stack_;
+
+ /// reference to Thread object that owns this ThreadControlBlock
+ Thread& owner_;
+
+ /// list of mutexes (mutex control blocks) with enabled priority protocol owned by this thread
+ MutexList ownedProtocolMutexList_;
+
+ /// pointer to MutexControlBlock (with PriorityInheritance protocol) that blocks this thread
+ const MutexControlBlock* priorityInheritanceMutexControlBlock_;
+
+ /// pointer to list that has this object
+ ThreadList* list_;
+
+ /// pointer to ThreadGroupControlBlock with which this object is associated
+ ThreadGroupControlBlock* threadGroupControlBlock_;
+
+ /// functor executed in unblockHook()
+ const UnblockFunctor* unblockFunctor_;
+
+ /// pointer to SignalsReceiverControlBlock object for this thread, nullptr if this thread cannot receive signals
+ SignalsReceiverControlBlock* signalsReceiverControlBlock_;
+
+ /// newlib's _reent structure with thread-specific data
+ _reent reent_;
+
+ /// round-robin quantum
+ RoundRobinQuantum roundRobinQuantum_;
+
+ /// scheduling policy of the thread
+ SchedulingPolicy schedulingPolicy_;
+
+ /// current state of object
+ ThreadState state_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADCONTROLBLOCK_HPP_
diff --git a/include/distortos/internal/scheduler/ThreadGroupControlBlock.hpp b/include/distortos/internal/scheduler/ThreadGroupControlBlock.hpp
new file mode 100644
index 0000000..59ff313
--- /dev/null
+++ b/include/distortos/internal/scheduler/ThreadGroupControlBlock.hpp
@@ -0,0 +1,61 @@
+/**
+ * \file
+ * \brief ThreadGroupControlBlock class header
+ *
+ * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADGROUPCONTROLBLOCK_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADGROUPCONTROLBLOCK_HPP_
+
+#include "distortos/internal/scheduler/ThreadListNode.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class ThreadControlBlock;
+
+/// ThreadGroupControlBlock class is a control block for ThreadGroup
+class ThreadGroupControlBlock
+{
+public:
+
+ /**
+ * \brief ThreadGroupControlBlock's constructor
+ */
+
+ constexpr ThreadGroupControlBlock() :
+ threadList_{}
+ {
+
+ }
+
+ /**
+ * \brief Adds new ThreadControlBlock to internal list of this object.
+ *
+ * \param [in] threadControlBlock is a reference to added ThreadControlBlock object
+ */
+
+ void add(ThreadControlBlock& threadControlBlock);
+
+private:
+
+ /// intrusive list of threads (thread control blocks)
+ using List = estd::IntrusiveList<ThreadListNode, &ThreadListNode::threadGroupNode, ThreadControlBlock>;
+
+ /// list of threads (thread control blocks) in this group
+ List threadList_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADGROUPCONTROLBLOCK_HPP_
diff --git a/include/distortos/internal/scheduler/ThreadList.hpp b/include/distortos/internal/scheduler/ThreadList.hpp
new file mode 100644
index 0000000..edf2483
--- /dev/null
+++ b/include/distortos/internal/scheduler/ThreadList.hpp
@@ -0,0 +1,65 @@
+/**
+ * \file
+ * \brief ThreadList class header
+ *
+ * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADLIST_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADLIST_HPP_
+
+#include "distortos/internal/scheduler/ThreadListNode.hpp"
+
+#include "estd/SortedIntrusiveList.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class ThreadControlBlock;
+
+/// functor which gives descending effective priority order of elements on the list
+struct ThreadDescendingEffectivePriority
+{
+ /**
+ * \brief ThreadDescendingEffectivePriority's constructor
+ */
+
+ constexpr ThreadDescendingEffectivePriority()
+ {
+
+ }
+
+ /**
+ * \brief ThreadDescendingEffectivePriority's function call operator
+ *
+ * \param [in] left is the object on the left-hand side of comparison
+ * \param [in] right is the object on the right-hand side of comparison
+ *
+ * \return true if left's effective priority is less than right's effective priority
+ */
+
+ bool operator()(const ThreadListNode& left, const ThreadListNode& right) const
+ {
+ return left.getEffectivePriority() < right.getEffectivePriority();
+ }
+};
+
+/// sorted intrusive list of threads (thread control blocks)
+class ThreadList : public estd::SortedIntrusiveList<ThreadDescendingEffectivePriority, ThreadListNode,
+ &ThreadListNode::threadListNode, ThreadControlBlock>
+{
+
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADLIST_HPP_
diff --git a/include/distortos/internal/scheduler/ThreadListNode.hpp b/include/distortos/internal/scheduler/ThreadListNode.hpp
new file mode 100644
index 0000000..fcd7c85
--- /dev/null
+++ b/include/distortos/internal/scheduler/ThreadListNode.hpp
@@ -0,0 +1,86 @@
+/**
+ * \file
+ * \brief ThreadListNode class header
+ *
+ * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADLISTNODE_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADLISTNODE_HPP_
+
+#include "estd/IntrusiveList.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/**
+ * \brief ThreadListNode class is a base for ThreadControlBlock that provides nodes for intrusive lists
+ *
+ * This class is needed to break circular dependency - MutexList is contained in ThreadControlBlock and ThreadList is
+ * contained in MutexControlBlock.
+ */
+
+class ThreadListNode
+{
+public:
+
+ /**
+ * \brief ThreadListNode's constructor
+ *
+ * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
+ */
+
+ constexpr ThreadListNode(const uint8_t priority) :
+ threadListNode{},
+ threadGroupNode{},
+ priority_{priority},
+ boostedPriority_{}
+ {
+
+ }
+
+ /**
+ * \return effective priority of thread
+ */
+
+ uint8_t getEffectivePriority() const
+ {
+ return std::max(priority_, boostedPriority_);
+ }
+
+ /**
+ * \return priority of thread
+ */
+
+ uint8_t getPriority() const
+ {
+ return priority_;
+ }
+
+ /// node for intrusive list in thread lists
+ estd::IntrusiveListNode threadListNode;
+
+ /// node for intrusive list in thread group
+ estd::IntrusiveListNode threadGroupNode;
+
+protected:
+
+ /// thread's priority, 0 - lowest, UINT8_MAX - highest
+ uint8_t priority_;
+
+ /// thread's boosted priority, 0 - no boosting
+ uint8_t boostedPriority_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADLISTNODE_HPP_
diff --git a/include/distortos/internal/scheduler/forceContextSwitch.hpp b/include/distortos/internal/scheduler/forceContextSwitch.hpp
new file mode 100644
index 0000000..4509e51
--- /dev/null
+++ b/include/distortos/internal/scheduler/forceContextSwitch.hpp
@@ -0,0 +1,33 @@
+/**
+ * \file
+ * \brief forceContextSwitch() declaration
+ *
+ * \author Copyright (C) 2014-2016 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_FORCECONTEXTSWITCH_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_FORCECONTEXTSWITCH_HPP_
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/**
+ * \brief Forces unconditional context switch.
+ *
+ * Requests unconditional context switch and temporarily disables any interrupt masking.
+ */
+
+void forceContextSwitch();
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_FORCECONTEXTSWITCH_HPP_
diff --git a/include/distortos/internal/scheduler/getScheduler.hpp b/include/distortos/internal/scheduler/getScheduler.hpp
new file mode 100644
index 0000000..f95d51c
--- /dev/null
+++ b/include/distortos/internal/scheduler/getScheduler.hpp
@@ -0,0 +1,33 @@
+/**
+ * \file
+ * \brief getScheduler() declaration
+ *
+ * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_GETSCHEDULER_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_GETSCHEDULER_HPP_
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class Scheduler;
+
+/**
+ * \return reference to main instance of system's Scheduler
+ */
+
+Scheduler& getScheduler();
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_GETSCHEDULER_HPP_
diff --git a/include/distortos/internal/scheduler/idleThreadFunction.hpp b/include/distortos/internal/scheduler/idleThreadFunction.hpp
new file mode 100644
index 0000000..23699d4
--- /dev/null
+++ b/include/distortos/internal/scheduler/idleThreadFunction.hpp
@@ -0,0 +1,31 @@
+/**
+ * \file
+ * \brief idleThreadFunction() declaration
+ *
+ * \author Copyright (C) 2014-2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_IDLETHREADFUNCTION_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_IDLETHREADFUNCTION_HPP_
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/**
+ * \brief Idle thread's function
+ */
+
+void idleThreadFunction();
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_IDLETHREADFUNCTION_HPP_
diff --git a/include/distortos/internal/scheduler/lowLevelInitialization.hpp b/include/distortos/internal/scheduler/lowLevelInitialization.hpp
new file mode 100644
index 0000000..a6298c2
--- /dev/null
+++ b/include/distortos/internal/scheduler/lowLevelInitialization.hpp
@@ -0,0 +1,44 @@
+/**
+ * \file
+ * \brief internal::lowLevelInitialization() declaration
+ *
+ * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_LOWLEVELINITIALIZATION_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_LOWLEVELINITIALIZATION_HPP_
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/*---------------------------------------------------------------------------------------------------------------------+
+| global functions' declarations
++---------------------------------------------------------------------------------------------------------------------*/
+
+/**
+ * \brief Low level system initialization
+ *
+ * 1. Initializes main instance of system's Scheduler;
+ * 2. Initializes main thread with its group;
+ * 3. Starts idle thread;
+ * 4. Initializes main instance of Mutex used for malloc() and free() locking;
+ * 5. Initializes main instance of DeferredThreadDeleter (only if CONFIG_THREAD_DETACH_ENABLE option is enabled);
+ *
+ * This function is called before constructors for global and static objects from __libc_init_array() via address in
+ * distortosPreinitArray[].
+ */
+
+void lowLevelInitialization();
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_LOWLEVELINITIALIZATION_HPP_
diff --git a/include/distortos/internal/scheduler/threadRunner.hpp b/include/distortos/internal/scheduler/threadRunner.hpp
new file mode 100644
index 0000000..1cee654
--- /dev/null
+++ b/include/distortos/internal/scheduler/threadRunner.hpp
@@ -0,0 +1,48 @@
+/**
+ * \file
+ * \brief threadRunner() declaration
+ *
+ * \author Copyright (C) 2014-2016 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
+ *
+ * \par License
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
+ * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADRUNNER_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADRUNNER_HPP_
+
+namespace distortos
+{
+
+class Thread;
+
+namespace internal
+{
+
+/**
+ * \brief Thread runner function - entry point of threads.
+ *
+ * Performs following actions:
+ * - executes thread's "run" function;
+ * - thread's pre-termination hook is executed (if provided);
+ * - thread is terminated and removed from scheduler;
+ * - thread's termination hook is executed;
+ * - context switch is forced;
+ *
+ * This function never returns.
+ *
+ * \param [in] thread is a reference to Thread object that is being run
+ * \param [in] run is a reference to Thread's "run" function
+ * \param [in] preTerminationHook is a pointer to Thread's pre-termination hook, nullptr to skip
+ * \param [in] terminationHook is a reference to Thread's termination hook
+ */
+
+void threadRunner(Thread& thread, void (& run)(Thread&), void (* preTerminationHook)(Thread&),
+ void (& terminationHook)(Thread&)) __attribute__ ((noreturn));
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_THREADRUNNER_HPP_