aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <tullivan99@gmail.com>2016-11-08 20:09:05 -0500
committerClyne Sullivan <tullivan99@gmail.com>2016-11-08 20:09:05 -0500
commit92235fb259b0ebdfc99859c2c95fe1f8c163f411 (patch)
treee90d9b5adddad8d0ae744eadb5d15313517cc71b
parentdaad5eaa0296ff30624da5fbfaacdb88792b5fea (diff)
trying out distortos
-rw-r--r--Makefile239
-rw-r--r--STM32F103VD.ld267
-rw-r--r--chconf.h531
-rw-r--r--halconf.h345
-rw-r--r--include/control.h71
-rw-r--r--include/distortos/ConditionVariable.hpp304
-rw-r--r--include/distortos/DynamicFifoQueue.hpp56
-rw-r--r--include/distortos/DynamicMessageQueue.hpp60
-rw-r--r--include/distortos/DynamicRawFifoQueue.hpp42
-rw-r--r--include/distortos/DynamicRawMessageQueue.hpp42
-rw-r--r--include/distortos/DynamicSignalsReceiver.hpp52
-rw-r--r--include/distortos/DynamicThread.hpp373
-rw-r--r--include/distortos/DynamicThreadParameters.hpp99
-rw-r--r--include/distortos/FifoQueue.hpp682
-rw-r--r--include/distortos/MessageQueue.hpp762
-rw-r--r--include/distortos/Mutex.hpp280
-rw-r--r--include/distortos/OnceFlag.hpp60
-rw-r--r--include/distortos/RawFifoQueue.hpp463
-rw-r--r--include/distortos/RawMessageQueue.hpp555
-rw-r--r--include/distortos/SchedulingPolicy.hpp36
-rw-r--r--include/distortos/Semaphore.hpp245
-rw-r--r--include/distortos/SignalAction.hpp96
-rw-r--r--include/distortos/SignalInformation.hpp100
-rw-r--r--include/distortos/SignalInformationQueueWrapper.hpp62
-rw-r--r--include/distortos/SignalSet.hpp179
-rw-r--r--include/distortos/SignalsCatcher.hpp62
-rw-r--r--include/distortos/SignalsReceiver.hpp58
-rw-r--r--include/distortos/SoftwareTimer.hpp130
-rw-r--r--include/distortos/SoftwareTimerCommon.hpp87
-rw-r--r--include/distortos/StaticFifoQueue.hpp57
-rw-r--r--include/distortos/StaticMessageQueue.hpp64
-rw-r--r--include/distortos/StaticRawFifoQueue.hpp69
-rw-r--r--include/distortos/StaticRawMessageQueue.hpp71
-rw-r--r--include/distortos/StaticSignalsReceiver.hpp166
-rw-r--r--include/distortos/StaticSoftwareTimer.hpp90
-rw-r--r--include/distortos/StaticThread.hpp357
-rw-r--r--include/distortos/ThisThread-Signals.hpp279
-rw-r--r--include/distortos/ThisThread.hpp158
-rw-r--r--include/distortos/Thread.hpp194
-rw-r--r--include/distortos/ThreadCommon.hpp230
-rw-r--r--include/distortos/ThreadState.hpp54
-rw-r--r--include/distortos/TickClock.hpp56
-rw-r--r--include/distortos/UndetachableThread.hpp57
-rw-r--r--include/distortos/architecture/InterruptMaskingLock.hpp34
-rw-r--r--include/distortos/architecture/InterruptMaskingUnmaskingLock.hpp73
-rw-r--r--include/distortos/architecture/InterruptUnmaskingLock.hpp34
-rw-r--r--include/distortos/architecture/Stack.hpp122
-rw-r--r--include/distortos/architecture/disableInterruptMasking.hpp37
-rw-r--r--include/distortos/architecture/enableInterruptMasking.hpp40
-rw-r--r--include/distortos/architecture/getMainStack.hpp37
-rw-r--r--include/distortos/architecture/initializeStack.hpp50
-rw-r--r--include/distortos/architecture/lowLevelInitialization.hpp34
-rw-r--r--include/distortos/architecture/requestContextSwitch.hpp35
-rw-r--r--include/distortos/architecture/requestFunctionExecution.hpp53
-rw-r--r--include/distortos/architecture/restoreInterruptMasking.hpp39
-rw-r--r--include/distortos/architecture/startScheduling.hpp33
-rw-r--r--include/distortos/board/lowLevelInitialization.hpp36
-rw-r--r--include/distortos/callOnce.hpp50
-rw-r--r--include/distortos/chip/lowLevelInitialization.hpp34
-rw-r--r--include/distortos/devices/io/InputPin.hpp48
-rw-r--r--include/distortos/devices/io/OutputPin.hpp46
-rw-r--r--include/distortos/distortosVersion.h37
-rw-r--r--include/distortos/internal/memory/DeferredThreadDeleter.hpp121
-rw-r--r--include/distortos/internal/memory/dummyDeleter.hpp48
-rw-r--r--include/distortos/internal/memory/getDeferredThreadDeleter.hpp39
-rw-r--r--include/distortos/internal/memory/getMallocMutex.hpp33
-rw-r--r--include/distortos/internal/memory/storageDeleter.hpp44
-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
-rw-r--r--include/distortos/internal/synchronization/BoundQueueFunctor.hpp89
-rw-r--r--include/distortos/internal/synchronization/CallOnceControlBlock.hpp172
-rw-r--r--include/distortos/internal/synchronization/CopyConstructQueueFunctor.hpp67
-rw-r--r--include/distortos/internal/synchronization/FifoQueueBase.hpp145
-rw-r--r--include/distortos/internal/synchronization/MemcpyPopQueueFunctor.hpp65
-rw-r--r--include/distortos/internal/synchronization/MemcpyPushQueueFunctor.hpp65
-rw-r--r--include/distortos/internal/synchronization/MessageQueueBase.hpp221
-rw-r--r--include/distortos/internal/synchronization/MoveConstructQueueFunctor.hpp69
-rw-r--r--include/distortos/internal/synchronization/MutexControlBlock.hpp184
-rw-r--r--include/distortos/internal/synchronization/MutexList.hpp32
-rw-r--r--include/distortos/internal/synchronization/MutexListNode.hpp53
-rw-r--r--include/distortos/internal/synchronization/QueueFunctor.hpp40
-rw-r--r--include/distortos/internal/synchronization/SemaphoreFunctor.hpp43
-rw-r--r--include/distortos/internal/synchronization/SemaphoreTryWaitForFunctor.hpp62
-rw-r--r--include/distortos/internal/synchronization/SemaphoreTryWaitFunctor.hpp43
-rw-r--r--include/distortos/internal/synchronization/SemaphoreTryWaitUntilFunctor.hpp63
-rw-r--r--include/distortos/internal/synchronization/SemaphoreWaitFunctor.hpp43
-rw-r--r--include/distortos/internal/synchronization/SignalInformationQueue.hpp123
-rw-r--r--include/distortos/internal/synchronization/SignalsCatcherControlBlock.hpp213
-rw-r--r--include/distortos/internal/synchronization/SignalsReceiverControlBlock.hpp243
-rw-r--r--include/distortos/internal/synchronization/SwapPopQueueFunctor.hpp74
-rw-r--r--include/distortos/statistics.hpp38
-rw-r--r--include/estd/ContiguousRange.hpp164
-rw-r--r--include/estd/IntegerSequence.hpp229
-rw-r--r--include/estd/IntrusiveForwardList.hpp1120
-rw-r--r--include/estd/IntrusiveList.hpp1208
-rw-r--r--include/estd/ReferenceHolder.hpp61
-rw-r--r--include/estd/ReverseAdaptor.hpp83
-rw-r--r--include/estd/SortedIntrusiveForwardList.hpp355
-rw-r--r--include/estd/SortedIntrusiveList.hpp353
-rw-r--r--include/estd/TypeErasedFunctor.hpp99
-rw-r--r--include/estd/apply.hpp73
-rw-r--r--include/estd/invoke.hpp147
-rw-r--r--include/motor.h33
-rw-r--r--include/sys/signal.h41
-rw-r--r--libdistortos.abin0 -> 239010 bytes
-rw-r--r--main.cpp126
-rw-r--r--mcuconf.h204
-rw-r--r--setup.mk15
-rw-r--r--src/motor.cpp3
-rw-r--r--vexuser.cpp207
125 files changed, 16100 insertions, 1774 deletions
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 5a7aaed..0000000
--- a/Makefile
+++ /dev/null
@@ -1,239 +0,0 @@
-##############################################################################
-# Build global options
-# NOTE: Can be overridden externally.
-#
-include setup.mk
-
-# Compiler options here.
-ifeq ($(USE_OPT),)
- USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 -fsingle-precision-constant
-endif
-
-# C specific options here (added to USE_OPT).
-ifeq ($(USE_COPT),)
- USE_COPT = -std=gnu99
-endif
-
-# C++ specific options here (added to USE_OPT).
-ifeq ($(USE_CPPOPT),)
- USE_CPPOPT = -fno-rtti
-endif
-
-# Enable this if you want the linker to remove unused code and data
-ifeq ($(USE_LINK_GC),)
- USE_LINK_GC = yes
-endif
-
-# If enabled, this option allows to compile the application in THUMB mode.
-ifeq ($(USE_THUMB),)
- USE_THUMB = yes
-endif
-
-# Enable this if you want to see the full log while compiling.
-ifeq ($(USE_VERBOSE_COMPILE),)
- USE_VERBOSE_COMPILE = yes
-endif
-
-#
-# Build global options
-##############################################################################
-
-##############################################################################
-# Architecture or project specific options
-#
-
-# Enable this if you really want to use the STM FWLib.
-ifeq ($(USE_FWLIB),)
- USE_FWLIB = no
-endif
-
-#
-# Architecture or project specific options
-##############################################################################
-
-##############################################################################
-# Project, sources and paths
-#
-
-# PROS compatible build directory
-ifeq ($(BUILDDIR),)
-BUILDDIR = bin
-endif
-
-# Define project name here
-ifeq ($(PROJECT),)
-PROJECT = output
-endif
-
-# Path to ChibiOS/RT - default assumes making examples
-ifeq ($(CHIBIOS),)
-CHIBIOS = ../../../../ChibiOS_2.6.2
-endif
-
-# Path to ConVEX root - default assumes making examples
-ifeq ($(CONVEX),)
-CONVEX = ../..
-endif
-
-# Imported source files and paths
-include $(CONVEX)/boards/VEX_STM32_CORTEX/board.mk
-include $(CHIBIOS)/os/hal/platforms/STM32F1xx/platform.mk
-include $(CHIBIOS)/os/hal/hal.mk
-include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F1xx/port.mk
-include $(CHIBIOS)/os/kernel/kernel.mk
-include $(CONVEX)/fw/vexfw.mk
-
-# include the optional code
-ifeq ($(CONVEX_OPT),yes)
-include $(CONVEX)/opt/vexopt.mk
-endif
-
-# Define linker script file here
-LDSCRIPT= $(CONVEX)/ld/STM32F103xD.ld
-
-
-# C sources that can be compiled in ARM or THUMB mode depending on the global
-# setting.
-# replaced standard shell with custom variant
-# $(CHIBIOS)/os/various/shell.c \
-
-CSRC = $(PORTSRC) \
- $(KERNSRC) \
- $(HALSRC) \
- $(PLATFORMSRC) \
- $(BOARDSRC) \
- $(CHIBIOS)/os/various/evtimer.c \
- $(CHIBIOS)/os/various/syscalls.c \
- $(CHIBIOS)/os/various/chprintf.c \
- $(VEXFWSRC) \
- $(VEXOPTSRC)
-# $(VEXUSERSRC) \
-# main.c
-
-# C++ sources that can be compiled in ARM or THUMB mode depending on the global
-# setting.
-CPPSRC = $(VEXUSERSRC) \
- main.cpp
-
-# C sources to be compiled in ARM mode regardless of the global setting.
-# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
-# option that results in lower performance and larger code size.
-ACSRC =
-
-# C++ sources to be compiled in ARM mode regardless of the global setting.
-# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
-# option that results in lower performance and larger code size.
-ACPPSRC =
-
-# C sources to be compiled in THUMB mode regardless of the global setting.
-# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
-# option that results in lower performance and larger code size.
-TCSRC =
-
-# C sources to be compiled in THUMB mode regardless of the global setting.
-# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
-# option that results in lower performance and larger code size.
-TCPPSRC =
-
-# List ASM source files here
-ASMSRC = $(PORTASM)
-
-INCDIR = $(PORTINC) $(KERNINC) \
- $(HALINC) $(PLATFORMINC) $(BOARDINC) \
- $(CHIBIOS)/os/various $(VEXFWINC) $(VEXOPTINC) $(VEXUSERINC)
-
-#
-# Project, sources and paths
-##############################################################################
-
-##############################################################################
-# Compiler settings
-#
-
-MCU = cortex-m3
-
-#TRGT = arm-elf-
-TRGT = arm-none-eabi-
-CC = $(TRGT)gcc
-CPPC = $(TRGT)g++
-# Enable loading with g++ only if you need C++ runtime support.
-# NOTE: You can use C++ even without C++ support if you are careful. C++
-# runtime support makes code size explode.
-#D = $(TRGT)gcc
-LD = $(TRGT)g++
-CP = $(TRGT)objcopy
-AS = $(TRGT)gcc -x assembler-with-cpp
-OD = $(TRGT)objdump
-HEX = $(CP) -O ihex
-BIN = $(CP) -O binary
-
-# ARM-specific options here
-AOPT = -mfloat-abi=hard -mcpu=cortex-m3
-
-# THUMB-specific options here
-TOPT = -mthumb -DTHUMB
-
-# Define C warning options here
-CWARN = -Wall -Wextra -Wstrict-prototypes
-
-# Define C++ warning options here
-CPPWARN = -Wall -Wextra -Wno-write-strings
-
-#
-# Compiler settings
-##############################################################################
-
-##############################################################################
-# Start of default section
-#
-
-# List all default C defines here, like -D_DEBUG=1
-DDEFS =
-
-# List all default ASM defines here, like -D_DEBUG=1
-DADEFS =
-
-# List all default directories to look for include files here
-DINCDIR =
-
-# List the default directory to look for the libraries here
-DLIBDIR =
-
-# List all default libraries here
-DLIBS =
-
-#
-# End of default section
-##############################################################################
-
-##############################################################################
-# Start of user section
-#
-
-# List all user C define here, like -D_DEBUG=1
-UDEFS =
-
-# Define ASM defines here
-UADEFS =
-
-# List all user directories here
-UINCDIR =
-
-# List the user directory to look for the libraries here
-ULIBDIR =
-
-# List all user libraries here
-ULIBS = -lm
-
-#
-# End of user defines
-##############################################################################
-
-ifeq ($(USE_FWLIB),yes)
- include $(CHIBIOS)/ext/stm32lib/stm32lib.mk
- CSRC += $(STM32SRC)
- INCDIR += $(STM32INC)
- USE_OPT += -DUSE_STDPERIPH_DRIVER
-endif
-
-include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk
diff --git a/STM32F103VD.ld b/STM32F103VD.ld
new file mode 100644
index 0000000..21f2004
--- /dev/null
+++ b/STM32F103VD.ld
@@ -0,0 +1,267 @@
+/**
+ * \file
+ * \brief Linker script for STM32F103VD chip:
+ * - 393216 bytes of rom;
+ * - 65536 bytes of ram;
+ *
+ * \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/.
+ *
+ * \warning
+ * Automatically generated file - do not edit!
+ *
+ * \date 2016-11-08 19:50:43
+ */
+
+SEARCH_DIR(.);
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm");
+OUTPUT_ARCH(arm);
+
+/*---------------------------------------------------------------------------------------------------------------------+
+| stacks sizes
++---------------------------------------------------------------------------------------------------------------------*/
+
+/* Handler mode (core exceptions / interrupts) can use only main stack */
+PROVIDE(__main_stack_size = 2048);
+
+/* Thread mode can use main stack (default after reset) or process stack - selected in CONTROL special register */
+PROVIDE(__process_stack_size = 2048);
+
+/*---------------------------------------------------------------------------------------------------------------------+
+| available memories
++---------------------------------------------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ rom : org = 0x08000000, len = 393216
+ ram : org = 0x20000000, len = 65536
+}
+
+PROVIDE(__rom_start = ORIGIN(rom));
+PROVIDE(__rom_size = LENGTH(rom));
+PROVIDE(__rom_end = __rom_start + __rom_size);
+
+PROVIDE(__ram_start = ORIGIN(ram));
+PROVIDE(__ram_size = LENGTH(ram));
+PROVIDE(__ram_end = __ram_start + __ram_size);
+
+/*---------------------------------------------------------------------------------------------------------------------+
+| entry point
++---------------------------------------------------------------------------------------------------------------------*/
+
+ENTRY(Reset_Handler);
+
+/*---------------------------------------------------------------------------------------------------------------------+
+| put data in sections
++---------------------------------------------------------------------------------------------------------------------*/
+
+SECTIONS
+{
+ .text :
+ {
+ . = ALIGN(4);
+ PROVIDE(__text_start = .);
+
+ /* sub-section: .vectors */
+
+ . = ALIGN(4);
+ PROVIDE(__vectors_start = .);
+
+ KEEP(*(.coreVectors));
+ KEEP(*(.chipVectors));
+
+ . = ALIGN(4);
+ PROVIDE(__vectors_end = .);
+
+ /* end of sub-section: .vectors */
+
+ *(.text* .gnu.linkonce.t.*);
+ *(.rodata* .gnu.linkonce.r.*);
+ *(.glue_7t .glue_7);
+
+ *(.ARM.extab* .gnu.linkonce.armextab.*); /* exception unwinding information */
+ *(.gcc_except_table); /* information used for stack unwinding during exception */
+ *(.eh_frame_hdr); /* additional information about .ex_frame section */
+ *(.eh_frame); /* information used for stack unwinding during exception */
+
+ /* sub-section: data_array */
+
+ . = ALIGN(4);
+ PROVIDE(__data_array_start = .);
+
+ LONG(LOADADDR(.data)); LONG(ADDR(.data)); LONG(ADDR(.data) + SIZEOF(.data));
+
+ . = ALIGN(4);
+ PROVIDE(__data_array_end = .);
+
+ /* end of sub-section: data_array */
+
+ /* sub-section: bss_array */
+
+ . = ALIGN(4);
+ PROVIDE(__bss_array_start = .);
+
+ LONG(ADDR(.bss)); LONG(ADDR(.bss) + SIZEOF(.bss));
+ LONG(ADDR(.stack)); LONG(ADDR(.stack) + SIZEOF(.stack));
+
+ . = ALIGN(4);
+ PROVIDE(__bss_array_end = .);
+
+ /* end of sub-section: bss_array */
+
+ /* sub-sections: init, preinit_array, init_array and fini_array */
+
+ KEEP(*(.init));
+
+ . = ALIGN(4);
+ PROVIDE(__preinit_array_start = .);
+
+ KEEP(*(.preinit_array));
+
+ . = ALIGN(4);
+ PROVIDE(__preinit_array_end = .);
+
+ . = ALIGN(4);
+ PROVIDE(__init_array_start = .);
+
+ KEEP(*(SORT(.init_array.*)));
+ KEEP(*(.init_array));
+
+ . = ALIGN(4);
+ PROVIDE(__init_array_end = .);
+
+ KEEP(*(.fini));
+
+ . = ALIGN(4);
+ PROVIDE(__fini_array_start = .);
+
+ KEEP(*(.fini_array));
+ KEEP(*(SORT(.fini_array.*)));
+
+ . = ALIGN(4);
+ PROVIDE(__fini_array_end = .);
+
+ /* end of sub-sections: init, preinit_array, init_array and fini_array */
+
+ . = ALIGN(4);
+ PROVIDE(__text_end = .);
+ } > rom AT > rom
+
+ . = ALIGN(4);
+ PROVIDE(__exidx_start = .);
+
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*);
+ } > rom AT > rom /* index entries for section unwinding */
+
+ . = ALIGN(4);
+ PROVIDE(__exidx_end = .);
+
+ .bss :
+ {
+ . = ALIGN(4);
+ PROVIDE(__bss_start = .);
+
+ *(.bss* .gnu.linkonce.b.*)
+ *(COMMON);
+
+ . = ALIGN(4);
+ PROVIDE(__bss_end = .);
+ } > ram AT > ram
+
+ .data :
+ {
+ . = ALIGN(4);
+ PROVIDE(__data_init_start = LOADADDR(.data));
+ PROVIDE(__data_start = .);
+
+ *(.data* .gnu.linkonce.d.*)
+
+ . = ALIGN(4);
+ PROVIDE(__data_end = .);
+ } > ram AT > rom
+
+ .noinit (NOLOAD) :
+ {
+ . = ALIGN(4);
+ PROVIDE(__noinit_start = .);
+
+ *(.noinit)
+
+ . = ALIGN(4);
+ PROVIDE(__noinit_end = .);
+ } > ram AT > ram
+
+ .stack :
+ {
+ . = ALIGN(8);
+ PROVIDE(__stack_start = .);
+ PROVIDE(__main_stack_start = .);
+
+ . += __main_stack_size;
+
+ . = ALIGN(8);
+ PROVIDE(__main_stack_end = .);
+ PROVIDE(__process_stack_start = .);
+
+ . += __process_stack_size;
+
+ . = ALIGN(8);
+ PROVIDE(__process_stack_end = .);
+ PROVIDE(__stack_end = .);
+ } > ram AT > ram
+
+ . = ALIGN(4);
+ PROVIDE(__heap_start = .);
+ PROVIDE(__heap_end = __ram_end);
+
+ .stab 0 (NOLOAD) : { *(.stab) }
+ .stabstr 0 (NOLOAD) : { *(.stabstr) }
+ /* DWARF debug sections.
+ * Symbols in the DWARF debugging sections are relative to the beginning
+ * of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ .note.gnu.arm.ident 0 : { KEEP(*(.note.gnu.arm.ident)) }
+ .ARM.attributes 0 : { KEEP(*(.ARM.attributes)) }
+ /DISCARD/ : { *(.note.GNU-stack) }
+}
+
+PROVIDE(__text_size = __text_end - __text_start);
+PROVIDE(__vectors_size = __vectors_end - __vectors_start);
+PROVIDE(__data_array_size = __data_array_end - __data_array_start);
+PROVIDE(__bss_array_size = __bss_array_end - __bss_array_start);
+PROVIDE(__exidx_size = __exidx_end - __exidx_start);
+PROVIDE(__bss_size = __bss_end - __bss_start);
+PROVIDE(__data_size = __data_end - __data_start);
+PROVIDE(__noinit_size = __noinit_end - __noinit_start);
+PROVIDE(__stack_size = __stack_end - __stack_start);
+PROVIDE(__heap_size = __heap_end - __heap_start);
+
+PROVIDE(__bss_start__ = __bss_start);
+PROVIDE(__bss_end__ = __bss_end);
diff --git a/chconf.h b/chconf.h
deleted file mode 100644
index f943ea8..0000000
--- a/chconf.h
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file templates/chconf.h
- * @brief Configuration file template.
- * @details A copy of this file must be placed in each project directory, it
- * contains the application specific kernel settings.
- *
- * @addtogroup config
- * @details Kernel related settings and hooks.
- * @{
- */
-
-#ifndef _CHCONF_H_
-#define _CHCONF_H_
-
-/*===========================================================================*/
-/**
- * @name Kernel parameters and options
- * @{
- */
-/*===========================================================================*/
-
-/**
- * @brief System tick frequency.
- * @details Frequency of the system timer that drives the system ticks. This
- * setting also defines the system tick time unit.
- */
-#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
-#define CH_FREQUENCY 1000
-#endif
-
-/**
- * @brief Round robin interval.
- * @details This constant is the number of system ticks allowed for the
- * threads before preemption occurs. Setting this value to zero
- * disables the preemption for threads with equal priority and the
- * round robin becomes cooperative. Note that higher priority
- * threads can still preempt, the kernel is always preemptive.
- *
- * @note Disabling the round robin preemption makes the kernel more compact
- * and generally faster.
- */
-#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
-#define CH_TIME_QUANTUM 20
-#endif
-
-/**
- * @brief Managed RAM size.
- * @details Size of the RAM area to be managed by the OS. If set to zero
- * then the whole available RAM is used. The core memory is made
- * available to the heap allocator and/or can be used directly through
- * the simplified core memory allocator.
- *
- * @note In order to let the OS manage the whole RAM the linker script must
- * provide the @p __heap_base__ and @p __heap_end__ symbols.
- * @note Requires @p CH_USE_MEMCORE.
- */
-#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
-#define CH_MEMCORE_SIZE 0
-#endif
-
-/**
- * @brief Idle thread automatic spawn suppression.
- * @details When this option is activated the function @p chSysInit()
- * does not spawn the idle thread automatically. The application has
- * then the responsibility to do one of the following:
- * - Spawn a custom idle thread at priority @p IDLEPRIO.
- * - Change the main() thread priority to @p IDLEPRIO then enter
- * an endless loop. In this scenario the @p main() thread acts as
- * the idle thread.
- * .
- * @note Unless an idle thread is spawned the @p main() thread must not
- * enter a sleep state.
- */
-#if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__)
-#define CH_NO_IDLE_THREAD FALSE
-#endif
-
-/** @} */
-
-/*===========================================================================*/
-/**
- * @name Performance options
- * @{
- */
-/*===========================================================================*/
-
-/**
- * @brief OS optimization.
- * @details If enabled then time efficient rather than space efficient code
- * is used when two possible implementations exist.
- *
- * @note This is not related to the compiler optimization options.
- * @note The default is @p TRUE.
- */
-#if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__)
-#define CH_OPTIMIZE_SPEED TRUE
-#endif
-
-/** @} */
-
-/*===========================================================================*/
-/**
- * @name Subsystem options
- * @{
- */
-/*===========================================================================*/
-
-/**
- * @brief Threads registry APIs.
- * @details If enabled then the registry APIs are included in the kernel.
- *
- * @note The default is @p TRUE.
- */
-#if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__)
-#define CH_USE_REGISTRY TRUE
-#endif
-
-/**
- * @brief Threads synchronization APIs.
- * @details If enabled then the @p chThdWait() function is included in
- * the kernel.
- *
- * @note The default is @p TRUE.
- */
-#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
-#define CH_USE_WAITEXIT TRUE
-#endif
-
-/**
- * @brief Semaphores APIs.
- * @details If enabled then the Semaphores APIs are included in the kernel.
- *
- * @note The default is @p TRUE.
- */
-#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
-#define CH_USE_SEMAPHORES TRUE
-#endif
-
-/**
- * @brief Semaphores queuing mode.
- * @details If enabled then the threads are enqueued on semaphores by
- * priority rather than in FIFO order.
- *
- * @note The default is @p FALSE. Enable this if you have special requirements.
- * @note Requires @p CH_USE_SEMAPHORES.
- */
-#if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__)
-#define CH_USE_SEMAPHORES_PRIORITY FALSE
-#endif
-
-/**
- * @brief Atomic semaphore API.
- * @details If enabled then the semaphores the @p chSemSignalWait() API
- * is included in the kernel.
- *
- * @note The default is @p TRUE.
- * @note Requires @p CH_USE_SEMAPHORES.
- */
-#if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__)
-#define CH_USE_SEMSW TRUE
-#endif
-
-/**
- * @brief Mutexes APIs.
- * @details If enabled then the mutexes APIs are included in the kernel.
- *
- * @note The default is @p TRUE.
- */
-#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
-#define CH_USE_MUTEXES TRUE
-#endif
-
-/**
- * @brief Conditional Variables APIs.
- * @details If enabled then the conditional variables APIs are included
- * in the kernel.
- *
- * @note The default is @p TRUE.
- * @note Requires @p CH_USE_MUTEXES.
- */
-#if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__)
-#define CH_USE_CONDVARS TRUE
-#endif
-
-/**
- * @brief Conditional Variables APIs with timeout.
- * @details If enabled then the conditional variables APIs with timeout
- * specification are included in the kernel.
- *
- * @note The default is @p TRUE.
- * @note Requires @p CH_USE_CONDVARS.
- */
-#if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__)
-#define CH_USE_CONDVARS_TIMEOUT TRUE
-#endif
-
-/**
- * @brief Events Flags APIs.
- * @details If enabled then the event flags APIs are included in the kernel.
- *
- * @note The default is @p TRUE.
- */
-#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
-#define CH_USE_EVENTS TRUE
-#endif
-
-/**
- * @brief Events Flags APIs with timeout.
- * @details If enabled then the events APIs with timeout specification
- * are included in the kernel.
- *
- * @note The default is @p TRUE.
- * @note Requires @p CH_USE_EVENTS.
- */
-#if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__)
-#define CH_USE_EVENTS_TIMEOUT TRUE
-#endif
-
-/**
- * @brief Synchronous Messages APIs.
- * @details If enabled then the synchronous messages APIs are included
- * in the kernel.
- *
- * @note The default is @p TRUE.
- */
-#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
-#define CH_USE_MESSAGES TRUE
-#endif
-
-/**
- * @brief Synchronous Messages queuing mode.
- * @details If enabled then messages are served by priority rather than in
- * FIFO order.
- *
- * @note The default is @p FALSE. Enable this if you have special requirements.
- * @note Requires @p CH_USE_MESSAGES.
- */
-#if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__)
-#define CH_USE_MESSAGES_PRIORITY FALSE
-#endif
-
-/**
- * @brief Mailboxes APIs.
- * @details If enabled then the asynchronous messages (mailboxes) APIs are
- * included in the kernel.
- *
- * @note The default is @p TRUE.
- * @note Requires @p CH_USE_SEMAPHORES.
- */
-#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
-#define CH_USE_MAILBOXES TRUE
-#endif
-
-/**
- * @brief I/O Queues APIs.
- * @details If enabled then the I/O queues APIs are included in the kernel.
- *
- * @note The default is @p TRUE.
- */
-#if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__)
-#define CH_USE_QUEUES TRUE
-#endif
-
-/**
- * @brief Core Memory Manager APIs.
- * @details If enabled then the core memory manager APIs are included
- * in the kernel.
- *
- * @note The default is @p TRUE.
- */
-#if !defined(CH_USE_MEMCORE) || defined(__DOXYGEN__)
-#define CH_USE_MEMCORE TRUE
-#endif
-
-/**
- * @brief Heap Allocator APIs.
- * @details If enabled then the memory heap allocator APIs are included
- * in the kernel.
- *
- * @note The default is @p TRUE.
- * @note Requires @p CH_USE_MEMCORE and either @p CH_USE_MUTEXES or
- * @p CH_USE_SEMAPHORES.
- * @note Mutexes are recommended.
- */
-#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
-#define CH_USE_HEAP TRUE
-#endif
-
-/**
- * @brief C-runtime allocator.
- * @details If enabled the the heap allocator APIs just wrap the C-runtime
- * @p malloc() and @p free() functions.
- *
- * @note The default is @p FALSE.
- * @note Requires @p CH_USE_HEAP.
- * @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the
- * appropriate documentation.
- */
-#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
-#define CH_USE_MALLOC_HEAP FALSE
-#endif
-
-/**
- * @brief Memory Pools Allocator APIs.
- * @details If enabled then the memory pools allocator APIs are included
- * in the kernel.
- *
- * @note The default is @p TRUE.
- */
-#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
-#define CH_USE_MEMPOOLS TRUE
-#endif
-
-/**
- * @brief Dynamic Threads APIs.
- * @details If enabled then the dynamic threads creation APIs are included
- * in the kernel.
- *
- * @note The default is @p TRUE.
- * @note Requires @p CH_USE_WAITEXIT.
- * @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS.
- */
-#if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__)
-#define CH_USE_DYNAMIC TRUE
-#endif
-
-/** @} */
-
-/*===========================================================================*/
-/**
- * @name Debug options
- * @{
- */
-/*===========================================================================*/
-
-/**
- * @brief Debug option, system state check.
- * @details If enabled the correct call protocol for system APIs is checked
- * at runtime.
- *
- * @note The default is @p FALSE.
- */
-#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
-#define CH_DBG_SYSTEM_STATE_CHECK FALSE
-#endif
-
-/**
- * @brief Debug option, parameters checks.
- * @details If enabled then the checks on the API functions input
- * parameters are activated.
- *
- * @note The default is @p FALSE.
- */
-#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
-#define CH_DBG_ENABLE_CHECKS FALSE
-#endif
-
-/**
- * @brief Debug option, consistency checks.
- * @details If enabled then all the assertions in the kernel code are
- * activated. This includes consistency checks inside the kernel,
- * runtime anomalies and port-defined checks.
- *
- * @note The default is @p FALSE.
- */
-#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
-#define CH_DBG_ENABLE_ASSERTS FALSE
-#endif
-
-/**
- * @brief Debug option, trace buffer.
- * @details If enabled then the context switch circular trace buffer is
- * activated.
- *
- * @note The default is @p FALSE.
- */
-#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
-#define CH_DBG_ENABLE_TRACE FALSE
-#endif
-
-/**
- * @brief Debug option, stack checks.
- * @details If enabled then a runtime stack check is performed.
- *
- * @note The default is @p FALSE.
- * @note The stack check is performed in a architecture/port dependent way.
- * It may not be implemented or some ports.
- * @note The default failure mode is to halt the system with the global
- * @p panic_msg variable set to @p NULL.
- */
-#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
-#define CH_DBG_ENABLE_STACK_CHECK FALSE
-#endif
-
-/**
- * @brief Debug option, stacks initialization.
- * @details If enabled then the threads working area is filled with a byte
- * value when a thread is created. This can be useful for the
- * runtime measurement of the used stack.
- *
- * @note The default is @p FALSE.
- */
-#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
-#define CH_DBG_FILL_THREADS FALSE
-#endif
-
-/**
- * @brief Debug option, threads profiling.
- * @details If enabled then a field is added to the @p Thread structure that
- * counts the system ticks occurred while executing the thread.
- *
- * @note The default is @p TRUE.
- * @note This debug option is defaulted to TRUE because it is required by
- * some test cases into the test suite.
- */
-#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
-#define CH_DBG_THREADS_PROFILING TRUE
-#endif
-
-/** @} */
-
-/*===========================================================================*/
-/**
- * @name Kernel hooks
- * @{
- */
-/*===========================================================================*/
-
-/**
- * @brief Threads descriptor structure extension.
- * @details User fields added to the end of the @p Thread structure.
- */
-#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
-#define THREAD_EXT_FIELDS \
- /* Add threads custom fields here.*/
-#endif
-
-/**
- * @brief Threads initialization hook.
- * @details User initialization code added to the @p chThdInit() API.
- *
- * @note It is invoked from within @p chThdInit() and implicitly from all
- * the threads creation APIs.
- */
-#if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__)
-#define THREAD_EXT_INIT_HOOK(tp) { \
- /* Add threads initialization code here.*/ \
-}
-#endif
-
-/**
- * @brief Threads finalization hook.
- * @details User finalization code added to the @p chThdExit() API.
- *
- * @note It is inserted into lock zone.
- * @note It is also invoked when the threads simply return in order to
- * terminate.
- */
-#if !defined(THREAD_EXT_EXIT_HOOK) || defined(__DOXYGEN__)
-#define THREAD_EXT_EXIT_HOOK(tp) { \
- /* Add threads finalization code here.*/ \
-}
-#endif
-
-/**
- * @brief Context switch hook.
- * @details This hook is invoked just before switching between threads.
- */
-#if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__)
-#define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \
- /* System halt code here.*/ \
-}
-#endif
-
-/**
- * @brief Idle Loop hook.
- * @details This hook is continuously invoked by the idle thread loop.
- */
-#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
-#define IDLE_LOOP_HOOK() { \
- /* Idle loop code here.*/ \
-}
-#endif
-
-/**
- * @brief System tick event hook.
- * @details This hook is invoked in the system tick handler immediately
- * after processing the virtual timers queue.
- */
-#if !defined(SYSTEM_TICK_EVENT_HOOK) || defined(__DOXYGEN__)
-#define SYSTEM_TICK_EVENT_HOOK() { \
- /* System tick event code here.*/ \
-}
-#endif
-
-/**
- * @brief System halt hook.
- * @details This hook is invoked in case to a system halting error before
- * the system is halted.
- */
-#if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
-#define SYSTEM_HALT_HOOK() { \
- /* System halt code here.*/ \
-}
-#endif
-
-/** @} */
-
-/*===========================================================================*/
-/* Port-specific settings (override port settings defaulted in chcore.h). */
-/*===========================================================================*/
-
-#endif /* _CHCONF_H_ */
-
-/** @} */
diff --git a/halconf.h b/halconf.h
deleted file mode 100644
index aaf2f31..0000000
--- a/halconf.h
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file templates/halconf.h
- * @brief HAL configuration header.
- * @details HAL configuration file, this file allows to enable or disable the
- * various device drivers from your application. You may also use
- * this file in order to override the device drivers default settings.
- *
- * @addtogroup HAL_CONF
- * @{
- */
-
-#ifndef _HALCONF_H_
-#define _HALCONF_H_
-
-#include "mcuconf.h"
-
-/**
- * @brief Enables the TM subsystem.
- */
-#if !defined(HAL_USE_TM) || defined(__DOXYGEN__)
-#define HAL_USE_TM TRUE
-#endif
-
-/**
- * @brief Enables the PAL subsystem.
- */
-#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
-#define HAL_USE_PAL TRUE
-#endif
-
-/**
- * @brief Enables the ADC subsystem.
- */
-#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
-#define HAL_USE_ADC TRUE
-#endif
-
-/**
- * @brief Enables the CAN subsystem.
- */
-#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
-#define HAL_USE_CAN FALSE
-#endif
-
-/**
- * @brief Enables the EXT subsystem.
- */
-#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
-#define HAL_USE_EXT TRUE
-#endif
-
-/**
- * @brief Enables the GPT subsystem.
- */
-#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
-#define HAL_USE_GPT TRUE
-#endif
-
-/**
- * @brief Enables the I2C subsystem.
- */
-#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
-#define HAL_USE_I2C TRUE
-#endif
-
-/**
- * @brief Enables the ICU subsystem.
- */
-#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
-#define HAL_USE_ICU FALSE
-#endif
-
-/**
- * @brief Enables the MAC subsystem.
- */
-#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
-#define HAL_USE_MAC FALSE
-#endif
-
-/**
- * @brief Enables the MMC_SPI subsystem.
- */
-#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
-#define HAL_USE_MMC_SPI FALSE
-#endif
-
-/**
- * @brief Enables the PWM subsystem.
- */
-#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
-#define HAL_USE_PWM FALSE
-#endif
-
-/**
- * @brief Enables the RTC subsystem.
- */
-#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
-#define HAL_USE_RTC FALSE
-#endif
-
-/**
- * @brief Enables the SDC subsystem.
- */
-#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
-#define HAL_USE_SDC FALSE
-#endif
-
-/**
- * @brief Enables the SERIAL subsystem.
- */
-#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
-#define HAL_USE_SERIAL TRUE
-#endif
-
-/**
- * @brief Enables the SERIAL over USB subsystem.
- */
-#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
-#define HAL_USE_SERIAL_USB FALSE
-#endif
-
-/**
- * @brief Enables the SPI subsystem.
- */
-#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
-#define HAL_USE_SPI TRUE
-#endif
-
-/**
- * @brief Enables the UART subsystem.
- */
-#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
-#define HAL_USE_UART FALSE
-#endif
-
-/**
- * @brief Enables the USB subsystem.
- */
-#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
-#define HAL_USE_USB FALSE
-#endif
-
-/*===========================================================================*/
-/* ADC driver related settings. */
-/*===========================================================================*/
-
-/**
- * @brief Enables synchronous APIs.
- * @note Disabling this option saves both code and data space.
- */
-#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
-#define ADC_USE_WAIT TRUE
-#endif
-
-/**
- * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
- * @note Disabling this option saves both code and data space.
- */
-#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
-#define ADC_USE_MUTUAL_EXCLUSION TRUE
-#endif
-
-/*===========================================================================*/
-/* CAN driver related settings. */
-/*===========================================================================*/
-
-/**
- * @brief Sleep mode related APIs inclusion switch.
- */
-#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
-#define CAN_USE_SLEEP_MODE TRUE
-#endif
-
-/*===========================================================================*/
-/* I2C driver related settings. */
-/*===========================================================================*/
-
-/**
- * @brief Enables the mutual exclusion APIs on the I2C bus.
- */
-#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
-#define I2C_USE_MUTUAL_EXCLUSION TRUE
-#endif
-
-/*===========================================================================*/
-/* MAC driver related settings. */
-/*===========================================================================*/
-
-/**
- * @brief Enables an event sources for incoming packets.
- */
-#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
-#define MAC_USE_ZERO_COPY FALSE
-#endif
-
-/**
- * @brief Enables an event sources for incoming packets.
- */
-#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
-#define MAC_USE_EVENTS TRUE
-#endif
-
-/*===========================================================================*/
-/* MMC_SPI driver related settings. */
-/*===========================================================================*/
-
-/**
- * @brief Block size for MMC transfers.
- */
-#if !defined(MMC_SECTOR_SIZE) || defined(__DOXYGEN__)
-#define MMC_SECTOR_SIZE 512
-#endif
-
-/**
- * @brief Delays insertions.
- * @details If enabled this options inserts delays into the MMC waiting
- * routines releasing some extra CPU time for the threads with
- * lower priority, this may slow down the driver a bit however.
- * This option is recommended also if the SPI driver does not
- * use a DMA channel and heavily loads the CPU.
- */
-#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
-#define MMC_NICE_WAITING TRUE
-#endif
-
-/**
- * @brief Number of positive insertion queries before generating the
- * insertion event.
- */
-#if !defined(MMC_POLLING_INTERVAL) || defined(__DOXYGEN__)
-#define MMC_POLLING_INTERVAL 10
-#endif
-
-/**
- * @brief Interval, in milliseconds, between insertion queries.
- */
-#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__)
-#define MMC_POLLING_DELAY 10
-#endif
-
-/**
- * @brief Uses the SPI polled API for small data transfers.
- * @details Polled transfers usually improve performance because it
- * saves two context switches and interrupt servicing. Note
- * that this option has no effect on large transfers which
- * are always performed using DMAs/IRQs.
- */
-#if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__)
-#define MMC_USE_SPI_POLLING TRUE
-#endif
-
-/*===========================================================================*/
-/* SDC driver related settings. */
-/*===========================================================================*/
-
-/**
- * @brief Number of initialization attempts before rejecting the card.
- * @note Attempts are performed at 10mS intervals.
- */
-#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
-#define SDC_INIT_RETRY 100
-#endif
-
-/**
- * @brief Include support for MMC cards.
- * @note MMC support is not yet implemented so this option must be kept
- * at @p FALSE.
- */
-#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
-#define SDC_MMC_SUPPORT FALSE
-#endif
-
-/**
- * @brief Delays insertions.
- * @details If enabled this options inserts delays into the MMC waiting
- * routines releasing some extra CPU time for the threads with
- * lower priority, this may slow down the driver a bit however.
- */
-#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
-#define SDC_NICE_WAITING TRUE
-#endif
-
-/*===========================================================================*/
-/* SERIAL driver related settings. */
-/*===========================================================================*/
-
-/**
- * @brief Default bit rate.
- * @details Configuration parameter, this is the baud rate selected for the
- * default configuration.
- */
-#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
-#define SERIAL_DEFAULT_BITRATE 19200
-#endif
-
-/**
- * @brief Serial buffers size.
- * @details Configuration parameter, you can change the depth of the queue
- * buffers depending on the requirements of your application.
- * @note The default is 64 bytes for both the transmission and receive
- * buffers.
- */
-#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
-#define SERIAL_BUFFERS_SIZE 64
-#endif
-
-/*===========================================================================*/
-/* SPI driver related settings. */
-/*===========================================================================*/
-
-/**
- * @brief Enables synchronous APIs.
- * @note Disabling this option saves both code and data space.
- */
-#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
-#define SPI_USE_WAIT TRUE
-#endif
-
-/**
- * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
- * @note Disabling this option saves both code and data space.
- */
-#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
-#define SPI_USE_MUTUAL_EXCLUSION TRUE
-#endif
-
-#endif /* _HALCONF_H_ */
-
-/** @} */
diff --git a/include/control.h b/include/control.h
deleted file mode 100644
index ee9cca2..0000000
--- a/include/control.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef CONTROL_H_
-#define CONTROL_H_
-
-#include <stdint.h>
-
-#include "ch.h"
-#include "hal.h"
-#include "vex.h"
-
-typedef enum {
- BUTTON_UP,
- BUTTON_RELEASE,
- BUTTON_DOWN
-} button_t;
-
-struct joydata_t {
- int Ch1 :8;
- int Ch2 :8;
- int Ch3 :8;
- int Ch4 :8;
-
- struct accel_t {
- int y :8;
- int x :8;
- int z :8;
- } __attribute__ ((packed)) accel;
-
- char Btn5D :1;
- char Btn5U :1;
- char Btn6D :1;
- char Btn6U :1;
-
- char Reserved :4;
-
- char Btn8D :1;
- char Btn8L :1;
- char Btn8U :1;
- char Btn8R :1;
- char Btn7D :1;
- char Btn7L :1;
- char Btn7U :1;
- char Btn7R :1;
-
- char Reserved2[2];
-
-} __attribute__ ((packed));
-
-struct Controller {
-private:
- int index;
- struct joydata_t* data;
-
-public:
- Controller(int idx = 1)
- : index(idx), data(nullptr) {}
- ~Controller(void) {}
-
- void update(void) {
- data = reinterpret_cast<struct joydata_t*>(vexSpiGetJoystickDataPtr(index));
- data->Ch1 = vexControllerGet(Ch1);//( data->Ch1 == 0xFF ) ? 127 : data->Ch1 - 127;
- data->Ch2 = vexControllerGet(Ch2);//-(( data->Ch2 == 0xFF ) ? 127 : data->Ch2 - 127);
- data->Ch3 = vexControllerGet(Ch3);//-(( data->Ch3 == 0xFF ) ? 127 : data->Ch3 - 127);
- data->Ch4 = vexControllerGet(Ch4);//( data->Ch4 == 0xFF ) ? 127 : data->Ch4 - 127;
- }
-
- inline const struct joydata_t* operator->(void) const
- { return data; }
-
-} __attribute__ ((packed));
-
-#endif // CONTROL_H_
diff --git a/include/distortos/ConditionVariable.hpp b/include/distortos/ConditionVariable.hpp
new file mode 100644
index 0000000..6b7f869
--- /dev/null
+++ b/include/distortos/ConditionVariable.hpp
@@ -0,0 +1,304 @@
+/**
+ * \file
+ * \brief ConditionVariable 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_CONDITIONVARIABLE_HPP_
+#define INCLUDE_DISTORTOS_CONDITIONVARIABLE_HPP_
+
+#include "distortos/internal/scheduler/ThreadList.hpp"
+
+#include "distortos/TickClock.hpp"
+
+namespace distortos
+{
+
+class Mutex;
+
+/**
+ * \brief ConditionVariable is an advanced synchronization primitive
+ *
+ * Similar to std::condition_variable - http://en.cppreference.com/w/cpp/thread/condition_variable
+ * Similar to POSIX pthread_cond_t
+ *
+ * \ingroup synchronization
+ */
+
+class ConditionVariable
+{
+public:
+
+ /**
+ * \brief ConditionVariable constructor
+ *
+ * Similar to std::condition_variable::condition_variable() -
+ * http://en.cppreference.com/w/cpp/thread/condition_variable/condition_variable
+ * Similar to pthread_cond_init() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_init.html
+ */
+
+ constexpr ConditionVariable() :
+ blockedList_{}
+ {
+
+ }
+
+ /**
+ * \brief Notifies all waiting threads.
+ *
+ * Similar to std::condition_variable::notify_all() -
+ * http://en.cppreference.com/w/cpp/thread/condition_variable/notify_all
+ * Similar to pthread_cond_broadcast() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_signal.html
+ *
+ * Unblocks all threads waiting on this condition variable. The notifying thread does not need to hold the same
+ * mutex as the one held by the waiting thread(s).
+ */
+
+ void notifyAll();
+
+ /**
+ * \brief Notifies one waiting thread.
+ *
+ * Similar to std::condition_variable::notify_one() -
+ * http://en.cppreference.com/w/cpp/thread/condition_variable/notify_one
+ * Similar to pthread_cond_signal() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_signal.html
+ *
+ * Unblocks one thread waiting on this condition variable. The notifying thread does not need to hold the same
+ * mutex as the one held by the waiting thread(s).
+ */
+
+ void notifyOne();
+
+ /**
+ * \brief Waits for notification.
+ *
+ * Similar to std::condition_variable::wait() - http://en.cppreference.com/w/cpp/thread/condition_variable/wait
+ * Similar to pthread_cond_wait() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_wait.html
+ *
+ * Atomically releases supplied mutex and blocks current thread until the condition variable is notified. The thread
+ * will be unblocked when notifyAll() or notifyOne() is executed. It may also be unblocked spuriously. When
+ * unblocked, regardless of the reason, lock is reacquired and wait exits.
+ *
+ * \param [in] mutex is a reference to mutex which must be owned by calling thread
+ *
+ * \return zero if the wait was completed successfully, error code otherwise:
+ * - EPERM - the mutex type is ErrorChecking or Recursive, and the current thread does not own the mutex;
+ */
+
+ int wait(Mutex& mutex);
+
+ /**
+ * \brief Waits for predicate to become true.
+ *
+ * Similar to std::condition_variable::wait() - http://en.cppreference.com/w/cpp/thread/condition_variable/wait
+ * Similar to pthread_cond_wait() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_wait.html
+ *
+ * Overload for wait() which also checks the predicate. This function will return only if the predicate is true.
+ *
+ * \tparam Predicate is a type of functor to check the predicate
+ *
+ * \param [in] mutex is a reference to mutex which must be owned by calling thread
+ * \param [in] predicate is the predicate that will be checked
+ *
+ * \return zero if the wait was completed successfully, error code otherwise:
+ * - EPERM - the mutex type is ErrorChecking or Recursive, and the current thread does not own the mutex;
+ */
+
+ template<typename Predicate>
+ int wait(Mutex& mutex, Predicate predicate);
+
+ /**
+ * \brief Waits for notification for given duration of time.
+ *
+ * Similar to std::condition_variable::wait_for() -
+ * http://en.cppreference.com/w/cpp/thread/condition_variable/wait_for
+ * Similar to pthread_cond_timedwait() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html#
+ *
+ * Atomically releases supplied mutex and blocks current thread until the condition variable is notified. The thread
+ * will be unblocked when notifyAll() or notifyOne() is executed or when given duration of time expires. It may also
+ * be unblocked spuriously. When unblocked, regardless of the reason, lock is reacquired and wait exits.
+ *
+ * \param [in] mutex is a reference to mutex which must be owned by calling thread
+ * \param [in] duration is the duration after which the wait for notification will be terminated
+ *
+ * \return zero if the wait was completed successfully, error code otherwise:
+ * - EPERM - the mutex type is ErrorChecking or Recursive, and the current thread does not own the mutex;
+ * - ETIMEDOUT - no notification was received before the specified timeout expired;
+ */
+
+ int waitFor(Mutex& mutex, TickClock::duration duration);
+
+ /**
+ * \brief Waits for notification for given duration of time.
+ *
+ * Similar to std::condition_variable::wait_for() -
+ * http://en.cppreference.com/w/cpp/thread/condition_variable/wait_for
+ * Similar to pthread_cond_timedwait() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html#
+ *
+ * Template variant of waitFor(Mutex& mutex, TickClock::duration duration).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] mutex is a reference to mutex which must be owned by calling thread
+ * \param [in] duration is the duration after which the wait for notification will be terminated
+ *
+ * \return zero if the wait was completed successfully, error code otherwise:
+ * - EPERM - the mutex type is ErrorChecking or Recursive, and the current thread does not own the mutex;
+ * - ETIMEDOUT - no notification was received before the specified timeout expired;
+ */
+
+ template<typename Rep, typename Period>
+ int waitFor(Mutex& mutex, const std::chrono::duration<Rep, Period> duration)
+ {
+ return waitFor(mutex, std::chrono::duration_cast<TickClock::duration>(duration));
+ }
+
+ /**
+ * \brief Waits for predicate to become true for given duration of time.
+ *
+ * Similar to std::condition_variable::wait_for() -
+ * http://en.cppreference.com/w/cpp/thread/condition_variable/wait_for
+ * Similar to pthread_cond_timedwait() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html#
+ *
+ * Overload for waitFor() which also checks the predicate. This function will return only if the predicate is true
+ * or when given duration of time expires.
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ * \tparam Predicate is a type of functor to check the predicate
+ *
+ * \param [in] mutex is a reference to mutex which must be owned by calling thread
+ * \param [in] duration is the duration after which the wait for notification will be terminated
+ * \param [in] predicate is the predicate that will be checked
+ *
+ * \return zero if the wait was completed successfully, error code otherwise:
+ * - EPERM - the mutex type is ErrorChecking or Recursive, and the current thread does not own the mutex;
+ * - ETIMEDOUT - no notification was received before the specified timeout expired;
+ */
+
+ template<typename Rep, typename Period, typename Predicate>
+ int waitFor(Mutex& mutex, const std::chrono::duration<Rep, Period> duration, Predicate predicate)
+ {
+ return waitUntil(mutex, TickClock::now() + duration + TickClock::duration{1}, std::move(predicate));
+ }
+
+ /**
+ * \brief Waits for notification until given time point.
+ *
+ * Similar to std::condition_variable::wait_until() -
+ * http://en.cppreference.com/w/cpp/thread/condition_variable/wait_until
+ * Similar to pthread_cond_timedwait() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html#
+ *
+ * Atomically releases supplied mutex and blocks current thread until the condition variable is notified. The thread
+ * will be unblocked when notifyAll() or notifyOne() is executed or when given time point is reached. It may also be
+ * unblocked spuriously. When unblocked, regardless of the reason, lock is reacquired and wait exits.
+ *
+ * \param [in] mutex is a reference to mutex which must be owned by calling thread
+ * \param [in] timePoint is the time point at which the wait for notification will be terminated
+ *
+ * \return zero if the wait was completed successfully, error code otherwise:
+ * - EPERM - the mutex type is ErrorChecking or Recursive, and the current thread does not own the mutex;
+ * - ETIMEDOUT - no notification was received before the specified timeout expired;
+ */
+
+ int waitUntil(Mutex& mutex, TickClock::time_point timePoint);
+
+ /**
+ * \brief Waits for notification until given time point.
+ *
+ * Similar to std::condition_variable::wait_until() -
+ * http://en.cppreference.com/w/cpp/thread/condition_variable/wait_until
+ * Similar to pthread_cond_timedwait() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html#
+ *
+ * Template variant of waitUntil(Mutex& mutex, TickClock::time_point timePoint).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] mutex is a reference to mutex which must be owned by calling thread
+ * \param [in] timePoint is the time point at which the wait for notification will be terminated
+ *
+ * \return zero if the wait was completed successfully, error code otherwise:
+ * - EPERM - the mutex type is ErrorChecking or Recursive, and the current thread does not own the mutex;
+ * - ETIMEDOUT - no notification was received before the specified timeout expired;
+ */
+
+ template<typename Duration>
+ int waitUntil(Mutex& mutex, const std::chrono::time_point<TickClock, Duration> timePoint)
+ {
+ return waitUntil(mutex, std::chrono::time_point_cast<TickClock::duration>(timePoint));
+ }
+
+ /**
+ * \brief Waits for predicate to become true until given time point.
+ *
+ * Similar to std::condition_variable::wait_until() -
+ * http://en.cppreference.com/w/cpp/thread/condition_variable/wait_until
+ * Similar to pthread_cond_timedwait() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html#
+ *
+ * Overload for waitUntil() which also checks the predicate. This function will return only if the predicate is true
+ * or when given time point is reached.
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ * \tparam Predicate is a type of functor to check the predicate
+ *
+ * \param [in] mutex is a reference to mutex which must be owned by calling thread
+ * \param [in] timePoint is the time point at which the wait for notification will be terminated
+ * \param [in] predicate is the predicate that will be checked
+ *
+ * \return zero if the wait was completed successfully, error code otherwise:
+ * - EPERM - the mutex type is ErrorChecking or Recursive, and the current thread does not own the mutex;
+ * - ETIMEDOUT - no notification was received before the specified timeout expired;
+ */
+
+ template<typename Duration, typename Predicate>
+ int waitUntil(Mutex& mutex, std::chrono::time_point<TickClock, Duration> timePoint, Predicate predicate);
+
+private:
+
+ /// ThreadControlBlock objects blocked on this condition variable
+ internal::ThreadList blockedList_;
+};
+
+template<typename Predicate>
+int ConditionVariable::wait(Mutex& mutex, Predicate predicate)
+{
+ while (predicate() == false)
+ {
+ const auto ret = wait(mutex);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+template<typename Duration, typename Predicate>
+int ConditionVariable::waitUntil(Mutex& mutex, const std::chrono::time_point<TickClock, Duration> timePoint, Predicate predicate)
+{
+ while (predicate() == false)
+ {
+ const auto ret = waitUntil(mutex, timePoint);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_CONDITIONVARIABLE_HPP_
diff --git a/include/distortos/DynamicFifoQueue.hpp b/include/distortos/DynamicFifoQueue.hpp
new file mode 100644
index 0000000..fba876f
--- /dev/null
+++ b/include/distortos/DynamicFifoQueue.hpp
@@ -0,0 +1,56 @@
+/**
+ * \file
+ * \brief DynamicFifoQueue 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_DYNAMICFIFOQUEUE_HPP_
+#define INCLUDE_DISTORTOS_DYNAMICFIFOQUEUE_HPP_
+
+#include "FifoQueue.hpp"
+
+#include "distortos/internal/memory/storageDeleter.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief DynamicFifoQueue class is a variant of FifoQueue that has dynamic storage for queue's contents.
+ *
+ * \tparam T is the type of data in queue
+ *
+ * \ingroup queues
+ */
+
+template<typename T>
+class DynamicFifoQueue : public FifoQueue<T>
+{
+public:
+
+ /// import Storage type from base class
+ using typename FifoQueue<T>::Storage;
+
+ /**
+ * \brief DynamicFifoQueue's constructor
+ *
+ * \param [in] queueSize is the maximum number of elements in queue
+ */
+
+ explicit DynamicFifoQueue(size_t queueSize);
+};
+
+template<typename T>
+DynamicFifoQueue<T>::DynamicFifoQueue(const size_t queueSize) :
+ FifoQueue<T>{{new Storage[queueSize], internal::storageDeleter<Storage>}, queueSize}
+{
+
+}
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_DYNAMICFIFOQUEUE_HPP_
diff --git a/include/distortos/DynamicMessageQueue.hpp b/include/distortos/DynamicMessageQueue.hpp
new file mode 100644
index 0000000..b298351
--- /dev/null
+++ b/include/distortos/DynamicMessageQueue.hpp
@@ -0,0 +1,60 @@
+/**
+ * \file
+ * \brief DynamicMessageQueue 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_DYNAMICMESSAGEQUEUE_HPP_
+#define INCLUDE_DISTORTOS_DYNAMICMESSAGEQUEUE_HPP_
+
+#include "MessageQueue.hpp"
+
+#include "distortos/internal/memory/storageDeleter.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief DynamicMessageQueue class is a variant of MessageQueue that has dynamic storage for queue's contents.
+ *
+ * \tparam T is the type of data in queue
+ *
+ * \ingroup queues
+ */
+
+template<typename T>
+class DynamicMessageQueue : public MessageQueue<T>
+{
+public:
+
+ /// import EntryStorage type from base class
+ using typename MessageQueue<T>::EntryStorage;
+
+ /// import ValueStorage type from base class
+ using typename MessageQueue<T>::ValueStorage;
+
+ /**
+ * \brief DynamicMessageQueue's constructor
+ *
+ * \param [in] queueSize is the maximum number of elements in queue
+ */
+
+ explicit DynamicMessageQueue(size_t queueSize);
+};
+
+template<typename T>
+DynamicMessageQueue<T>::DynamicMessageQueue(const size_t queueSize) :
+ MessageQueue<T>{{new EntryStorage[queueSize], internal::storageDeleter<EntryStorage>},
+ {new ValueStorage[queueSize], internal::storageDeleter<ValueStorage>}, queueSize}
+{
+
+}
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_DYNAMICMESSAGEQUEUE_HPP_
diff --git a/include/distortos/DynamicRawFifoQueue.hpp b/include/distortos/DynamicRawFifoQueue.hpp
new file mode 100644
index 0000000..afd2f0b
--- /dev/null
+++ b/include/distortos/DynamicRawFifoQueue.hpp
@@ -0,0 +1,42 @@
+/**
+ * \file
+ * \brief DynamicRawFifoQueue 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_DYNAMICRAWFIFOQUEUE_HPP_
+#define INCLUDE_DISTORTOS_DYNAMICRAWFIFOQUEUE_HPP_
+
+#include "RawFifoQueue.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief DynamicRawFifoQueue class is a variant of RawFifoQueue that has dynamic storage for queue's contents.
+ *
+ * \ingroup queues
+ */
+
+class DynamicRawFifoQueue : public RawFifoQueue
+{
+public:
+
+ /**
+ * \brief DynamicRawFifoQueue's constructor
+ *
+ * \param [in] elementSize is the size of single queue element, bytes
+ * \param [in] queueSize is the maximum number of elements in queue
+ */
+
+ DynamicRawFifoQueue(size_t elementSize, size_t queueSize);
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_DYNAMICRAWFIFOQUEUE_HPP_
diff --git a/include/distortos/DynamicRawMessageQueue.hpp b/include/distortos/DynamicRawMessageQueue.hpp
new file mode 100644
index 0000000..ab68807
--- /dev/null
+++ b/include/distortos/DynamicRawMessageQueue.hpp
@@ -0,0 +1,42 @@
+/**
+ * \file
+ * \brief DynamicRawMessageQueue 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_DYNAMICRAWMESSAGEQUEUE_HPP_
+#define INCLUDE_DISTORTOS_DYNAMICRAWMESSAGEQUEUE_HPP_
+
+#include "distortos/RawMessageQueue.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief DynamicRawMessageQueue class is a variant of RawMessageQueue that has dynamic storage for queue's contents.
+ *
+ * \ingroup queues
+ */
+
+class DynamicRawMessageQueue : public RawMessageQueue
+{
+public:
+
+ /**
+ * \brief DynamicRawMessageQueue's constructor
+ *
+ * \param [in] elementSize is the size of single queue element, bytes
+ * \param [in] queueSize is the maximum number of elements in queue
+ */
+
+ DynamicRawMessageQueue(size_t elementSize, size_t queueSize);
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_DYNAMICRAWMESSAGEQUEUE_HPP_
diff --git a/include/distortos/DynamicSignalsReceiver.hpp b/include/distortos/DynamicSignalsReceiver.hpp
new file mode 100644
index 0000000..386a612
--- /dev/null
+++ b/include/distortos/DynamicSignalsReceiver.hpp
@@ -0,0 +1,52 @@
+/**
+ * \file
+ * \brief DynamicSignalsReceiver 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_DYNAMICSIGNALSRECEIVER_HPP_
+#define INCLUDE_DISTORTOS_DYNAMICSIGNALSRECEIVER_HPP_
+
+#include "distortos/SignalInformationQueueWrapper.hpp"
+#include "distortos/SignalsCatcher.hpp"
+#include "distortos/SignalsReceiver.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief DynamicSignalsReceiver class is a templated interface for SignalsReceiver that has dynamic storage for queued
+ * signals and SignalAction associations required for catching signals.
+ */
+
+class DynamicSignalsReceiver : public SignalsReceiver
+{
+public:
+
+ /**
+ * \brief DynamicSignalsReceiver's constructor
+ *
+ * \param [in] queuedSignals is the max number of queued signals, 0 to disable queuing of signals for this receiver
+ * \param [in] signalActions is the max number of different SignalAction objects, 0 to disable catching of signals
+ * for this receiver
+ */
+
+ DynamicSignalsReceiver(size_t queuedSignals, size_t signalActions);
+
+private:
+
+ /// internal SignalInformationQueueWrapper object
+ SignalInformationQueueWrapper signalInformationQueueWrapper_;
+
+ /// internal SignalsCatcher object
+ SignalsCatcher signalsCatcher_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_DYNAMICSIGNALSRECEIVER_HPP_
diff --git a/include/distortos/DynamicThread.hpp b/include/distortos/DynamicThread.hpp
new file mode 100644
index 0000000..4d7550a
--- /dev/null
+++ b/include/distortos/DynamicThread.hpp
@@ -0,0 +1,373 @@
+/**
+ * \file
+ * \brief DynamicThread 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_DYNAMICTHREAD_HPP_
+#define INCLUDE_DISTORTOS_DYNAMICTHREAD_HPP_
+
+#include "distortos/internal/scheduler/DynamicThreadBase.hpp"
+
+namespace distortos
+{
+
+/// \addtogroup threads
+/// \{
+
+/**
+ * \brief DynamicThread class is a type-erased interface for thread that has dynamic storage for bounded function, stack
+ * and internal DynamicSignalsReceiver object.
+ */
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+class DynamicThread : public Thread
+{
+public:
+
+ /**
+ * \brief DynamicThread'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>
+ DynamicThread(size_t stackSize, bool canReceiveSignals, size_t queuedSignals, size_t signalActions,
+ uint8_t priority, SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args);
+
+ /**
+ * \brief DynamicThread'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>
+ DynamicThread(const DynamicThreadParameters parameters, Function&& function, Args&&... args) :
+ DynamicThread{parameters.stackSize, parameters.canReceiveSignals, parameters.queuedSignals,
+ parameters.signalActions, parameters.priority, parameters.schedulingPolicy,
+ std::forward<Function>(function), std::forward<Args>(args)...}
+ {
+
+ }
+
+ /**
+ * \brief DynamicThread's destructor
+ */
+
+ ~DynamicThread() override;
+
+ /**
+ * \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;
+
+ /**
+ * \brief Generates signal for thread.
+ *
+ * Similar to pthread_kill() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html
+ *
+ * Adds the signalNumber to set of pending signals. If this thread is currently waiting for this signal, it will be
+ * unblocked.
+ *
+ * \param [in] signalNumber is the signal that will be generated, [0; 31]
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - reception of signals is disabled for this thread;
+ * - EINVAL - internal thread object was detached;
+ *
+ * \ingroup signals
+ */
+
+ int generateSignal(uint8_t signalNumber) override;
+
+ /**
+ * \return effective priority of thread
+ */
+
+ uint8_t getEffectivePriority() const override;
+
+ /**
+ * \brief Gets set of currently pending signals.
+ *
+ * Similar to sigpending() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpending.html
+ *
+ * This function shall return the set of signals that are blocked from delivery and are pending on the thread.
+ *
+ * \return set of currently pending signals
+ *
+ * \ingroup signals
+ */
+
+ SignalSet getPendingSignalSet() const override;
+
+ /**
+ * \return priority of thread
+ */
+
+ uint8_t getPriority() const override;
+
+ /**
+ * \return scheduling policy of the thread
+ */
+
+ SchedulingPolicy getSchedulingPolicy() const override;
+
+ /**
+ * \return current state of thread
+ */
+
+ ThreadState getState() const override;
+
+ /**
+ * \brief Waits for thread termination.
+ *
+ * Similar to std::thread::join() - http://en.cppreference.com/w/cpp/thread/thread/join
+ * Similar to POSIX pthread_join() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html
+ *
+ * Blocks current thread until this thread finishes its execution. The results of multiple simultaneous calls to
+ * join() on the same target thread are undefined.
+ *
+ * \return 0 on success, error code otherwise:
+ * - EDEADLK - deadlock condition was detected,
+ * - EINVAL - this thread is not joinable,
+ * - EINVAL - internal thread object was detached;
+ * - ...
+ *
+ * \ingroup synchronization
+ */
+
+ int join() override;
+
+ /**
+ * \brief Queues signal for thread.
+ *
+ * Similar to sigqueue() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigqueue.html
+ *
+ * Adds the signalNumber and signal value (sigval union) to queue of SignalInformation objects. If this thread is
+ * currently waiting for this signal, it will be unblocked.
+ *
+ * \param [in] signalNumber is the signal that will be queued, [0; 31]
+ * \param [in] value is the signal value
+ *
+ * \return 0 on success, error code otherwise:
+ * - EAGAIN - no resources are available to queue the signal, maximal number of signals is already queued in
+ * associated queue of SignalInformation objects;
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - reception or queuing of signals are disabled for this thread;
+ * - EINVAL - internal thread object was detached;
+ *
+ * \ingroup signals
+ */
+
+ int queueSignal(uint8_t signalNumber, sigval value) override;
+
+ /**
+ * \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 = {}) override;
+
+ /**
+ * param [in] schedulingPolicy is the new scheduling policy of the thread
+ */
+
+ void setSchedulingPolicy(SchedulingPolicy schedulingPolicy) override;
+
+ /**
+ * \brief Starts the thread.
+ *
+ * This operation can be performed on threads in "New" state only.
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - thread is already started;
+ * - EINVAL - internal thread object was detached;
+ * - error codes returned by scheduler::Scheduler::add();
+ */
+
+ int start() override;
+
+ DynamicThread(const DynamicThread&) = delete;
+ DynamicThread(DynamicThread&&) = default;
+ const DynamicThread& operator=(const DynamicThread&) = delete;
+ DynamicThread& operator=(DynamicThread&&) = delete;
+
+private:
+
+ /// internal thread object
+ std::unique_ptr<internal::DynamicThreadBase> detachableThread_;
+};
+
+#else // !def CONFIG_THREAD_DETACH_ENABLE
+
+class DynamicThread : public internal::DynamicThreadBase
+{
+public:
+
+ using internal::DynamicThreadBase::DynamicThreadBase;
+};
+
+#endif // !def CONFIG_THREAD_DETACH_ENABLE
+
+/**
+ * \brief Helper factory function to make DynamicThread object
+ *
+ * \tparam Function is the function that will be executed
+ * \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
+ *
+ * \return DynamicThread object
+ */
+
+template<typename Function, typename... Args>
+DynamicThread makeDynamicThread(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)
+{
+ return {stackSize, canReceiveSignals, queuedSignals, signalActions, priority, schedulingPolicy,
+ std::forward<Function>(function), std::forward<Args>(args)...};
+}
+
+/**
+ * \brief Helper factory function to make DynamicThread object
+ *
+ * \tparam Function is the function that will be executed
+ * \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
+ *
+ * \return DynamicThread object
+ */
+
+template<typename Function, typename... Args>
+DynamicThread makeDynamicThread(const DynamicThreadParameters parameters, Function&& function, Args&&... args)
+{
+ return {parameters, std::forward<Function>(function), std::forward<Args>(args)...};
+}
+
+/**
+ * \brief Helper factory function to make and start DynamicThread object
+ *
+ * \tparam Function is the function that will be executed
+ * \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
+ *
+ * \return DynamicThread object
+ */
+
+template<typename Function, typename... Args>
+DynamicThread makeAndStartDynamicThread(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)
+{
+ auto thread = makeDynamicThread(stackSize, canReceiveSignals, queuedSignals, signalActions, priority,
+ schedulingPolicy, std::forward<Function>(function), std::forward<Args>(args)...);
+ thread.start(); /// \todo make sure this never fails
+ return thread;
+}
+
+/**
+ * \brief Helper factory function to make and start DynamicThread object
+ *
+ * \tparam Function is the function that will be executed
+ * \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
+ *
+ * \return DynamicThread object
+ */
+
+template<typename Function, typename... Args>
+DynamicThread makeAndStartDynamicThread(const DynamicThreadParameters parameters, Function&& function, Args&&... args)
+{
+ auto thread = makeDynamicThread(parameters, std::forward<Function>(function), std::forward<Args>(args)...);
+ thread.start(); /// \todo make sure this never fails
+ return thread;
+}
+
+/// \}
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+template<typename Function, typename... Args>
+DynamicThread::DynamicThread(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) :
+ detachableThread_{new internal::DynamicThreadBase{stackSize, canReceiveSignals, queuedSignals, signalActions,
+ priority, schedulingPolicy, *this, std::forward<Function>(function), std::forward<Args>(args)...}}
+{
+
+}
+
+#endif // def CONFIG_THREAD_DETACH_ENABLE
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_DYNAMICTHREAD_HPP_
diff --git a/include/distortos/DynamicThreadParameters.hpp b/include/distortos/DynamicThreadParameters.hpp
new file mode 100644
index 0000000..b27056c
--- /dev/null
+++ b/include/distortos/DynamicThreadParameters.hpp
@@ -0,0 +1,99 @@
+/**
+ * \file
+ * \brief DynamicThreadParameters 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_DYNAMICTHREADPARAMETERS_HPP_
+#define INCLUDE_DISTORTOS_DYNAMICTHREADPARAMETERS_HPP_
+
+#include "distortos/SchedulingPolicy.hpp"
+
+#include <cstddef>
+
+namespace distortos
+{
+
+/**
+ * \brief DynamicThreadParameters struct is a helper with parameters for DynamicThread's constructor
+ *
+ * This struct is a replacement for overloads of DynamicThread's constructor, makeDynamicThread() and
+ * makeAndStartDynamicThread() which - unfortunately - cannot be used, as they would lead to compilation errors due to
+ * ambiguity.
+ *
+ * \ingroup threads
+ */
+
+struct DynamicThreadParameters
+{
+ /**
+ * \brief DynamicThreadParameters's constructor
+ *
+ * \param [in] stackSizee is the size of stack, bytes
+ * \param [in] canReceiveSignalss selects whether reception of signals is enabled (true) or disabled (false) for
+ * this thread
+ * \param [in] queuedSignalss 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] signalActionss 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] priorityy is the thread's priority, 0 - lowest, UINT8_MAX - highest
+ * \param [in] schedulingPolicyy is the scheduling policy of the thread, default - SchedulingPolicy::roundRobin
+ */
+
+ constexpr DynamicThreadParameters(const size_t stackSizee, const bool canReceiveSignalss,
+ const size_t queuedSignalss, const size_t signalActionss, const uint8_t priorityy,
+ const SchedulingPolicy schedulingPolicyy = SchedulingPolicy::roundRobin) :
+ queuedSignals{queuedSignalss},
+ signalActions{signalActionss},
+ stackSize{stackSizee},
+ canReceiveSignals{canReceiveSignalss},
+ priority{priorityy},
+ schedulingPolicy{schedulingPolicyy}
+ {
+
+ }
+
+ /**
+ * \brief DynamicThreadParameters's constructor
+ *
+ * \param [in] stackSizee is the size of stack, bytes
+ * \param [in] priorityy is the thread's priority, 0 - lowest, UINT8_MAX - highest
+ * \param [in] schedulingPolicyy is the scheduling policy of the thread, default - SchedulingPolicy::roundRobin
+ */
+
+ constexpr DynamicThreadParameters(const size_t stackSizee, const uint8_t priorityy,
+ const SchedulingPolicy schedulingPolicyy = SchedulingPolicy::roundRobin) :
+ DynamicThreadParameters{stackSizee, false, 0, 0, priorityy, schedulingPolicyy}
+ {
+
+ }
+
+ /// max number of queued signals for this thread, relevant only if \a canReceiveSignals == true, 0 to disable
+ /// queuing of signals for this thread
+ size_t queuedSignals;
+
+ /// max number of different SignalAction objects for this thread, relevant only if \a canReceiveSignals == true, 0
+ /// to disable catching of signals for this thread
+ size_t signalActions;
+
+ /// size of stack, bytes
+ size_t stackSize;
+
+ /// selects whether reception of signals is enabled (true) or disabled (false) for this thread
+ bool canReceiveSignals;
+
+ /// thread's priority, 0 - lowest, UINT8_MAX - highest
+ uint8_t priority;
+
+ /// scheduling policy of the thread
+ SchedulingPolicy schedulingPolicy;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_DYNAMICTHREADPARAMETERS_HPP_
diff --git a/include/distortos/FifoQueue.hpp b/include/distortos/FifoQueue.hpp
new file mode 100644
index 0000000..9f6c952
--- /dev/null
+++ b/include/distortos/FifoQueue.hpp
@@ -0,0 +1,682 @@
+/**
+ * \file
+ * \brief FifoQueue 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_FIFOQUEUE_HPP_
+#define INCLUDE_DISTORTOS_FIFOQUEUE_HPP_
+
+#include "distortos/internal/synchronization/FifoQueueBase.hpp"
+#include "distortos/internal/synchronization/BoundQueueFunctor.hpp"
+#include "distortos/internal/synchronization/CopyConstructQueueFunctor.hpp"
+#include "distortos/internal/synchronization/MoveConstructQueueFunctor.hpp"
+#include "distortos/internal/synchronization/SwapPopQueueFunctor.hpp"
+#include "distortos/internal/synchronization/SemaphoreWaitFunctor.hpp"
+#include "distortos/internal/synchronization/SemaphoreTryWaitFunctor.hpp"
+#include "distortos/internal/synchronization/SemaphoreTryWaitForFunctor.hpp"
+#include "distortos/internal/synchronization/SemaphoreTryWaitUntilFunctor.hpp"
+
+/// GCC 4.9 is needed for all FifoQueue::*emplace*() functions - earlier versions don't support parameter pack expansion
+/// in lambdas
+#define DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED __GNUC_PREREQ(4, 9)
+
+namespace distortos
+{
+
+/**
+ * \brief FifoQueue class is a simple FIFO queue for thread-thread, thread-interrupt or interrupt-interrupt
+ * communication. It supports multiple readers and multiple writers. It is implemented as a wrapper for
+ * internal::FifoQueueBase.
+ *
+ * \tparam T is the type of data in queue
+ *
+ * \ingroup queues
+ */
+
+template<typename T>
+class FifoQueue
+{
+public:
+
+ /// type of uninitialized storage for data
+ using Storage = typename std::aligned_storage<sizeof(T), alignof(T)>::type;
+
+ /// unique_ptr (with deleter) to Storage[]
+ using StorageUniquePointer =
+ std::unique_ptr<Storage[], internal::FifoQueueBase::StorageUniquePointer::deleter_type>;
+
+ /**
+ * \brief FifoQueue's constructor
+ *
+ * \param [in] storageUniquePointer is a rvalue reference to StorageUniquePointer with storage for queue elements
+ * (sufficiently large for \a maxElements, each sizeof(T) bytes long) and appropriate deleter
+ * \param [in] maxElements is the number of elements in storage array
+ */
+
+ FifoQueue(StorageUniquePointer&& storageUniquePointer, const size_t maxElements) :
+ fifoQueueBase_{{storageUniquePointer.release(), storageUniquePointer.get_deleter()}, sizeof(T), maxElements}
+ {
+
+ }
+
+ /**
+ * \brief FifoQueue's destructor
+ *
+ * Pops all remaining elements from the queue.
+ */
+
+ ~FifoQueue();
+
+#if DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Emplaces the element in the queue.
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename... Args>
+ int emplace(Args&&... args)
+ {
+ const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
+ return emplaceInternal(semaphoreWaitFunctor, std::forward<Args>(args)...);
+ }
+
+#endif // DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Pops the oldest (first) element from the queue.
+ *
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pop(T& value)
+ {
+ const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
+ return popInternal(semaphoreWaitFunctor, value);
+ }
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int push(const T& value)
+ {
+ const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
+ return pushInternal(semaphoreWaitFunctor, value);
+ }
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int push(T&& value)
+ {
+ const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
+ return pushInternal(semaphoreWaitFunctor, std::move(value));
+ }
+
+#if DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Tries to emplace the element in the queue.
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename... Args>
+ int tryEmplace(Args&&... args)
+ {
+ const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
+ return emplaceInternal(semaphoreTryWaitFunctor, std::forward<Args>(args)...);
+ }
+
+ /**
+ * \brief Tries to emplace the element in the queue for a given duration of time.
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without emplacing the element
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename... Args>
+ int tryEmplaceFor(const TickClock::duration duration, Args&&... args)
+ {
+ const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
+ return emplaceInternal(semaphoreTryWaitForFunctor, std::forward<Args>(args)...);
+ }
+
+ /**
+ * \brief Tries to emplace the element in the queue for a given duration of time.
+ *
+ * Template variant of FifoQueue::tryEmplaceFor(TickClock::duration, Args&&...).
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without emplacing the element
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period, typename... Args>
+ int tryEmplaceFor(const std::chrono::duration<Rep, Period> duration, Args&&... args)
+ {
+ return tryEmplaceFor(std::chrono::duration_cast<TickClock::duration>(duration), std::forward<Args>(args)...);
+ }
+
+ /**
+ * \brief Tries to emplace the element in the queue until a given time point.
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without emplacing the element
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename... Args>
+ int tryEmplaceUntil(const TickClock::time_point timePoint, Args&&... args)
+ {
+ const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
+ return emplaceInternal(semaphoreTryWaitUntilFunctor, std::forward<Args>(args)...);
+ }
+
+ /**
+ * \brief Tries to emplace the element in the queue until a given time point.
+ *
+ * Template variant of FifoQueue::tryEmplaceUntil(TickClock::time_point, Args&&...).
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without emplacing the element
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration, typename... Args>
+ int tryEmplaceUntil(const std::chrono::time_point<TickClock, Duration> timePoint, Args&&... args)
+ {
+ return tryEmplaceUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint),
+ std::forward<Args>(args)...);
+ }
+
+#endif // DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue.
+ *
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPop(T& value)
+ {
+ internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
+ return popInternal(semaphoreTryWaitFunctor, value);
+ }
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue for a given duration of time.
+ *
+ * \param [in] duration is the duration after which the call will be terminated without popping the element
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPopFor(const TickClock::duration duration, T& value)
+ {
+ const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
+ return popInternal(semaphoreTryWaitForFunctor, value);
+ }
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue for a given duration of time.
+ *
+ * Template variant of tryPopFor(TickClock::duration, T&).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the call will be terminated without popping the element
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period>
+ int tryPopFor(const std::chrono::duration<Rep, Period> duration, T& value)
+ {
+ return tryPopFor(std::chrono::duration_cast<TickClock::duration>(duration), value);
+ }
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue until a given time point.
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without popping the element
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPopUntil(const TickClock::time_point timePoint, T& value)
+ {
+ const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
+ return popInternal(semaphoreTryWaitUntilFunctor, value);
+ }
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue until a given time point.
+ *
+ * Template variant of tryPopUntil(TickClock::time_point, T&).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without popping the element
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration>
+ int tryPopUntil(const std::chrono::time_point<TickClock, Duration> timePoint, T& value)
+ {
+ return tryPopUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue.
+ *
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPush(const T& value)
+ {
+ const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
+ return pushInternal(semaphoreTryWaitFunctor, value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue.
+ *
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPush(T&& value)
+ {
+ const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
+ return pushInternal(semaphoreTryWaitFunctor, std::move(value));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without pushing the element
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushFor(const TickClock::duration duration, const T& value)
+ {
+ const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
+ return pushInternal(semaphoreTryWaitForFunctor, value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * Template variant of tryPushFor(TickClock::duration, const T&).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without pushing the element
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period>
+ int tryPushFor(const std::chrono::duration<Rep, Period> duration, const T& value)
+ {
+ return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * \param [in] duration is the duration after which the call will be terminated without pushing the element
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushFor(const TickClock::duration duration, T&& value)
+ {
+ const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
+ return pushInternal(semaphoreTryWaitForFunctor, std::move(value));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * Template variant of tryPushFor(TickClock::duration, T&&).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the call will be terminated without pushing the element
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period>
+ int tryPushFor(const std::chrono::duration<Rep, Period> duration, T&& value)
+ {
+ return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), std::move(value));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushUntil(const TickClock::time_point timePoint, const T& value)
+ {
+ const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
+ return pushInternal(semaphoreTryWaitUntilFunctor, value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * Template variant of tryPushUntil(TickClock::time_point, const T&).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration>
+ int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const T& value)
+ {
+ return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushUntil(const TickClock::time_point timePoint, T&& value)
+ {
+ const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
+ return pushInternal(semaphoreTryWaitUntilFunctor, std::move(value));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * Template variant of tryPushUntil(TickClock::time_point, T&&).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration>
+ int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, T&& value)
+ {
+ return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), std::move(value));
+ }
+
+private:
+
+#if DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Emplaces the element in the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename... Args>
+ int emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, Args&&... args);
+
+#endif // DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Pops the oldest (first) element from the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a popSemaphore_
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T& value);
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const T& value);
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T&& value);
+
+ /// contained internal::FifoQueueBase object which implements whole functionality
+ internal::FifoQueueBase fifoQueueBase_;
+};
+
+template<typename T>
+FifoQueue<T>::~FifoQueue()
+{
+ T value;
+ while (tryPop(value) == 0);
+}
+
+#if DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+template<typename T>
+template<typename... Args>
+int FifoQueue<T>::emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, Args&&... args)
+{
+ const auto emplaceFunctor = internal::makeBoundQueueFunctor(
+ [&args...](void* const storage)
+ {
+ new (storage) T{std::forward<Args>(args)...};
+ });
+ return fifoQueueBase_.push(waitSemaphoreFunctor, emplaceFunctor);
+}
+
+#endif // DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+template<typename T>
+int FifoQueue<T>::popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T& value)
+{
+ const internal::SwapPopQueueFunctor<T> swapPopQueueFunctor {value};
+ return fifoQueueBase_.pop(waitSemaphoreFunctor, swapPopQueueFunctor);
+}
+
+template<typename T>
+int FifoQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const T& value)
+{
+ const internal::CopyConstructQueueFunctor<T> copyConstructQueueFunctor {value};
+ return fifoQueueBase_.push(waitSemaphoreFunctor, copyConstructQueueFunctor);
+}
+
+template<typename T>
+int FifoQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T&& value)
+{
+ const internal::MoveConstructQueueFunctor<T> moveConstructQueueFunctor {std::move(value)};
+ return fifoQueueBase_.push(waitSemaphoreFunctor, moveConstructQueueFunctor);
+}
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_FIFOQUEUE_HPP_
diff --git a/include/distortos/MessageQueue.hpp b/include/distortos/MessageQueue.hpp
new file mode 100644
index 0000000..0f44d8f
--- /dev/null
+++ b/include/distortos/MessageQueue.hpp
@@ -0,0 +1,762 @@
+/**
+ * \file
+ * \brief MessageQueue 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_MESSAGEQUEUE_HPP_
+#define INCLUDE_DISTORTOS_MESSAGEQUEUE_HPP_
+
+#include "distortos/internal/synchronization/MessageQueueBase.hpp"
+#include "distortos/internal/synchronization/BoundQueueFunctor.hpp"
+#include "distortos/internal/synchronization/CopyConstructQueueFunctor.hpp"
+#include "distortos/internal/synchronization/MoveConstructQueueFunctor.hpp"
+#include "distortos/internal/synchronization/SwapPopQueueFunctor.hpp"
+#include "distortos/internal/synchronization/SemaphoreWaitFunctor.hpp"
+#include "distortos/internal/synchronization/SemaphoreTryWaitFunctor.hpp"
+#include "distortos/internal/synchronization/SemaphoreTryWaitForFunctor.hpp"
+#include "distortos/internal/synchronization/SemaphoreTryWaitUntilFunctor.hpp"
+
+namespace distortos
+{
+
+/// GCC 4.9 is needed for all MessageQueue::*emplace*() functions - earlier versions don't support parameter pack
+/// expansion in lambdas
+#define DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED __GNUC_PREREQ(4, 9)
+
+/**
+ * \brief MessageQueue class is a message queue for thread-thread, thread-interrupt or interrupt-interrupt
+ * communication. It supports multiple readers and multiple writers. It is implemented as a wrapper for
+ * internal::MessageQueueBase.
+ *
+ * Similar to POSIX mqd_t - http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/mqueue.h.html
+ *
+ * \tparam T is the type of data in queue
+ *
+ * \ingroup queues
+ */
+
+template<typename T>
+class MessageQueue
+{
+public:
+
+ /// type of uninitialized storage for Entry with link
+ using EntryStorage = internal::MessageQueueBase::EntryStorage;
+
+ /// type of uninitialized storage for value
+ using ValueStorage = internal::MessageQueueBase::ValueStorage<T>;
+
+ /// import EntryStorageUniquePointer type from internal::MessageQueueBase class
+ using EntryStorageUniquePointer = internal::MessageQueueBase::EntryStorageUniquePointer;
+
+ /// unique_ptr (with deleter) to ValueStorage[]
+ using ValueStorageUniquePointer =
+ std::unique_ptr<ValueStorage[], internal::MessageQueueBase::ValueStorageUniquePointer::deleter_type>;
+
+ /**
+ * \brief MessageQueue's constructor
+ *
+ * \param [in] entryStorageUniquePointer is a rvalue reference to EntryStorageUniquePointer with storage for queue
+ * entries (sufficiently large for \a maxElements EntryStorage objects) and appropriate deleter
+ * \param [in] valueStorageUniquePointer is a rvalue reference to ValueStorageUniquePointer with storage for queue
+ * elements (sufficiently large for \a maxElements, each sizeof(T) bytes long) and appropriate deleter
+ * \param [in] maxElements is the number of elements in \a entryStorage and \a valueStorage arrays
+ */
+
+ MessageQueue(EntryStorageUniquePointer&& entryStorageUniquePointer,
+ ValueStorageUniquePointer&& valueStorageUniquePointer, const size_t maxElements) :
+ messageQueueBase_{std::move(entryStorageUniquePointer),
+ {valueStorageUniquePointer.release(), valueStorageUniquePointer.get_deleter()},
+ sizeof(*valueStorageUniquePointer.get()), maxElements}
+ {
+
+ }
+
+ /**
+ * \brief MessageQueue's destructor
+ *
+ * Pops all remaining elements from the queue.
+ */
+
+ ~MessageQueue();
+
+#if DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Emplaces the element in the queue.
+ *
+ * Similar to mq_send() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] priority is the priority of new element
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename... Args>
+ int emplace(const uint8_t priority, Args&&... args)
+ {
+ const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
+ return emplaceInternal(semaphoreWaitFunctor, priority, std::forward<Args>(args)...);
+ }
+
+#endif // DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Pops oldest element with highest priority from the queue.
+ *
+ * Similar to mq_receive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pop(uint8_t& priority, T& value)
+ {
+ const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
+ return popInternal(semaphoreWaitFunctor, priority, value);
+ }
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * Similar to mq_send() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int push(const uint8_t priority, const T& value)
+ {
+ const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
+ return pushInternal(semaphoreWaitFunctor, priority, value);
+ }
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * Similar to mq_send() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int push(const uint8_t priority, T&& value)
+ {
+ const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
+ return pushInternal(semaphoreWaitFunctor, priority, std::move(value));
+ }
+
+#if DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Tries to emplace the element in the queue.
+ *
+ * Similar to mq_send() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] priority is the priority of new element
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename... Args>
+ int tryEmplace(const uint8_t priority, Args&&... args)
+ {
+ const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
+ return emplaceInternal(semaphoreTryWaitFunctor, priority, std::forward<Args>(args)...);
+ }
+
+ /**
+ * \brief Tries to emplace the element in the queue for a given duration of time.
+ *
+ * Similar to mq_timedsend() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without emplacing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename... Args>
+ int tryEmplaceFor(const TickClock::duration duration, const uint8_t priority, Args&&... args)
+ {
+ const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
+ return emplaceInternal(semaphoreTryWaitForFunctor, priority, std::forward<Args>(args)...);
+ }
+
+ /**
+ * \brief Tries to emplace the element in the queue for a given duration of time.
+ *
+ * Template variant of MessageQueue::tryEmplaceFor(TickClock::duration, uint8_t, Args&&...).
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without emplacing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period, typename... Args>
+ int tryEmplaceFor(const std::chrono::duration<Rep, Period> duration, const uint8_t priority, Args&&... args)
+ {
+ return tryEmplaceFor(std::chrono::duration_cast<TickClock::duration>(duration), priority,
+ std::forward<Args>(args)...);
+ }
+
+ /**
+ * \brief Tries to emplace the element in the queue until a given time point.
+ *
+ * Similar to mq_timedsend() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without emplacing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename... Args>
+ int tryEmplaceUntil(const TickClock::time_point timePoint, const uint8_t priority, Args&&... args)
+ {
+ const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
+ return emplaceInternal(semaphoreTryWaitUntilFunctor, priority, std::forward<Args>(args)...);
+ }
+
+ /**
+ * \brief Tries to emplace the element in the queue until a given time point.
+ *
+ * Template variant of FifoQueue::tryEmplaceUntil(TickClock::time_point, uint8_t, Args&&...).
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without emplacing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration, typename... Args>
+ int tryEmplaceUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const uint8_t priority,
+ Args&&... args)
+ {
+ return tryEmplaceUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority,
+ std::forward<Args>(args)...);
+ }
+
+#endif // DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Tries to pop oldest element with highest priority from the queue.
+ *
+ * Similar to mq_receive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPop(uint8_t& priority, T& value)
+ {
+ const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
+ return popInternal(semaphoreTryWaitFunctor, priority, value);
+ }
+
+ /**
+ * \brief Tries to pop oldest element with highest priority from the queue for a given duration of time.
+ *
+ * Similar to mq_timedreceive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \param [in] duration is the duration after which the call will be terminated without popping the element
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPopFor(const TickClock::duration duration, uint8_t& priority, T& value)
+ {
+ const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
+ return popInternal(semaphoreTryWaitForFunctor, priority, value);
+ }
+
+ /**
+ * \brief Tries to pop oldest element with highest priority from the queue for a given duration of time.
+ *
+ * Template variant of tryPopFor(TickClock::duration, uint8_t&, T&).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the call will be terminated without popping the element
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period>
+ int tryPopFor(const std::chrono::duration<Rep, Period> duration, uint8_t& priority, T& value)
+ {
+ return tryPopFor(std::chrono::duration_cast<TickClock::duration>(duration), priority, value);
+ }
+
+ /**
+ * \brief Tries to pop oldest element with highest priority from the queue until a given time point.
+ *
+ * Similar to mq_timedreceive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without popping the element
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPopUntil(const TickClock::time_point timePoint, uint8_t& priority, T& value)
+ {
+ const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
+ return popInternal(semaphoreTryWaitUntilFunctor, priority, value);
+ }
+
+ /**
+ * \brief Tries to pop oldest element with highest priority from the queue until a given time point.
+ *
+ * Template variant of tryPopUntil(TickClock::time_point, uint8_t&, T&).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without popping the element
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration>
+ int tryPopUntil(const std::chrono::time_point<TickClock, Duration> timePoint, uint8_t& priority, T& value)
+ {
+ return tryPopUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority, value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue.
+ *
+ * Similar to mq_send() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPush(const uint8_t priority, const T& value)
+ {
+ const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
+ return pushInternal(semaphoreTryWaitFunctor, priority, value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue.
+ *
+ * Similar to mq_send() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPush(const uint8_t priority, T&& value)
+ {
+ const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
+ return pushInternal(semaphoreTryWaitFunctor, priority, std::move(value));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * Similar to mq_timedsend() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushFor(const TickClock::duration duration, const uint8_t priority, const T& value)
+ {
+ const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
+ return pushInternal(semaphoreTryWaitForFunctor, priority, value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * Template variant of tryPushFor(TickClock::duration, uint8_t, const T&).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period>
+ int tryPushFor(const std::chrono::duration<Rep, Period> duration, const uint8_t priority, const T& value)
+ {
+ return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), priority, value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * Similar to mq_timedsend() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushFor(const TickClock::duration duration, const uint8_t priority, T&& value)
+ {
+ const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
+ return pushInternal(semaphoreTryWaitForFunctor, priority, std::move(value));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * Template variant of tryPushFor(TickClock::duration, uint8_t, T&&).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the call will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period>
+ int tryPushFor(const std::chrono::duration<Rep, Period> duration, const uint8_t priority, T&& value)
+ {
+ return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), priority, std::move(value));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * Similar to mq_timedsend() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushUntil(const TickClock::time_point timePoint, const uint8_t priority, const T& value)
+ {
+ const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
+ return pushInternal(semaphoreTryWaitUntilFunctor, priority, value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * Template variant of tryPushUntil(TickClock::time_point, uint8_t, const T&).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration>
+ int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const uint8_t priority,
+ const T& value)
+ {
+ return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority, value);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * Similar to mq_timedsend() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushUntil(const TickClock::time_point timePoint, const uint8_t priority, T&& value)
+ {
+ const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
+ return pushInternal(semaphoreTryWaitUntilFunctor, priority, std::move(value));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * Template variant of tryPushUntil(TickClock::time_point, uint8_t, T&&).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration>
+ int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const uint8_t priority, T&& value)
+ {
+ return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority, std::move(value));
+ }
+
+private:
+
+#if DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Emplaces the element in the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Args are types of arguments for constructor of T
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
+ * \param [in] priority is the priority of new element
+ * \param [in] args are arguments for constructor of T
+ *
+ * \return zero if element was emplaced successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename... Args>
+ int emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t priority, Args&&... args);
+
+#endif // DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+ /**
+ * \brief Pops oldest element with highest priority from the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a popSemaphore_
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t& priority, T& value);
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a reference to object that will be pushed, value in queue's storage is copy-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t priority, const T& value);
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
+ * \param [in] priority is the priority of new element
+ * \param [in] value is a rvalue reference to object that will be pushed, value in queue's storage is
+ * move-constructed
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t priority, T&& value);
+
+ /// contained internal::MessageQueueBase object which implements whole functionality
+ internal::MessageQueueBase messageQueueBase_;
+};
+
+template<typename T>
+MessageQueue<T>::~MessageQueue()
+{
+ uint8_t priority;
+ T value;
+ while (tryPop(priority, value) == 0);
+}
+
+#if DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+template<typename T>
+template<typename... Args>
+int MessageQueue<T>::emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const uint8_t priority,
+ Args&&... args)
+{
+ const auto emplaceFunctor = internal::makeBoundQueueFunctor(
+ [&args...](void* const storage)
+ {
+ new (storage) T{std::forward<Args>(args)...};
+ });
+ return messageQueueBase_.push(waitSemaphoreFunctor, priority, emplaceFunctor);
+}
+
+#endif // DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1 || DOXYGEN == 1
+
+template<typename T>
+int MessageQueue<T>::popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t& priority, T& value)
+{
+ const internal::SwapPopQueueFunctor<T> swapPopQueueFunctor {value};
+ return messageQueueBase_.pop(waitSemaphoreFunctor, priority, swapPopQueueFunctor);
+}
+
+template<typename T>
+int MessageQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const uint8_t priority,
+ const T& value)
+{
+ const internal::CopyConstructQueueFunctor<T> copyConstructQueueFunctor {value};
+ return messageQueueBase_.push(waitSemaphoreFunctor, priority, copyConstructQueueFunctor);
+}
+
+template<typename T>
+int MessageQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const uint8_t priority,
+ T&& value)
+{
+ const internal::MoveConstructQueueFunctor<T> moveConstructQueueFunctor {std::move(value)};
+ return messageQueueBase_.push(waitSemaphoreFunctor, priority, moveConstructQueueFunctor);
+}
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_MESSAGEQUEUE_HPP_
diff --git a/include/distortos/Mutex.hpp b/include/distortos/Mutex.hpp
new file mode 100644
index 0000000..481700d
--- /dev/null
+++ b/include/distortos/Mutex.hpp
@@ -0,0 +1,280 @@
+/**
+ * \file
+ * \brief Mutex 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_MUTEX_HPP_
+#define INCLUDE_DISTORTOS_MUTEX_HPP_
+
+#include "distortos/internal/synchronization/MutexControlBlock.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief Mutex is the basic synchronization primitive
+ *
+ * Similar to std::mutex - http://en.cppreference.com/w/cpp/thread/mutex
+ * Similar to POSIX pthread_mutex_t -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09 -> 2.9.3 Thread Mutexes
+ *
+ * \ingroup synchronization
+ */
+
+class Mutex
+{
+public:
+
+ /// mutex protocols
+ using Protocol = internal::MutexControlBlock::Protocol;
+
+ /// type used for counting recursive locks
+ using RecursiveLocksCount = uint16_t;
+
+ /// type of mutex
+ enum class Type : uint8_t
+ {
+ /// normal mutex, similar to PTHREAD_MUTEX_NORMAL
+ normal,
+ /// mutex with additional error checking, similar to PTHREAD_MUTEX_ERRORCHECK
+ errorChecking,
+ /// recursive mutex, similar to PTHREAD_MUTEX_RECURSIVE
+ recursive
+ };
+
+ /**
+ * \brief Gets the maximum number of recursive locks possible before returning EAGAIN
+ *
+ * \note Actual number of lock() operations possible is getMaxRecursiveLocks() + 1.
+ *
+ * \return maximum number of recursive locks possible before returning EAGAIN
+ */
+
+ constexpr static RecursiveLocksCount getMaxRecursiveLocks()
+ {
+ return std::numeric_limits<RecursiveLocksCount>::max();
+ }
+
+ /**
+ * \brief Mutex constructor
+ *
+ * Similar to std::mutex::mutex() - http://en.cppreference.com/w/cpp/thread/mutex/mutex
+ * Similar to pthread_mutex_init() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_init.html
+ *
+ * \param [in] type is the type of mutex, default - Type::normal
+ * \param [in] protocol is the mutex protocol, default - Protocol::none
+ * \param [in] priorityCeiling is the priority ceiling of mutex, ignored when protocol != Protocol::priorityProtect,
+ * default - 0
+ */
+
+ constexpr explicit Mutex(const Type type = Type::normal, const Protocol protocol = Protocol::none,
+ const uint8_t priorityCeiling = {}) :
+ controlBlock_{protocol, priorityCeiling},
+ recursiveLocksCount_{},
+ type_{type}
+ {
+
+ }
+
+ /**
+ * \brief Locks the mutex.
+ *
+ * Similar to std::mutex::lock() - http://en.cppreference.com/w/cpp/thread/mutex/lock
+ * Similar to pthread_mutex_lock() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html#
+ *
+ * If the mutex is already locked by another thread, the calling thread shall block until the mutex becomes
+ * available. This function shall return with the mutex in the locked state with the calling thread as its owner. If
+ * a thread attempts to relock a mutex that it has already locked, deadlock occurs.
+ *
+ * \return zero if the caller successfully locked the mutex, error code otherwise:
+ * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been
+ * exceeded;
+ * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex;
+ * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling
+ * thread's priority is higher than the mutex's current priority ceiling;
+ */
+
+ int lock();
+
+ /**
+ * \brief Tries to lock the mutex.
+ *
+ * Similar to std::mutex::try_lock() - http://en.cppreference.com/w/cpp/thread/mutex/try_lock
+ * Similar to pthread_mutex_trylock() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html#
+ *
+ * This function shall be equivalent to lock(), except that if the mutex is currently locked (by any thread,
+ * including the current thread), the call shall return immediately.
+ *
+ * \return zero if the caller successfully locked the mutex, error code otherwise:
+ * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been
+ * exceeded;
+ * - EBUSY - the mutex could not be acquired because it was already locked;
+ * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling
+ * thread's priority is higher than the mutex's current priority ceiling;
+ */
+
+ int tryLock();
+
+ /**
+ * \brief Tries to lock the mutex for given duration of time.
+ *
+ * Similar to std::timed_mutex::try_lock_for() - http://en.cppreference.com/w/cpp/thread/timed_mutex/try_lock_for
+ * Similar to pthread_mutex_timedlock() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_timedlock.html#
+ *
+ * If the mutex is already locked, the calling thread shall block until the mutex becomes available as in lock()
+ * function. If the mutex cannot be locked without waiting for another thread to unlock the mutex, this wait shall
+ * be terminated when the specified timeout expires.
+ *
+ * Under no circumstance shall the function fail with a timeout if the mutex can be locked immediately. The validity
+ * of the duration parameter need not be checked if the mutex can be locked immediately.
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without locking the mutex
+ *
+ * \return zero if the caller successfully locked the mutex, error code otherwise:
+ * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been
+ * exceeded;
+ * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex;
+ * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling
+ * thread's priority is higher than the mutex's current priority ceiling;
+ * - ETIMEDOUT - the mutex could not be locked before the specified timeout expired;
+ */
+
+ int tryLockFor(TickClock::duration duration);
+
+ /**
+ * Tries to lock the mutex for given duration of time.
+ *
+ * Template variant of tryLockFor(TickClock::duration duration).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without locking the mutex
+ *
+ * \return zero if the caller successfully locked the mutex, error code otherwise:
+ * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been
+ * exceeded;
+ * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex;
+ * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling
+ * thread's priority is higher than the mutex's current priority ceiling;
+ * - ETIMEDOUT - the mutex could not be locked before the specified timeout expired;
+ */
+
+ template<typename Rep, typename Period>
+ int tryLockFor(const std::chrono::duration<Rep, Period> duration)
+ {
+ return tryLockFor(std::chrono::duration_cast<TickClock::duration>(duration));
+ }
+
+ /**
+ * \brief Tries to lock the mutex until given time point.
+ *
+ * Similar to std::timed_mutex::try_lock_until() -
+ * http://en.cppreference.com/w/cpp/thread/timed_mutex/try_lock_until
+ * Similar to pthread_mutex_timedlock() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_timedlock.html#
+ *
+ * If the mutex is already locked, the calling thread shall block until the mutex becomes available as in lock()
+ * function. If the mutex cannot be locked without waiting for another thread to unlock the mutex, this wait shall
+ * be terminated when the specified timeout expires.
+ *
+ * Under no circumstance shall the function fail with a timeout if the mutex can be locked immediately. The validity
+ * of the timePoint parameter need not be checked if the mutex can be locked immediately.
+ *
+ * \param [in] timePoint is the time point at which the wait will be terminated without locking the mutex
+ *
+ * \return zero if the caller successfully locked the mutex, error code otherwise:
+ * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been
+ * exceeded;
+ * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex;
+ * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling
+ * thread's priority is higher than the mutex's current priority ceiling;
+ * - ETIMEDOUT - the mutex could not be locked before the specified timeout expired;
+ */
+
+ int tryLockUntil(TickClock::time_point timePoint);
+
+ /**
+ * \brief Tries to lock the mutex until given time point.
+ *
+ * Template variant of tryLockUntil(TickClock::time_point timePoint).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the wait will be terminated without locking the mutex
+ *
+ * \return zero if the caller successfully locked the mutex, error code otherwise:
+ * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been
+ * exceeded;
+ * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex;
+ * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling
+ * thread's priority is higher than the mutex's current priority ceiling;
+ * - ETIMEDOUT - the mutex could not be locked before the specified timeout expired;
+ */
+
+ template<typename Duration>
+ int tryLockUntil(const std::chrono::time_point<TickClock, Duration> timePoint)
+ {
+ return tryLockUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint));
+ }
+
+ /**
+ * \brief Unlocks the mutex.
+ *
+ * Similar to std::mutex::unlock() - http://en.cppreference.com/w/cpp/thread/mutex/unlock
+ * Similar to pthread_mutex_unlock() -
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html#
+ *
+ * The mutex must be locked by the current thread, otherwise, the behavior is undefined. If there are threads
+ * blocked on this mutex, the highest priority waiting thread shall be unblocked, and if there is more than one
+ * highest priority thread blocked waiting, then the highest priority thread that has been waiting the longest shall
+ * be unblocked.
+ *
+ * \return zero if the caller successfully unlocked the mutex, error code otherwise:
+ * - EPERM - the mutex type is ErrorChecking or Recursive, and the current thread does not own the mutex;
+ */
+
+ int unlock();
+
+private:
+
+ /**
+ * \brief Internal version of tryLock().
+ *
+ * Internal version with no interrupt masking and additional code for ErrorChecking type (which is not required for
+ * tryLock()).
+ *
+ * \return zero if the caller successfully locked the mutex, error code otherwise:
+ * - EAGAIN - the mutex could not be acquired because the maximum number of recursive locks for mutex has been
+ * exceeded;
+ * - EBUSY - the mutex could not be acquired because it was already locked;
+ * - EDEADLK - the mutex type is ErrorChecking and the current thread already owns the mutex;
+ * - EINVAL - the mutex was created with the protocol attribute having the value PriorityProtect and the calling
+ * thread's priority is higher than the mutex's current priority ceiling;
+ */
+
+ int tryLockInternal();
+
+ /// instance of control block
+ internal::MutexControlBlock controlBlock_;
+
+ /// number of recursive locks, used when mutex type is Recursive
+ RecursiveLocksCount recursiveLocksCount_;
+
+ /// type of mutex
+ Type type_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_MUTEX_HPP_
diff --git a/include/distortos/OnceFlag.hpp b/include/distortos/OnceFlag.hpp
new file mode 100644
index 0000000..0ac6185
--- /dev/null
+++ b/include/distortos/OnceFlag.hpp
@@ -0,0 +1,60 @@
+/**
+ * \file
+ * \brief OnceFlag 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_ONCEFLAG_HPP_
+#define INCLUDE_DISTORTOS_ONCEFLAG_HPP_
+
+#include "distortos/internal/synchronization/CallOnceControlBlock.hpp"
+
+#if DISTORTOS_CALLONCE_SUPPORTED == 1 || DOXYGEN == 1
+
+namespace distortos
+{
+
+/**
+ * \brief OnceFlag is a helper class for callOnce().
+ *
+ * Similar to std::once_flag - http://en.cppreference.com/w/cpp/thread/once_flag
+ * Similar to POSIX pthread_once_t - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_once.html#
+ *
+ * \note This class requires GCC 4.9.
+ *
+ * \ingroup synchronization
+ */
+
+class OnceFlag
+{
+ template<typename Function, typename... Args>
+ friend void callOnce(OnceFlag& onceFlag, Function&& function, Args&&... args);
+
+public:
+
+ /**
+ * \brief OnceFlag's constructor
+ */
+
+ constexpr OnceFlag() :
+ callOnceControlBlock_{}
+ {
+
+ }
+
+private:
+
+ /// internal internal::CallOnceControlBlock object used by callOnce()
+ internal::CallOnceControlBlock callOnceControlBlock_;
+};
+
+} // namespace distortos
+
+#endif // DISTORTOS_CALLONCE_SUPPORTED == 1 || DOXYGEN == 1
+
+#endif // INCLUDE_DISTORTOS_ONCEFLAG_HPP_
diff --git a/include/distortos/RawFifoQueue.hpp b/include/distortos/RawFifoQueue.hpp
new file mode 100644
index 0000000..94456a7
--- /dev/null
+++ b/include/distortos/RawFifoQueue.hpp
@@ -0,0 +1,463 @@
+/**
+ * \file
+ * \brief RawFifoQueue 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_RAWFIFOQUEUE_HPP_
+#define INCLUDE_DISTORTOS_RAWFIFOQUEUE_HPP_
+
+#include "distortos/internal/synchronization/FifoQueueBase.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief RawFifoQueue class is very similar to FifoQueue, but optimized for binary serializable types (like POD types).
+ *
+ * Type \a T can be used with both RawFifoQueue and FifoQueue only when
+ * <em>std::is_trivially_copyable<T>::value == true</em>, otherwise only FifoQueue use is safe, while using RawFifoQueue
+ * results in undefined behavior.
+ *
+ * \ingroup queues
+ */
+
+class RawFifoQueue
+{
+public:
+
+ /// unique_ptr (with deleter) to storage
+ using StorageUniquePointer = internal::FifoQueueBase::StorageUniquePointer;
+
+ /**
+ * \brief RawFifoQueue's constructor
+ *
+ * \param [in] storageUniquePointer is a rvalue reference to StorageUniquePointer with storage for queue elements
+ * (sufficiently large for \a maxElements, each \a elementSize bytes long) and appropriate deleter
+ * \param [in] elementSize is the size of single queue element, bytes
+ * \param [in] maxElements is the number of elements in storage memory block
+ */
+
+ RawFifoQueue(StorageUniquePointer&& storageUniquePointer, size_t elementSize, size_t maxElements);
+
+ /**
+ * \brief Pops the oldest (first) element from the queue.
+ *
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pop(void* buffer, size_t size);
+
+ /**
+ * \brief Pops the oldest (first) element from the queue.
+ *
+ * \tparam T is the type of data popped from the queue
+ *
+ * \param [out] buffer is a reference to object that will be used to return popped value
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename T>
+ int pop(T& buffer)
+ {
+ return pop(&buffer, sizeof(buffer));
+ }
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * \param [in] data is a pointer to data that will be pushed to RawFifoQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int push(const void* data, size_t size);
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * \tparam T is the type of data pushed to the queue
+ *
+ * \param [in] data is a reference to data that will be pushed to RawFifoQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename T>
+ int push(const T& data)
+ {
+ return push(&data, sizeof(data));
+ }
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue.
+ *
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPop(void* buffer, size_t size);
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue.
+ *
+ * \tparam T is the type of data popped from the queue
+ *
+ * \param [out] buffer is a reference to object that will be used to return popped value
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename T>
+ int tryPop(T& buffer)
+ {
+ return tryPop(&buffer, sizeof(buffer));
+ }
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue for a given duration of time.
+ *
+ * \param [in] duration is the duration after which the call will be terminated without popping the element
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPopFor(TickClock::duration duration, void* buffer, size_t size);
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue for a given duration of time.
+ *
+ * Template variant of tryPopFor(TickClock::duration, void*, size_t).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the call will be terminated without popping the element
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period>
+ int tryPopFor(const std::chrono::duration<Rep, Period> duration, void* const buffer, const size_t size)
+ {
+ return tryPopFor(std::chrono::duration_cast<TickClock::duration>(duration), buffer, size);
+ }
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue for a given duration of time.
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ * \tparam T is the type of data popped from the queue
+ *
+ * \param [in] duration is the duration after which the call will be terminated without popping the element
+ * \param [out] buffer is a reference to object that will be used to return popped value
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period, typename T>
+ int tryPopFor(const std::chrono::duration<Rep, Period> duration, T& buffer)
+ {
+ return tryPopFor(std::chrono::duration_cast<TickClock::duration>(duration), &buffer, sizeof(buffer));
+ }
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue until a given time point.
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without popping the element
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPopUntil(TickClock::time_point timePoint, void* buffer, size_t size);
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue until a given time point.
+ *
+ * Template variant of tryPopUntil(TickClock::time_point, void*, size_t).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without popping the element
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration>
+ int tryPopUntil(const std::chrono::time_point<TickClock, Duration> timePoint, void* const buffer, const size_t size)
+ {
+ return tryPopUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), buffer, size);
+ }
+
+ /**
+ * \brief Tries to pop the oldest (first) element from the queue until a given time point.
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ * \tparam T is the type of data popped from the queue
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without popping the element
+ * \param [out] buffer is a reference to object that will be used to return popped value
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration, typename T>
+ int tryPopUntil(const std::chrono::time_point<TickClock, Duration> timePoint, T& buffer)
+ {
+ return tryPopUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), &buffer, sizeof(buffer));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue.
+ *
+ * \param [in] data is a pointer to data that will be pushed to RawFifoQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPush(const void* data, size_t size);
+
+ /**
+ * \brief Tries to push the element to the queue.
+ *
+ * \tparam T is the type of data pushed to the queue
+ *
+ * \param [in] data is a reference to data that will be pushed to RawFifoQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename T>
+ int tryPush(const T& data)
+ {
+ return tryPush(&data, sizeof(data));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without pushing the element
+ * \param [in] data is a pointer to data that will be pushed to RawFifoQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushFor(TickClock::duration duration, const void* data, size_t size);
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * Template variant of tryPushFor(TickClock::duration, const void*, size_t).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without pushing the element
+ * \param [in] data is a pointer to data that will be pushed to RawFifoQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period>
+ int tryPushFor(const std::chrono::duration<Rep, Period> duration, const void* const data, const size_t size)
+ {
+ return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), data, size);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ * \tparam T is the type of data pushed to the queue
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without pushing the element
+ * \param [in] data is a reference to data that will be pushed to RawFifoQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period, typename T>
+ int tryPushFor(const std::chrono::duration<Rep, Period> duration, const T& data)
+ {
+ return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), &data, sizeof(data));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] data is a pointer to data that will be pushed to RawFifoQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushUntil(TickClock::time_point timePoint, const void* data, size_t size);
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * Template variant of tryPushUntil(TickClock::time_point, const void*, size_t).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] data is a pointer to data that will be pushed to RawFifoQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration>
+ int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const void* const data,
+ const size_t size)
+ {
+ return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), data, size);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ * \tparam T is the type of data pushed to the queue
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] data is a reference to data that will be pushed to RawFifoQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration, typename T>
+ int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const T& data)
+ {
+ return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), &data, sizeof(data));
+ }
+
+private:
+
+ /**
+ * \brief Pops the oldest (first) element from the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a popSemaphore_
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, void* buffer, size_t size);
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
+ * \param [in] data is a pointer to data that will be pushed to RawFifoQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawFifoQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawFifoQueue;
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const void* data, size_t size);
+
+ /// contained internal::FifoQueueBase object which implements base functionality
+ internal::FifoQueueBase fifoQueueBase_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_RAWFIFOQUEUE_HPP_
diff --git a/include/distortos/RawMessageQueue.hpp b/include/distortos/RawMessageQueue.hpp
new file mode 100644
index 0000000..d4b2a54
--- /dev/null
+++ b/include/distortos/RawMessageQueue.hpp
@@ -0,0 +1,555 @@
+/**
+ * \file
+ * \brief RawMessageQueue 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_RAWMESSAGEQUEUE_HPP_
+#define INCLUDE_DISTORTOS_RAWMESSAGEQUEUE_HPP_
+
+#include "distortos/internal/synchronization/MessageQueueBase.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief RawMessageQueue class is very similar to MessageQueue, but optimized for binary serializable types (like POD
+ * types).
+ *
+ * Type \a T can be used with both RawMessageQueue and MessageQueue only when
+ * <em>std::is_trivially_copyable<T>::value == true</em>, otherwise only MessageQueue use is safe, while using
+ * RawMessageQueue results in undefined behavior.
+ *
+ * Similar to POSIX mqd_t - http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/mqueue.h.html
+ *
+ * \ingroup queues
+ */
+
+class RawMessageQueue
+{
+public:
+
+ /// type of uninitialized storage for Entry with link
+ using EntryStorage = internal::MessageQueueBase::EntryStorage;
+
+ /// import EntryStorageUniquePointer type from internal::MessageQueueBase class
+ using EntryStorageUniquePointer = internal::MessageQueueBase::EntryStorageUniquePointer;
+
+ /**
+ * type of uninitialized storage for value
+ *
+ * \tparam T is the type of data in queue
+ */
+
+ template<typename T>
+ using ValueStorage = internal::MessageQueueBase::ValueStorage<T>;
+
+ using ValueStorageUniquePointer = internal::MessageQueueBase::ValueStorageUniquePointer;
+
+ /**
+ * \brief RawMessageQueue's constructor
+ *
+ * \param [in] entryStorageUniquePointer is a rvalue reference to EntryStorageUniquePointer with storage for queue
+ * entries (sufficiently large for \a maxElements EntryStorage objects) and appropriate deleter
+ * \param [in] valueStorageUniquePointer is a rvalue reference to ValueStorageUniquePointer with storage for queue
+ * elements (sufficiently large for \a maxElements, each \a elementSize bytes long) and appropriate deleter
+ * \param [in] elementSize is the size of single queue element, bytes
+ * \param [in] maxElements is the number of elements in \a entryStorage array and \a valueStorage memory block
+ */
+
+ RawMessageQueue(EntryStorageUniquePointer&& entryStorageUniquePointer,
+ ValueStorageUniquePointer&& valueStorageUniquePointer, size_t elementSize, size_t maxElements);
+
+ /**
+ * \brief Pops oldest element with highest priority from the queue.
+ *
+ * Similar to mq_receive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of
+ * RawMessageQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pop(uint8_t& priority, void* buffer, size_t size);
+
+ /**
+ * \brief Pops oldest element with highest priority from the queue.
+ *
+ * Similar to mq_receive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \tparam T is the type of data popped from the queue
+ *
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] buffer is a reference to object that will be used to return popped value
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename T>
+ int pop(uint8_t& priority, T& buffer)
+ {
+ return pop(priority, &buffer, sizeof(buffer));
+ }
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * Similar to mq_send() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] priority is the priority of new element
+ * \param [in] data is a pointer to data that will be pushed to RawMessageQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawMessageQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int push(uint8_t priority, const void* data, size_t size);
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * Similar to mq_send() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \tparam T is the type of data pushed to the queue
+ *
+ * \param [in] priority is the priority of new element
+ * \param [in] data is a reference to data that will be pushed to RawMessageQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::wait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename T>
+ int push(const uint8_t priority, const T& data)
+ {
+ return push(priority, &data, sizeof(data));
+ }
+
+ /**
+ * \brief Tries to pop the oldest element with highest priority from the queue.
+ *
+ * Similar to mq_receive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of
+ * RawMessageQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPop(uint8_t& priority, void* buffer, size_t size);
+
+ /**
+ * \brief Tries to pop the oldest element with highest priority from the queue.
+ *
+ * Similar to mq_receive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \tparam T is the type of data popped from the queue
+ *
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] buffer is a reference to object that will be used to return popped value
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename T>
+ int tryPop(uint8_t& priority, T& buffer)
+ {
+ return tryPop(priority, &buffer, sizeof(buffer));
+ }
+
+ /**
+ * \brief Tries to pop the oldest element with highest priority from the queue for a given duration of time.
+ *
+ * Similar to mq_timedreceive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \param [in] duration is the duration after which the call will be terminated without popping the element
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of
+ * RawMessageQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPopFor(TickClock::duration duration, uint8_t& priority, void* buffer, size_t size);
+
+ /**
+ * \brief Tries to pop the oldest element with highest priority from the queue for a given duration of time.
+ *
+ * Template variant of tryPopFor(TickClock::duration, uint8_t&, void*, size_t).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the call will be terminated without popping the element
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of
+ * RawMessageQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period>
+ int tryPopFor(const std::chrono::duration<Rep, Period> duration, uint8_t& priority, void* const buffer,
+ const size_t size)
+ {
+ return tryPopFor(std::chrono::duration_cast<TickClock::duration>(duration), priority, buffer, size);
+ }
+
+ /**
+ * \brief Tries to pop the oldest element with highest priority from the queue for a given duration of time.
+ *
+ * Similar to mq_timedreceive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ * \tparam T is the type of data popped from the queue
+ *
+ * \param [in] duration is the duration after which the call will be terminated without popping the element
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] buffer is a reference to object that will be used to return popped value
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period, typename T>
+ int tryPopFor(const std::chrono::duration<Rep, Period> duration, uint8_t& priority, T& buffer)
+ {
+ return tryPopFor(std::chrono::duration_cast<TickClock::duration>(duration), priority, &buffer, sizeof(buffer));
+ }
+
+ /**
+ * \brief Tries to pop the oldest element with highest priority from the queue until a given time point.
+ *
+ * Similar to mq_timedreceive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without popping the element
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of
+ * RawMessageQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPopUntil(TickClock::time_point timePoint, uint8_t& priority, void* buffer, size_t size);
+
+ /**
+ * \brief Tries to pop the oldest element with highest priority from the queue until a given time point.
+ *
+ * Template variant of tryPopUntil(TickClock::time_point, uint8_t&, void*, size_t).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without popping the element
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of
+ * RawMessageQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration>
+ int tryPopUntil(const std::chrono::time_point<TickClock, Duration> timePoint, uint8_t& priority, void* const buffer,
+ const size_t size)
+ {
+ return tryPopUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority, buffer, size);
+ }
+
+ /**
+ * \brief Tries to pop the oldest element with highest priority from the queue until a given time point.
+ *
+ * Similar to mq_timedreceive() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html#
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ * \tparam T is the type of data popped from the queue
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without popping the element
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] buffer is a reference to object that will be used to return popped value
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration, typename T>
+ int tryPopUntil(const std::chrono::time_point<TickClock, Duration> timePoint, uint8_t& priority, T& buffer)
+ {
+ return tryPopUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority, &buffer,
+ sizeof(buffer));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue.
+ *
+ * Similar to mq_send() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] priority is the priority of new element
+ * \param [in] data is a pointer to data that will be pushed to RawMessageQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawMessageQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPush(uint8_t priority, const void* data, size_t size);
+
+ /**
+ * \brief Tries to push the element to the queue.
+ *
+ * Similar to mq_send() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \tparam T is the type of data pushed to the queue
+ *
+ * \param [in] priority is the priority of new element
+ * \param [in] data is a reference to data that will be pushed to RawMessageQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWait();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename T>
+ int tryPush(const uint8_t priority, const T& data)
+ {
+ return tryPush(priority, &data, sizeof(data));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * Similar to mq_timedsend() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] data is a pointer to data that will be pushed to RawMessageQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawMessageQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushFor(TickClock::duration duration, uint8_t priority, const void* data, size_t size);
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * Template variant of tryPushFor(TickClock::duration, uint8_t, const void*, size_t).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] data is a pointer to data that will be pushed to RawMessageQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawMessageQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period>
+ int tryPushFor(const std::chrono::duration<Rep, Period> duration, const uint8_t priority, const void* const data,
+ const size_t size)
+ {
+ return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), priority, data, size);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue for a given duration of time.
+ *
+ * Similar to mq_timedsend() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ * \tparam T is the type of data pushed to the queue
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] data is a reference to data that will be pushed to RawMessageQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitFor();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Rep, typename Period, typename T>
+ int tryPushFor(const std::chrono::duration<Rep, Period> duration, const uint8_t priority, const T& data)
+ {
+ return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), priority, &data, sizeof(data));
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * Similar to mq_timedsend() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] data is a pointer to data that will be pushed to RawMessageQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawMessageQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ int tryPushUntil(TickClock::time_point timePoint, uint8_t priority, const void* data, size_t size);
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * Template variant of tryPushUntil(TickClock::time_point, uint8_t, const void*, size_t).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] data is a pointer to data that will be pushed to RawMessageQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawMessageQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration>
+ int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const uint8_t priority,
+ const void* const data, const size_t size)
+ {
+ return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority, data, size);
+ }
+
+ /**
+ * \brief Tries to push the element to the queue until a given time point.
+ *
+ * Similar to mq_timedsend() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html#
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ * \tparam T is the type of data pushed to the queue
+ *
+ * \param [in] timePoint is the time point at which the call will be terminated without pushing the element
+ * \param [in] priority is the priority of new element
+ * \param [in] data is a reference to data that will be pushed to RawMessageQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - sizeof(T) doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by Semaphore::tryWaitUntil();
+ * - error codes returned by Semaphore::post();
+ */
+
+ template<typename Duration, typename T>
+ int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const uint8_t priority,
+ const T& data)
+ {
+ return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority, &data,
+ sizeof(data));
+ }
+
+private:
+
+ /**
+ * \brief Pops oldest element with highest priority from the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a popSemaphore_
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes - must be equal to the \a elementSize attribute of
+ * RawMessageQueue
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t& priority, void* buffer,
+ size_t size);
+
+ /**
+ * \brief Pushes the element to the queue.
+ *
+ * Internal version - builds the Functor object.
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
+ * \param [in] priority is the priority of new element
+ * \param [in] data is a pointer to data that will be pushed to RawMessageQueue
+ * \param [in] size is the size of \a data, bytes - must be equal to the \a elementSize attribute of RawMessageQueue
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - EMSGSIZE - \a size doesn't match the \a elementSize attribute of RawMessageQueue;
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t priority, const void* data,
+ size_t size);
+
+ /// contained internal::MessageQueueBase object which implements base functionality
+ internal::MessageQueueBase messageQueueBase_;
+
+ /// size of single queue element, bytes
+ const size_t elementSize_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_RAWMESSAGEQUEUE_HPP_
diff --git a/include/distortos/SchedulingPolicy.hpp b/include/distortos/SchedulingPolicy.hpp
new file mode 100644
index 0000000..8793fb4
--- /dev/null
+++ b/include/distortos/SchedulingPolicy.hpp
@@ -0,0 +1,36 @@
+/**
+ * \file
+ * \brief SchedulingPolicy enum class header
+ *
+ * \author Copyright (C) 2014 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_SCHEDULINGPOLICY_HPP_
+#define INCLUDE_DISTORTOS_SCHEDULINGPOLICY_HPP_
+
+#include <cstdint>
+
+namespace distortos
+{
+
+/**
+ * \brief scheduling policy of the thread
+ *
+ * \ingroup threads
+ */
+
+enum class SchedulingPolicy : uint8_t
+{
+ /// FIFO scheduling policy
+ fifo,
+ /// round-robin scheduling policy
+ roundRobin,
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_SCHEDULINGPOLICY_HPP_
diff --git a/include/distortos/Semaphore.hpp b/include/distortos/Semaphore.hpp
new file mode 100644
index 0000000..26ca298
--- /dev/null
+++ b/include/distortos/Semaphore.hpp
@@ -0,0 +1,245 @@
+/**
+ * \file
+ * \brief Semaphore 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_SEMAPHORE_HPP_
+#define INCLUDE_DISTORTOS_SEMAPHORE_HPP_
+
+#include "distortos/internal/scheduler/ThreadList.hpp"
+
+#include "distortos/TickClock.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief Semaphore is the basic synchronization primitive
+ *
+ * Similar to POSIX semaphores - http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_16
+ *
+ * \ingroup synchronization
+ */
+
+class Semaphore
+{
+public:
+
+ /// type used for semaphore's "value"
+ using Value = unsigned int;
+
+ /**
+ * \brief Semaphore constructor
+ *
+ * Similar to sem_init() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_init.html#
+ *
+ * \param [in] value is the initial value of the semaphore, if this value is greater than maxValue, it will be
+ * truncated
+ * \param [in] maxValue is the max value of the semaphore before post() returns EOVERFLOW, default - max for Value
+ * type
+ */
+
+ constexpr explicit Semaphore(const Value value, const Value maxValue = std::numeric_limits<Value>::max()) :
+ blockedList_{},
+ value_{value <= maxValue ? value : maxValue},
+ maxValue_{maxValue}
+ {
+
+ }
+
+ /**
+ * \brief Semaphore destructor
+ *
+ * Similar to sem_destroy() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_destroy.html#
+ *
+ * It is safe to destroy a semaphore upon which no threads are currently blocked. The effect of destroying a
+ * semaphore upon which other threads are currently blocked is system error.
+ */
+
+ ~Semaphore()
+ {
+
+ }
+
+ /**
+ * \brief Gets current value of semaphore.
+ *
+ * Similar to sem_getvalue() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_getvalue.html#
+ *
+ * \return current value of semaphore, positive value if semaphore is not locked, zero otherwise
+ */
+
+ Value getValue() const
+ {
+ return value_;
+ }
+
+ /**
+ * \brief Unlocks the semaphore.
+ *
+ * Similar to sem_post() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_post.html#
+ *
+ * This function shall unlock the semaphore by performing a semaphore unlock operation. If the semaphore value
+ * resulting from this operation is positive, then no threads were blocked waiting for the semaphore to become
+ * unlocked; the semaphore value is simply incremented. Otherwise one of the threads blocked waiting for the
+ * semaphore shall be allowed to return successfully from its call to lock() - the highest priority waiting thread
+ * shall be unblocked, and if there is more than one highest priority thread blocked waiting for the semaphore, then
+ * the highest priority thread that has been waiting the longest shall be unblocked.
+ *
+ * \return zero if the calling process successfully "posted" the semaphore, error code otherwise:
+ * - EOVERFLOW - the maximum allowable value for a semaphore would be exceeded;
+ */
+
+ int post();
+
+ /**
+ * \brief Tries to lock the semaphore.
+ *
+ * Similar to sem_trywait() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_trywait.html#
+ *
+ * This function shall lock the semaphore only if the semaphore is currently not locked; that is, if the semaphore
+ * value is currently positive. Otherwise, it shall not lock the semaphore. Upon successful return, the state of the
+ * semaphore shall be locked and shall remain locked until unlock() function is executed.
+ *
+ * \return zero if the calling process successfully performed the semaphore lock operation, error code otherwise:
+ * - EAGAIN - semaphore was already locked, so it cannot be immediately locked by the tryWait() operation;
+ */
+
+ int tryWait();
+
+ /**
+ * \brief Tries to lock the semaphore for given duration of time.
+ *
+ * Similar to sem_timedwait() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_timedwait.html#
+ *
+ * If the semaphore is already locked, the calling thread shall block until the semaphore becomes available as in
+ * wait() function. If the semaphore cannot be locked without waiting for another thread to unlock the semaphore,
+ * this wait shall be terminated when the specified timeout expires.
+ *
+ * Under no circumstance shall the function fail with a timeout if the semaphore can be locked immediately. The
+ * validity of the duration parameter need not be checked if the semaphore can be locked immediately.
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without locking the semaphore
+ *
+ * \return zero if the calling process successfully performed the semaphore lock operation, error code otherwise:
+ * - EINTR - the wait was interrupted by an unmasked, caught signal;
+ * - ETIMEDOUT - the semaphore could not be locked before the specified timeout expired;
+ */
+
+ int tryWaitFor(TickClock::duration duration);
+
+ /**
+ * \brief Tries to lock the semaphore for given duration of time.
+ *
+ * Template variant of tryWaitFor(TickClock::duration duration).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the wait will be terminated without locking the semaphore
+ *
+ * \return zero if the calling process successfully performed the semaphore lock operation, error code otherwise:
+ * - EINTR - the wait was interrupted by an unmasked, caught signal;
+ * - ETIMEDOUT - the semaphore could not be locked before the specified timeout expired;
+ */
+
+ template<typename Rep, typename Period>
+ int tryWaitFor(const std::chrono::duration<Rep, Period> duration)
+ {
+ return tryWaitFor(std::chrono::duration_cast<TickClock::duration>(duration));
+ }
+
+ /**
+ * \brief Tries to lock the semaphore until given time point.
+ *
+ * Similar to sem_timedwait() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_timedwait.html#
+ *
+ * If the semaphore is already locked, the calling thread shall block until the semaphore becomes available as in
+ * wait() function. If the semaphore cannot be locked without waiting for another thread to unlock the semaphore,
+ * this wait shall be terminated when the specified timeout expires.
+ *
+ * Under no circumstance shall the function fail with a timeout if the semaphore can be locked immediately. The
+ * validity of the timePoint parameter need not be checked if the semaphore can be locked immediately.
+ *
+ * \param [in] timePoint is the time point at which the wait will be terminated without locking the semaphore
+ *
+ * \return zero if the calling process successfully performed the semaphore lock operation, error code otherwise:
+ * - EINTR - the wait was interrupted by an unmasked, caught signal;
+ * - ETIMEDOUT - the semaphore could not be locked before the specified timeout expired;
+ */
+
+ int tryWaitUntil(TickClock::time_point timePoint);
+
+ /**
+ * \brief Tries to lock the semaphore until given time point.
+ *
+ * Template variant of tryWaitUntil(TickClock::time_point timePoint).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the wait will be terminated without locking the semaphore
+ *
+ * \return zero if the calling process successfully performed the semaphore lock operation, error code otherwise:
+ * - EINTR - the wait was interrupted by an unmasked, caught signal;
+ * - ETIMEDOUT - the semaphore could not be locked before the specified timeout expired;
+ */
+
+ template<typename Duration>
+ int tryWaitUntil(const std::chrono::time_point<TickClock, Duration> timePoint)
+ {
+ return tryWaitUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint));
+ }
+
+ /**
+ * \brief Locks the semaphore.
+ *
+ * Similar to sem_wait() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_trywait.html#
+ *
+ * This function shall lock the semaphore by performing a semaphore lock operation on that semaphore. If the
+ * semaphore value is currently zero, then the calling thread shall not return from the call to lock() until it
+ * either locks the semaphore or the call is interrupted by a signal. Upon successful return, the state of the
+ * semaphore shall be locked and shall remain locked until unlock() function is executed.
+ *
+ * \return zero if the calling process successfully performed the semaphore lock operation, error code otherwise:
+ * - EINTR - the wait was interrupted by an unmasked, caught signal;
+ */
+
+ int wait();
+
+ Semaphore(const Semaphore&) = delete;
+ Semaphore(Semaphore&&) = default;
+ const Semaphore& operator=(const Semaphore&) = delete;
+ Semaphore& operator=(Semaphore&&) = delete;
+
+private:
+
+ /**
+ * \brief Internal version of tryWait().
+ *
+ * Internal version with no interrupt masking.
+ *
+ * \return zero if the calling process successfully performed the semaphore lock operation, error code otherwise:
+ * - EAGAIN - semaphore was already locked, so it cannot be immediately locked by the tryWait() operation;
+ */
+
+ int tryWaitInternal();
+
+ /// ThreadControlBlock objects blocked on this semaphore
+ internal::ThreadList blockedList_;
+
+ /// internal value of the semaphore
+ Value value_;
+
+ /// max value of the semaphore
+ Value maxValue_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_SEMAPHORE_HPP_
diff --git a/include/distortos/SignalAction.hpp b/include/distortos/SignalAction.hpp
new file mode 100644
index 0000000..d91d696
--- /dev/null
+++ b/include/distortos/SignalAction.hpp
@@ -0,0 +1,96 @@
+/**
+ * \file
+ * \brief SignalAction 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_SIGNALACTION_HPP_
+#define INCLUDE_DISTORTOS_SIGNALACTION_HPP_
+
+#include "distortos/SignalSet.hpp"
+
+namespace distortos
+{
+
+class SignalInformation;
+
+/**
+ * \brief SignalAction class contains information needed to handle signal that was caught
+ *
+ * Similar to \a sigaction - http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html
+ *
+ * \ingroup signals
+ */
+
+class SignalAction
+{
+public:
+
+ /// handler function
+ using Handler = void(const SignalInformation&);
+
+ /**
+ * \brief SignalAction's constructor which uses "default" signal handler.
+ */
+
+ constexpr SignalAction() :
+ signalMask_{SignalSet::empty},
+ handler_{}
+ {
+
+ }
+
+ /**
+ * \brief SignalAction's constructor.
+ *
+ * \param [in] handler is a reference to handler function (similar to \a sa_sigaction member of \a sigaction)
+ * \param [in] signalMask is the additional set of signals to be masked during execution of signal-catching function
+ * (similar to \a sa_mask member of \a sigaction)
+ */
+
+ constexpr SignalAction(Handler& handler, const SignalSet signalMask) :
+ signalMask_{signalMask},
+ handler_{&handler}
+ {
+
+ }
+
+ /**
+ * \return pointer to handler function (similar to \a sa_sigaction member of \a sigaction), nullptr if use of
+ * default handler was configured (similar to \a SIG_DFL)
+ */
+
+ Handler* getHandler() const
+ {
+ return handler_;
+ }
+
+ /**
+ * \return additional set of signals to be masked during execution of signal-catching function (similar to
+ * \a sa_mask member of \a sigaction)
+ */
+
+ SignalSet getSignalMask() const
+ {
+ return signalMask_;
+ }
+
+private:
+
+ /// additional set of signals to be masked during execution of signal-catching function (similar to \a sa_mask
+ /// member of \a sigaction)
+ SignalSet signalMask_;
+
+ /// pointer to handler function (similar to \a sa_sigaction member of \a sigaction), nullptr to use default handler
+ /// (similar to \a SIG_DFL)
+ Handler* handler_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_SIGNALACTION_HPP_
diff --git a/include/distortos/SignalInformation.hpp b/include/distortos/SignalInformation.hpp
new file mode 100644
index 0000000..b3d897c
--- /dev/null
+++ b/include/distortos/SignalInformation.hpp
@@ -0,0 +1,100 @@
+/**
+ * \file
+ * \brief SignalInformation 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_SIGNALINFORMATION_HPP_
+#define INCLUDE_DISTORTOS_SIGNALINFORMATION_HPP_
+
+#include <csignal>
+#include <cstdint>
+
+namespace distortos
+{
+
+/**
+ * \brief SignalInformation class contains information about queued signal
+ *
+ * Similar to siginfo_t - http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html
+ *
+ * \ingroup signals
+ */
+
+class SignalInformation
+{
+public:
+
+ /// replacement for predefined \a si_code values
+ enum class Code : uint8_t
+ {
+ /// signal generated by Thread::generateSignal() or ThisThread::Signals::generateSignal() (similar to
+ /// \a SI_USER)
+ generated,
+ /// signal queued by Thread::queueSignal() or ThisThread::Signals::queueSignal() (similar to \a SI_QUEUE)
+ queued,
+ };
+
+ /**
+ * \brief SignalInformation's constructor.
+ *
+ * \param [in] signalNumber is the signal number (similar to \a si_signo member of \a siginfo_t)
+ * \param [in] code is the signal code (similar to \a si_code member of \a siginfo_t)
+ * \param [in] value is the signal value (similar to \a si_value member of \a siginfo_t)
+ */
+
+ constexpr SignalInformation(const uint8_t signalNumber, const Code code, const sigval value) :
+ value_(value),
+ code_{code},
+ signalNumber_{signalNumber}
+ {
+
+ }
+
+ /**
+ * \return signal code (similar to \a si_code member of \a siginfo_t)
+ */
+
+ Code getCode() const
+ {
+ return code_;
+ }
+
+ /**
+ * \return signal number (similar to \a si_signo member of \a siginfo_t)
+ */
+
+ uint8_t getSignalNumber() const
+ {
+ return signalNumber_;
+ }
+
+ /**
+ * \return signal value (similar to \a si_value member of \a siginfo_t)
+ */
+
+ sigval getValue() const
+ {
+ return value_;
+ }
+
+private:
+
+ /// signal value (similar to \a si_value member of \a siginfo_t)
+ sigval value_;
+
+ /// signal code (similar to \a si_code member of \a siginfo_t)
+ Code code_;
+
+ /// signal number (similar to \a si_signo member of \a siginfo_t)
+ uint8_t signalNumber_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_SIGNALINFORMATION_HPP_
diff --git a/include/distortos/SignalInformationQueueWrapper.hpp b/include/distortos/SignalInformationQueueWrapper.hpp
new file mode 100644
index 0000000..f3825a5
--- /dev/null
+++ b/include/distortos/SignalInformationQueueWrapper.hpp
@@ -0,0 +1,62 @@
+/**
+ * \file
+ * \brief SignalInformationQueueWrapper 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_SIGNALINFORMATIONQUEUEWRAPPER_HPP_
+#define INCLUDE_DISTORTOS_SIGNALINFORMATIONQUEUEWRAPPER_HPP_
+
+#include "distortos/internal/synchronization/SignalInformationQueue.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class SignalsReceiverControlBlock;
+
+} // namespace internal
+
+/// SignalInformationQueueWrapper class is a container for internal::SignalInformationQueue
+class SignalInformationQueueWrapper
+{
+ friend class internal::SignalsReceiverControlBlock;
+
+public:
+
+ /// import Storage type alias from internal::SignalInformationQueue
+ using Storage = internal::SignalInformationQueue::Storage;
+
+ /// import StorageUniquePointer type alias from internal::SignalInformationQueue
+ using StorageUniquePointer = internal::SignalInformationQueue::StorageUniquePointer;
+
+ /**
+ * \brief SignalInformationQueueWrapper's constructor
+ *
+ * \param [in] storageUniquePointer is a rvalue reference to StorageUniquePointer with storage for queue elements
+ * (sufficiently large for \a maxElements Storage objects) and appropriate deleter
+ * \param [in] maxElements is the number of elements in \a storage array
+ */
+
+ SignalInformationQueueWrapper(StorageUniquePointer&& storageUniquePointer, const size_t maxElements) :
+ signalInformationQueue_{std::move(storageUniquePointer), maxElements}
+ {
+
+ }
+
+private:
+
+ /// contained internal::SignalInformationQueue object
+ internal::SignalInformationQueue signalInformationQueue_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_SIGNALINFORMATIONQUEUEWRAPPER_HPP_
diff --git a/include/distortos/SignalSet.hpp b/include/distortos/SignalSet.hpp
new file mode 100644
index 0000000..8473bdd
--- /dev/null
+++ b/include/distortos/SignalSet.hpp
@@ -0,0 +1,179 @@
+/**
+ * \file
+ * \brief SignalSet 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_SIGNALSET_HPP_
+#define INCLUDE_DISTORTOS_SIGNALSET_HPP_
+
+#include <bitset>
+
+namespace distortos
+{
+
+/**
+ * \brief SignalSet class is used as a set of signals.
+ *
+ * Similar to POSIX sigset_t - http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html
+ *
+ * \ingroup signals
+ */
+
+class SignalSet
+{
+public:
+
+ /// type of internal bitset for 32 signals
+ using Bitset = std::bitset<32>;
+
+ /// tag struct to construct empty SignalSet
+ struct Empty
+ {
+
+ };
+
+ /// tag struct to construct full SignalSet
+ struct Full
+ {
+
+ };
+
+ /// tag object to construct empty SignalSet
+ constexpr static Empty empty = {};
+
+ /// tag object to construct full SignalSet
+ constexpr static Full full = {};
+
+ /**
+ * \brief SignalSet's constructor
+ *
+ * \param [in] bitmask is the bit mask used to initialize internal bitset
+ */
+
+ constexpr explicit SignalSet(uint32_t bitmask) :
+ bitset_{bitmask}
+ {
+
+ }
+
+ /**
+ * \brief SignalSet's constructor
+ *
+ * \param [in] bitset is a reference to Bitset from which internal bitset is copy-constructed
+ */
+
+ constexpr explicit SignalSet(const Bitset& bitset) :
+ bitset_{bitset}
+ {
+
+ }
+
+ /**
+ * \brief SignalSet's constructor
+ *
+ * Constructs empty SignalSet.
+ *
+ * Similar to sigemptyset() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigemptyset.html#
+ */
+
+ constexpr explicit SignalSet(const Empty&) :
+ SignalSet{uint32_t{}}
+ {
+
+ }
+
+ /**
+ * \brief SignalSet's constructor
+ *
+ * Constructs full SignalSet.
+ *
+ * Similar to sigfillset() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigfillset.html#
+ */
+
+ constexpr explicit SignalSet(const Full&) :
+ SignalSet{~uint32_t{}}
+ {
+
+ }
+
+ /**
+ * \brief Sets single bit.
+ *
+ * Similar to sigaddset() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaddset.html#
+ *
+ * \param [in] signalNumber is the bit position that will be set, [0; 31]
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ int add(const uint8_t signalNumber)
+ {
+ return set(signalNumber, true);
+ }
+
+ /**
+ * \return copy of internal bitset
+ */
+
+ Bitset getBitset() const
+ {
+ return bitset_;
+ }
+
+ /**
+ * \brief Clears single bit.
+ *
+ * Similar to sigdelset() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigdelset.html#
+ *
+ * \param [in] signalNumber is the bit position that will be cleared, [0; 31]
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ int remove(const uint8_t signalNumber)
+ {
+ return set(signalNumber, false);
+ }
+
+ /**
+ * \brief Tests whether the bit is set.
+ *
+ * Similar to sigismember() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigismember.html#
+ *
+ * \param [in] signalNumber is the bit position that will be tested, [0; 31]
+ *
+ * \return pair with return code (0 on success, error code otherwise) and value of selected bit; error codes:
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ std::pair<int, bool> test(uint8_t signalNumber) const;
+
+private:
+
+ /**
+ * \brief Sets value of single bit.
+ *
+ * \param [in] signalNumber is the bit position that will be modified, [0; 31]
+ * \param [in] value is the new value for selected bit
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ int set(uint8_t signalNumber, bool value);
+
+ /// internal bitset for 32 signals
+ Bitset bitset_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_SIGNALSET_HPP_
diff --git a/include/distortos/SignalsCatcher.hpp b/include/distortos/SignalsCatcher.hpp
new file mode 100644
index 0000000..effaf73
--- /dev/null
+++ b/include/distortos/SignalsCatcher.hpp
@@ -0,0 +1,62 @@
+/**
+ * \file
+ * \brief SignalsCatcher 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_SIGNALSCATCHER_HPP_
+#define INCLUDE_DISTORTOS_SIGNALSCATCHER_HPP_
+
+#include "distortos/internal/synchronization/SignalsCatcherControlBlock.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class SignalsReceiverControlBlock;
+
+} // namespace internal
+
+/// SignalsCatcher class is a container for internal::SignalsCatcherControlBlock
+class SignalsCatcher
+{
+ friend class internal::SignalsReceiverControlBlock;
+
+public:
+
+ /// import Storage type alias from internal::SignalsCatcherControlBlock
+ using Storage = internal::SignalsCatcherControlBlock::Storage;
+
+ /// import StorageUniquePointer type alias from internal::SignalsCatcherControlBlock
+ using StorageUniquePointer = internal::SignalsCatcherControlBlock::StorageUniquePointer;
+
+ /**
+ * \brief SignalsCatcher's constructor
+ *
+ * \param [in] storageUniquePointer is a rvalue reference to StorageUniquePointer with storage for
+ * internal::Association objects (sufficiently large for \a storageSize elements) and appropriate deleter
+ * \param [in] storageSize is the number of elements in \a storage array
+ */
+
+ SignalsCatcher(StorageUniquePointer&& storageUniquePointer, const size_t storageSize) :
+ signalsCatcherControlBlock_{std::move(storageUniquePointer), storageSize}
+ {
+
+ }
+
+private:
+
+ /// contained internal::SignalsCatcherControlBlock object
+ internal::SignalsCatcherControlBlock signalsCatcherControlBlock_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_SIGNALSCATCHER_HPP_
diff --git a/include/distortos/SignalsReceiver.hpp b/include/distortos/SignalsReceiver.hpp
new file mode 100644
index 0000000..fa41cad
--- /dev/null
+++ b/include/distortos/SignalsReceiver.hpp
@@ -0,0 +1,58 @@
+/**
+ * \file
+ * \brief SignalsReceiver 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_SIGNALSRECEIVER_HPP_
+#define INCLUDE_DISTORTOS_SIGNALSRECEIVER_HPP_
+
+#include "distortos/internal/synchronization/SignalsReceiverControlBlock.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class ThreadControlBlock;
+
+} // namespace internal
+
+/// SignalsReceiver class is a container for internal::SignalsReceiverControlBlock
+class SignalsReceiver
+{
+ friend class internal::ThreadControlBlock;
+
+public:
+
+ /**
+ * \brief SignalsReceiver's constructor
+ *
+ * \param [in] signalInformationQueueWrapper is a pointer to SignalInformationQueueWrapper for this receiver,
+ * nullptr to disable queuing of signals for this receiver
+ * \param [in] signalsCatcher is a pointer to SignalsCatcher for this receiver, nullptr if this receiver cannot
+ * catch/handle signals
+ */
+
+ explicit SignalsReceiver(SignalInformationQueueWrapper* const signalInformationQueueWrapper,
+ SignalsCatcher* const signalsCatcher) :
+ signalsReceiverControlBlock_{signalInformationQueueWrapper, signalsCatcher}
+ {
+
+ }
+
+private:
+
+ /// contained internal::SignalsReceiverControlBlock object
+ internal::SignalsReceiverControlBlock signalsReceiverControlBlock_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_SIGNALSRECEIVER_HPP_
diff --git a/include/distortos/SoftwareTimer.hpp b/include/distortos/SoftwareTimer.hpp
new file mode 100644
index 0000000..c10060c
--- /dev/null
+++ b/include/distortos/SoftwareTimer.hpp
@@ -0,0 +1,130 @@
+/**
+ * \file
+ * \brief SoftwareTimer 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_SOFTWARETIMER_HPP_
+#define INCLUDE_DISTORTOS_SOFTWARETIMER_HPP_
+
+#include "distortos/TickClock.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief SoftwareTimer class is an abstract interface for software timers
+ *
+ * \ingroup softwareTimers
+ */
+
+class SoftwareTimer
+{
+public:
+
+ /**
+ * \brief SoftwareTimer's destructor
+ */
+
+ virtual ~SoftwareTimer() = 0;
+
+ /**
+ * \return true if the timer is running, false otherwise
+ */
+
+ virtual bool isRunning() const = 0;
+
+ /**
+ * \brief Starts the timer.
+ *
+ * \note The duration will never be shorter, so one additional tick is always added to the duration.
+ *
+ * \param [in] duration is the duration after which the function will be executed
+ *
+ * \return 0 on success, error code otherwise
+ */
+
+ int start(TickClock::duration duration);
+
+ /**
+ * \brief Starts the timer.
+ *
+ * \note The duration must not be shorter, so one additional tick is always added to the duration.
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the function will be executed
+ *
+ * \return 0 on success, error code otherwise
+ */
+
+ template<typename Rep, typename Period>
+ int start(const std::chrono::duration<Rep, Period> duration)
+ {
+ return start(std::chrono::duration_cast<TickClock::duration>(duration));
+ }
+
+ /**
+ * \brief Starts the timer.
+ *
+ * \param [in] timePoint is the time point at which the function will be executed
+ *
+ * \return 0 on success, error code otherwise
+ */
+
+ virtual int start(TickClock::time_point timePoint) = 0;
+
+ /**
+ * \brief Starts the timer.
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the function will be executed
+ *
+ * \return 0 on success, error code otherwise
+ */
+
+ template<typename Duration>
+ int start(const std::chrono::time_point<TickClock, Duration> timePoint)
+ {
+ return start(std::chrono::time_point_cast<TickClock::duration>(timePoint));
+ }
+
+ /**
+ * \brief Stops the timer.
+ *
+ * \return 0 on success, error code otherwise
+ */
+
+ virtual int stop() = 0;
+
+protected:
+
+ /**
+ * \brief Software timer's function runner
+ *
+ * \param [in] softwareTimer is a reference to SoftwareTimer object that is being run
+ */
+
+ static void softwareTimerRunner(SoftwareTimer& softwareTimer);
+
+private:
+
+ /**
+ * \brief "Run" function of software timer
+ *
+ * This should be overridden by derived classes.
+ */
+
+ virtual void run() = 0;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_SOFTWARETIMER_HPP_
diff --git a/include/distortos/SoftwareTimerCommon.hpp b/include/distortos/SoftwareTimerCommon.hpp
new file mode 100644
index 0000000..636a264
--- /dev/null
+++ b/include/distortos/SoftwareTimerCommon.hpp
@@ -0,0 +1,87 @@
+/**
+ * \file
+ * \brief SoftwareTimerCommon 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_SOFTWARETIMERCOMMON_HPP_
+#define INCLUDE_DISTORTOS_SOFTWARETIMERCOMMON_HPP_
+
+#include "distortos/SoftwareTimer.hpp"
+
+#include "distortos/internal/scheduler/SoftwareTimerControlBlock.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief SoftwareTimerCommon class implements common functionality of software timers
+ *
+ * \ingroup softwareTimers
+ */
+
+class SoftwareTimerCommon : public SoftwareTimer
+{
+public:
+
+ /**
+ * \brief SoftwareTimerCommon's constructor
+ */
+
+ constexpr SoftwareTimerCommon() :
+ softwareTimerControlBlock_{softwareTimerRunner, *this}
+ {
+
+ }
+
+ /**
+ * \brief SoftwareTimerCommon's destructor
+ */
+
+ ~SoftwareTimerCommon() override;
+
+ /**
+ * \return true if the timer is running, false otherwise
+ */
+
+ bool isRunning() const override;
+
+ /**
+ * \brief Starts the timer.
+ *
+ * \param [in] timePoint is the time point at which the function will be executed
+ *
+ * \return 0 on success, error code otherwise
+ */
+
+ int start(TickClock::time_point timePoint) override;
+
+ using SoftwareTimer::start;
+
+ /**
+ * \brief Stops the timer.
+ *
+ * \return 0 on success, error code otherwise
+ */
+
+ int stop() override;
+
+ SoftwareTimerCommon(const SoftwareTimerCommon&) = delete;
+ SoftwareTimerCommon(SoftwareTimerCommon&&) = default;
+ const SoftwareTimerCommon& operator=(const SoftwareTimerCommon&) = delete;
+ SoftwareTimerCommon& operator=(SoftwareTimerCommon&&) = delete;
+
+private:
+
+ /// internal SoftwareTimerControlBlock object
+ internal::SoftwareTimerControlBlock softwareTimerControlBlock_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_SOFTWARETIMERCOMMON_HPP_
diff --git a/include/distortos/StaticFifoQueue.hpp b/include/distortos/StaticFifoQueue.hpp
new file mode 100644
index 0000000..63bb636
--- /dev/null
+++ b/include/distortos/StaticFifoQueue.hpp
@@ -0,0 +1,57 @@
+/**
+ * \file
+ * \brief StaticFifoQueue 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_STATICFIFOQUEUE_HPP_
+#define INCLUDE_DISTORTOS_STATICFIFOQUEUE_HPP_
+
+#include "FifoQueue.hpp"
+
+#include "distortos/internal/memory/dummyDeleter.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief StaticFifoQueue class is a variant of FifoQueue that has automatic storage for queue's contents.
+ *
+ * \tparam T is the type of data in queue
+ * \tparam QueueSize is the maximum number of elements in queue
+ *
+ * \ingroup queues
+ */
+
+template<typename T, size_t QueueSize>
+class StaticFifoQueue : public FifoQueue<T>
+{
+public:
+
+ /// import Storage type from base class
+ using typename FifoQueue<T>::Storage;
+
+ /**
+ * \brief StaticFifoQueue's constructor
+ */
+
+ explicit StaticFifoQueue() :
+ FifoQueue<T>{{storage_.data(), internal::dummyDeleter<Storage>}, storage_.size()}
+ {
+
+ }
+
+private:
+
+ /// storage for queue's contents
+ std::array<Storage, QueueSize> storage_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_STATICFIFOQUEUE_HPP_
diff --git a/include/distortos/StaticMessageQueue.hpp b/include/distortos/StaticMessageQueue.hpp
new file mode 100644
index 0000000..ed370d0
--- /dev/null
+++ b/include/distortos/StaticMessageQueue.hpp
@@ -0,0 +1,64 @@
+/**
+ * \file
+ * \brief StaticMessageQueue 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_STATICMESSAGEQUEUE_HPP_
+#define INCLUDE_DISTORTOS_STATICMESSAGEQUEUE_HPP_
+
+#include "MessageQueue.hpp"
+
+#include "distortos/internal/memory/dummyDeleter.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief StaticMessageQueue class is a variant of MessageQueue that has automatic storage for queue's contents.
+ *
+ * \tparam T is the type of data in queue
+ * \tparam QueueSize is the maximum number of elements in queue
+ *
+ * \ingroup queues
+ */
+
+template<typename T, size_t QueueSize>
+class StaticMessageQueue : public MessageQueue<T>
+{
+public:
+
+ /// import EntryStorage type from base class
+ using typename MessageQueue<T>::EntryStorage;
+
+ /// import ValueStorage type from base class
+ using typename MessageQueue<T>::ValueStorage;
+
+ /**
+ * \brief StaticMessageQueue's constructor
+ */
+
+ explicit StaticMessageQueue() :
+ MessageQueue<T>{{entryStorage_.data(), internal::dummyDeleter<EntryStorage>},
+ {valueStorage_.data(), internal::dummyDeleter<ValueStorage>}, valueStorage_.size()}
+ {
+
+ }
+
+private:
+
+ /// storage for queue's entries
+ std::array<EntryStorage, QueueSize> entryStorage_;
+
+ /// storage for queue's contents
+ std::array<ValueStorage, QueueSize> valueStorage_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_STATICMESSAGEQUEUE_HPP_
diff --git a/include/distortos/StaticRawFifoQueue.hpp b/include/distortos/StaticRawFifoQueue.hpp
new file mode 100644
index 0000000..a271020
--- /dev/null
+++ b/include/distortos/StaticRawFifoQueue.hpp
@@ -0,0 +1,69 @@
+/**
+ * \file
+ * \brief StaticRawFifoQueue 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_STATICRAWFIFOQUEUE_HPP_
+#define INCLUDE_DISTORTOS_STATICRAWFIFOQUEUE_HPP_
+
+#include "RawFifoQueue.hpp"
+
+#include "distortos/internal/memory/dummyDeleter.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief StaticRawFifoQueue class is a variant of RawFifoQueue that has automatic storage for queue's contents.
+ *
+ * \tparam T is the type of data in queue
+ * \tparam QueueSize is the maximum number of elements in queue
+ *
+ * \ingroup queues
+ */
+
+template<typename T, size_t QueueSize>
+class StaticRawFifoQueue : public RawFifoQueue
+{
+public:
+
+ /// type of uninitialized storage for data
+ using Storage = typename std::aligned_storage<sizeof(T), alignof(T)>::type;
+
+ /**
+ * \brief StaticRawFifoQueue's constructor
+ */
+
+ explicit StaticRawFifoQueue() :
+ RawFifoQueue{{storage_.data(), internal::dummyDeleter<Storage>}, sizeof(*storage_.data()), storage_.size()}
+ {
+
+ }
+
+private:
+
+ /// storage for queue's contents
+ std::array<Storage, QueueSize> storage_;
+};
+
+/**
+ * \brief StaticRawFifoQueueFromSize type alias is a variant of StaticRawFifoQueue which uses size of element (instead
+ * of type) as template argument.
+ *
+ * \tparam ElementSize is the size of single queue element, bytes
+ * \tparam QueueSize is the maximum number of elements in queue
+ */
+
+template<size_t ElementSize, size_t QueueSize>
+using StaticRawFifoQueueFromSize =
+ StaticRawFifoQueue<typename std::aligned_storage<ElementSize, ElementSize>::type, QueueSize>;
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_STATICRAWFIFOQUEUE_HPP_
diff --git a/include/distortos/StaticRawMessageQueue.hpp b/include/distortos/StaticRawMessageQueue.hpp
new file mode 100644
index 0000000..8120d17
--- /dev/null
+++ b/include/distortos/StaticRawMessageQueue.hpp
@@ -0,0 +1,71 @@
+/**
+ * \file
+ * \brief StaticRawMessageQueue 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_STATICRAWMESSAGEQUEUE_HPP_
+#define INCLUDE_DISTORTOS_STATICRAWMESSAGEQUEUE_HPP_
+
+#include "distortos/RawMessageQueue.hpp"
+
+#include "distortos/internal/memory/dummyDeleter.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief StaticRawMessageQueue class is a variant of RawMessageQueue that has automatic storage for queue's contents.
+ *
+ * \tparam T is the type of data in queue
+ * \tparam QueueSize is the maximum number of elements in queue
+ *
+ * \ingroup queues
+ */
+
+template<typename T, size_t QueueSize>
+class StaticRawMessageQueue : public RawMessageQueue
+{
+public:
+
+ /**
+ * \brief StaticRawMessageQueue's constructor
+ */
+
+ explicit StaticRawMessageQueue() :
+ RawMessageQueue{{entryStorage_.data(), internal::dummyDeleter<EntryStorage>},
+ {valueStorage_.data(), internal::dummyDeleter<ValueStorage<T>>}, sizeof(*valueStorage_.data()),
+ valueStorage_.size()}
+ {
+
+ }
+
+private:
+
+ /// storage for queue's entries
+ std::array<EntryStorage, QueueSize> entryStorage_;
+
+ /// storage for queue's contents
+ std::array<ValueStorage<T>, QueueSize> valueStorage_;
+};
+
+/**
+ * \brief StaticRawMessageQueueFromSize type alias is a variant of StaticRawMessageQueue which uses size of element
+ * (instead of type) as template argument.
+ *
+ * \tparam ElementSize is the size of single queue element, bytes
+ * \tparam QueueSize is the maximum number of elements in queue
+ */
+
+template<size_t ElementSize, size_t QueueSize>
+using StaticRawMessageQueueFromSize =
+ StaticRawMessageQueue<typename std::aligned_storage<ElementSize, ElementSize>::type, QueueSize>;
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_STATICRAWMESSAGEQUEUE_HPP_
diff --git a/include/distortos/StaticSignalsReceiver.hpp b/include/distortos/StaticSignalsReceiver.hpp
new file mode 100644
index 0000000..a6894ab
--- /dev/null
+++ b/include/distortos/StaticSignalsReceiver.hpp
@@ -0,0 +1,166 @@
+/**
+ * \file
+ * \brief StaticSignalsReceiver 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_STATICSIGNALSRECEIVER_HPP_
+#define INCLUDE_DISTORTOS_STATICSIGNALSRECEIVER_HPP_
+
+#include "distortos/SignalInformationQueueWrapper.hpp"
+#include "distortos/SignalsCatcher.hpp"
+#include "distortos/SignalsReceiver.hpp"
+
+#include "distortos/internal/memory/dummyDeleter.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief StaticSignalsReceiver class is a templated interface for SignalsReceiver that has automatic storage for queued
+ * signals and SignalAction associations required for catching signals.
+ *
+ * \tparam QueuedSignals is the max number of queued signals, 0 to disable queuing of signals for this receiver
+ * \tparam SignalActions is the max number of different SignalAction objects, 0 to disable catching of signals for this
+ * receiver
+ */
+
+template<size_t QueuedSignals, size_t SignalActions>
+class StaticSignalsReceiver : public SignalsReceiver
+{
+public:
+
+ /**
+ * \brief StaticSignalsReceiver's constructor
+ */
+
+ StaticSignalsReceiver() :
+ SignalsReceiver{&signalInformationQueueWrapper_, &signalsCatcher_},
+ signalInformationQueueWrapper_{{signalInformationQueueWrapperStorage_.data(),
+ internal::dummyDeleter<SignalInformationQueueWrapper::Storage>},
+ signalInformationQueueWrapperStorage_.size()},
+ signalsCatcher_{{signalsCatcherStorage_.data(), internal::dummyDeleter<SignalsCatcher::Storage>},
+ signalsCatcherStorage_.size()}
+ {
+
+ }
+
+private:
+
+ /// storage for \a signalInformationQueueWrapper_
+ std::array<SignalInformationQueueWrapper::Storage, QueuedSignals> signalInformationQueueWrapperStorage_;
+
+ /// internal SignalInformationQueueWrapper object
+ SignalInformationQueueWrapper signalInformationQueueWrapper_;
+
+ /// storage for \a signalsCatcher_
+ std::array<SignalsCatcher::Storage, SignalActions> signalsCatcherStorage_;
+
+ /// internal SignalsCatcher object
+ SignalsCatcher signalsCatcher_;
+};
+
+/**
+ * \brief StaticSignalsReceiver class is a templated interface for SignalsReceiver that has automatic storage for queued
+ * signals and SignalAction associations required for catching signals.
+ *
+ * \tparam QueuedSignals is the max number of queued signals
+ *
+ * Specialization for receiver with enabled queuing (QueuedSignals != 0) and disabled catching (SignalActions == 0) of
+ * signals
+ */
+
+template<size_t QueuedSignals>
+class StaticSignalsReceiver<QueuedSignals, 0> : public SignalsReceiver
+{
+public:
+
+ /**
+ * \brief StaticSignalsReceiver's constructor
+ */
+
+ StaticSignalsReceiver() :
+ SignalsReceiver{&signalInformationQueueWrapper_, nullptr},
+ signalInformationQueueWrapper_{{signalInformationQueueWrapperStorage_.data(),
+ internal::dummyDeleter<SignalInformationQueueWrapper::Storage>},
+ signalInformationQueueWrapperStorage_.size()}
+ {
+
+ }
+
+private:
+
+ /// storage for \a signalInformationQueueWrapper_
+ std::array<SignalInformationQueueWrapper::Storage, QueuedSignals> signalInformationQueueWrapperStorage_;
+
+ /// internal SignalInformationQueueWrapper object
+ SignalInformationQueueWrapper signalInformationQueueWrapper_;
+};
+
+/**
+ * \brief StaticSignalsReceiver class is a templated interface for SignalsReceiver that has automatic storage for queued
+ * signals and SignalAction associations required for catching signals.
+ *
+ * \tparam SignalActions is the max number of different SignalAction objects
+ *
+ * Specialization for receiver with disabled queuing (QueuedSignals == 0) and enabled catching (SignalActions != 0) of
+ * signals
+ */
+
+template<size_t SignalActions>
+class StaticSignalsReceiver<0, SignalActions> : public SignalsReceiver
+{
+public:
+
+ /**
+ * \brief StaticSignalsReceiver's constructor
+ */
+
+ StaticSignalsReceiver() :
+ SignalsReceiver{nullptr, &signalsCatcher_},
+ signalsCatcher_{{signalsCatcherStorage_.data(), internal::dummyDeleter<SignalsCatcher::Storage>},
+ signalsCatcherStorage_.size()}
+ {
+
+ }
+
+private:
+
+ /// storage for \a signalsCatcher_
+ std::array<SignalsCatcher::Storage, SignalActions> signalsCatcherStorage_;
+
+ /// internal SignalsCatcher object
+ SignalsCatcher signalsCatcher_;
+};
+
+/**
+ * \brief StaticSignalsReceiver class is a templated interface for SignalsReceiver that has automatic storage for queued
+ * signals and SignalAction associations required for catching signals.
+ *
+ * Specialization for receiver with disabled queuing (QueuedSignals == 0) and catching (SignalActions == 0) of signals
+ */
+
+template<>
+class StaticSignalsReceiver<0, 0> : public SignalsReceiver
+{
+public:
+
+ /**
+ * \brief StaticSignalsReceiver's constructor
+ */
+
+ StaticSignalsReceiver() :
+ SignalsReceiver{nullptr, nullptr}
+ {
+
+ }
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_STATICSIGNALSRECEIVER_HPP_
diff --git a/include/distortos/StaticSoftwareTimer.hpp b/include/distortos/StaticSoftwareTimer.hpp
new file mode 100644
index 0000000..e1c27f7
--- /dev/null
+++ b/include/distortos/StaticSoftwareTimer.hpp
@@ -0,0 +1,90 @@
+/**
+ * \file
+ * \brief StaticSoftwareTimer 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_STATICSOFTWARETIMER_HPP_
+#define INCLUDE_DISTORTOS_STATICSOFTWARETIMER_HPP_
+
+#include "distortos/SoftwareTimerCommon.hpp"
+
+#include <functional>
+
+namespace distortos
+{
+
+/// \addtogroup softwareTimers
+/// \{
+
+/**
+ * \brief StaticSoftwareTimer class is a templated interface for software timer
+ *
+ * \tparam Function is the function that will be executed
+ * \tparam Args are the arguments for function
+ */
+
+template<typename Function, typename... Args>
+class StaticSoftwareTimer : public SoftwareTimerCommon
+{
+public:
+
+ /**
+ * \brief StaticSoftwareTimer's constructor
+ *
+ * \param [in] function is a function that will be executed from interrupt context at a later time
+ * \param [in] args are arguments for function
+ */
+
+ StaticSoftwareTimer(Function&& function, Args&&... args) :
+ SoftwareTimerCommon{},
+ boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)}
+ {
+
+ }
+
+private:
+
+ /**
+ * \brief "Run" function of software timer
+ *
+ * Executes bound function object.
+ */
+
+ void run() override
+ {
+ boundFunction_();
+ }
+
+ /// bound function object
+ decltype(std::bind(std::declval<Function>(), std::declval<Args>()...)) boundFunction_;
+};
+
+/**
+ * \brief Helper factory function to make StaticSoftwareTimer object with deduced template arguments
+ *
+ * \tparam Function is the function that will be executed
+ * \tparam Args are the arguments for function
+ *
+ * \param [in] function is a function that will be executed from interrupt context at a later time
+ * \param [in] args are arguments for function
+ *
+ * \return StaticSoftwareTimer object with deduced template arguments
+ */
+
+template<typename Function, typename... Args>
+StaticSoftwareTimer<Function, Args...> makeStaticSoftwareTimer(Function&& function, Args&&... args)
+{
+ return {std::forward<Function>(function), std::forward<Args>(args)...};
+}
+
+/// \}
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_STATICSOFTWARETIMER_HPP_
diff --git a/include/distortos/StaticThread.hpp b/include/distortos/StaticThread.hpp
new file mode 100644
index 0000000..c135e55
--- /dev/null
+++ b/include/distortos/StaticThread.hpp
@@ -0,0 +1,357 @@
+/**
+ * \file
+ * \brief StaticThread 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_STATICTHREAD_HPP_
+#define INCLUDE_DISTORTOS_STATICTHREAD_HPP_
+
+#include "distortos/StaticSignalsReceiver.hpp"
+#include "distortos/UndetachableThread.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/**
+ * \brief StaticThreadBase class is a templated common base for StaticThread
+ *
+ * \tparam Function is the function that will be executed in separate thread
+ * \tparam Args are the arguments for \a Function
+ */
+
+template<typename Function, typename... Args>
+class StaticThreadBase : public UndetachableThread
+{
+public:
+
+ /// base of StaticThreadBase
+ using Base = UndetachableThread;
+
+ /**
+ * \brief StaticThreadBase's constructor
+ *
+ * \param [in] stackStorageUniquePointer is a rvalue reference to StackStorageUniquePointer with storage for stack
+ * (\a size bytes long) and appropriate deleter
+ * \param [in] size is the size of stack's storage, bytes
+ * \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] signalsReceiver is a pointer to SignalsReceiver object for this thread, nullptr to disable reception
+ * of signals for this thread
+ * \param [in] function is a function that will be executed in separate thread
+ * \param [in] args are arguments for function
+ */
+
+ StaticThreadBase(StackStorageUniquePointer&& stackStorageUniquePointer, const size_t size, const uint8_t priority,
+ const SchedulingPolicy schedulingPolicy, SignalsReceiver* const signalsReceiver, Function&& function,
+ Args&&... args) :
+ Base{{std::move(stackStorageUniquePointer), size, *this, run, nullptr, terminationHook},
+ priority, schedulingPolicy, nullptr, signalsReceiver},
+ boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)}
+ {
+
+ }
+
+ StaticThreadBase(const StaticThreadBase&) = delete;
+ StaticThreadBase(StaticThreadBase&&) = default;
+ const StaticThreadBase& operator=(const StaticThreadBase&) = delete;
+ StaticThreadBase& operator=(StaticThreadBase&&) = delete;
+
+private:
+
+ /**
+ * \brief Thread's "run" function.
+ *
+ * Executes bound function object.
+ *
+ * \param [in] thread is a reference to Thread object, this must be StaticThreadBase!
+ */
+
+ static void run(Thread& thread)
+ {
+ static_cast<StaticThreadBase&>(thread).boundFunction_();
+ }
+
+ /// bound function object
+ decltype(std::bind(std::declval<Function>(), std::declval<Args>()...)) boundFunction_;
+};
+
+} // namespace internal
+
+/// \addtogroup threads
+/// \{
+
+/**
+ * \brief StaticThread class is a templated interface for thread that has automatic storage for stack.
+ *
+ * \tparam StackSize is the size of stack, bytes
+ * \tparam CanReceiveSignals selects whether reception of signals is enabled (true) or disabled (false) for this thread
+ * \tparam QueuedSignals is the max number of queued signals for this thread, relevant only if
+ * CanReceiveSignals == true, 0 to disable queuing of signals for this thread
+ * \tparam SignalActions is the max number of different SignalAction objects for this thread, relevant only if
+ * CanReceiveSignals == true, 0 to disable catching of signals for this thread
+ * \tparam Function is the function that will be executed in separate thread
+ * \tparam Args are the arguments for \a Function
+ */
+
+template<size_t StackSize, bool CanReceiveSignals, size_t QueuedSignals, size_t SignalActions, typename Function,
+ typename... Args>
+class StaticThread : public internal::StaticThreadBase<Function, Args...>
+{
+public:
+
+ /// base of StaticThread
+ using Base = internal::StaticThreadBase<Function, Args...>;
+
+ /**
+ * \brief StaticThread's constructor
+ *
+ * \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 function
+ */
+
+ StaticThread(uint8_t priority, SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args);
+
+ /**
+ * \brief StaticThread's constructor
+ *
+ * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
+ * \param [in] function is a function that will be executed in separate thread
+ * \param [in] args are arguments for function
+ */
+
+ StaticThread(const uint8_t priority, Function&& function, Args&&... args) :
+ StaticThread{priority, SchedulingPolicy::roundRobin, std::forward<Function>(function),
+ std::forward<Args>(args)...}
+ {
+
+ }
+
+ StaticThread(const StaticThread&) = delete;
+ StaticThread(StaticThread&&) = default;
+ const StaticThread& operator=(const StaticThread&) = delete;
+ StaticThread& operator=(StaticThread&&) = delete;
+
+private:
+
+ /// stack buffer
+ typename std::aligned_storage<StackSize>::type stack_;
+};
+
+/**
+ * \brief StaticThread class is a templated interface for thread that has automatic storage for stack and internal
+ * StaticSignalsReceiver object.
+ *
+ * Specialization for threads with enabled reception of signals (CanReceiveSignals == true)
+ *
+ * \tparam StackSize is the size of stack, bytes
+ * \tparam QueuedSignals is the max number of queued signals for this thread, 0 to disable queuing of signals for this
+ * thread
+ * \tparam SignalActions is the max number of different SignalAction objects for this thread, relevant only if
+ * CanReceiveSignals == true, 0 to disable catching of signals for this thread
+ * \tparam Function is the function that will be executed in separate thread
+ * \tparam Args are the arguments for \a Function
+ */
+
+template<size_t StackSize, size_t QueuedSignals, size_t SignalActions, typename Function, typename... Args>
+class StaticThread<StackSize, true, QueuedSignals, SignalActions, Function, Args...> :
+ public internal::StaticThreadBase<Function, Args...>
+{
+public:
+
+ /// base of StaticThread
+ using Base = internal::StaticThreadBase<Function, Args...>;
+
+ /**
+ * \brief StaticThread's constructor
+ *
+ * \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 function
+ */
+
+ StaticThread(uint8_t priority, SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args);
+
+ /**
+ * \brief StaticThread's constructor
+ *
+ * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
+ * \param [in] function is a function that will be executed in separate thread
+ * \param [in] args are arguments for function
+ */
+
+ StaticThread(const uint8_t priority, Function&& function, Args&&... args) :
+ StaticThread{priority, SchedulingPolicy::roundRobin, std::forward<Function>(function),
+ std::forward<Args>(args)...}
+ {
+
+ }
+
+ StaticThread(const StaticThread&) = delete;
+ StaticThread(StaticThread&&) = default;
+ const StaticThread& operator=(const StaticThread&) = delete;
+ StaticThread& operator=(StaticThread&&) = delete;
+
+private:
+
+ /// stack buffer
+ typename std::aligned_storage<StackSize>::type stack_;
+
+ /// internal StaticSignalsReceiver object
+ StaticSignalsReceiver<QueuedSignals, SignalActions> staticSignalsReceiver_;
+};
+
+/**
+ * \brief Helper factory function to make StaticThread object with partially deduced template arguments
+ *
+ * \tparam StackSize is the size of stack, bytes
+ * \tparam CanReceiveSignals selects whether reception of signals is enabled (true) or disabled (false) for this thread
+ * \tparam QueuedSignals is the max number of queued signals for this thread, relevant only if
+ * CanReceiveSignals == true, 0 to disable queuing of signals for this thread
+ * \tparam SignalActions is the max number of different SignalAction objects for this thread, relevant only if
+ * CanReceiveSignals == true, 0 to disable catching of signals for this thread
+ * \tparam Function is the function that will be executed
+ * \tparam Args are the arguments for \a Function
+ *
+ * \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 function
+ *
+ * \return StaticThread object with partially deduced template arguments
+ */
+
+template<size_t StackSize, bool CanReceiveSignals = {}, size_t QueuedSignals = {}, size_t SignalActions = {},
+ typename Function, typename... Args>
+StaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions, Function, Args...>
+makeStaticThread(const uint8_t priority, const SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args)
+{
+ return {priority, schedulingPolicy, std::forward<Function>(function), std::forward<Args>(args)...};
+}
+
+/**
+ * \brief Helper factory function to make StaticThread object with partially deduced template arguments
+ *
+ * \tparam StackSize is the size of stack, bytes
+ * \tparam CanReceiveSignals selects whether reception of signals is enabled (true) or disabled (false) for this thread
+ * \tparam QueuedSignals is the max number of queued signals for this thread, relevant only if
+ * CanReceiveSignals == true, 0 to disable queuing of signals for this thread
+ * \tparam SignalActions is the max number of different SignalAction objects for this thread, relevant only if
+ * CanReceiveSignals == true, 0 to disable catching of signals for this thread
+ * \tparam Function is the function that will be executed
+ * \tparam Args are the arguments for \a Function
+ *
+ * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
+ * \param [in] function is a function that will be executed in separate thread
+ * \param [in] args are arguments for function
+ *
+ * \return StaticThread object with partially deduced template arguments
+ */
+
+template<size_t StackSize, bool CanReceiveSignals = {}, size_t QueuedSignals = {}, size_t SignalActions = {},
+ typename Function, typename... Args>
+StaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions, Function, Args...>
+makeStaticThread(const uint8_t priority, Function&& function, Args&&... args)
+{
+ return {priority, std::forward<Function>(function), std::forward<Args>(args)...};
+}
+
+/**
+ * \brief Helper factory function to make and start StaticThread object with partially deduced template arguments
+ *
+ * \tparam StackSize is the size of stack, bytes
+ * \tparam CanReceiveSignals selects whether reception of signals is enabled (true) or disabled (false) for this thread
+ * \tparam QueuedSignals is the max number of queued signals for this thread, relevant only if
+ * CanReceiveSignals == true, 0 to disable queuing of signals for this thread
+ * \tparam SignalActions is the max number of different SignalAction objects for this thread, relevant only if
+ * CanReceiveSignals == true, 0 to disable catching of signals for this thread
+ * \tparam Function is the function that will be executed
+ * \tparam Args are the arguments for \a Function
+ *
+ * \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 function
+ *
+ * \return StaticThread object with partially deduced template arguments
+ */
+
+template<size_t StackSize, bool CanReceiveSignals = {}, size_t QueuedSignals = {}, size_t SignalActions = {},
+ typename Function, typename... Args>
+StaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions, Function, Args...>
+makeAndStartStaticThread(const uint8_t priority, const SchedulingPolicy schedulingPolicy, Function&& function,
+ Args&&... args)
+{
+ auto thread = makeStaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions>(priority,
+ schedulingPolicy, std::forward<Function>(function), std::forward<Args>(args)...);
+ thread.start(); /// \todo make sure this never fails
+ return thread;
+}
+
+/**
+ * \brief Helper factory function to make and start StaticThread object with partially deduced template arguments
+ *
+ * \tparam StackSize is the size of stack, bytes
+ * \tparam CanReceiveSignals selects whether reception of signals is enabled (true) or disabled (false) for this thread
+ * \tparam QueuedSignals is the max number of queued signals for this thread, relevant only if
+ * CanReceiveSignals == true, 0 to disable queuing of signals for this thread
+ * \tparam SignalActions is the max number of different SignalAction objects for this thread, relevant only if
+ * CanReceiveSignals == true, 0 to disable catching of signals for this thread
+ * \tparam Function is the function that will be executed
+ * \tparam Args are the arguments for \a Function
+ *
+ * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
+ * \param [in] function is a function that will be executed in separate thread
+ * \param [in] args are arguments for function
+ *
+ * \return StaticThread object with partially deduced template arguments
+ */
+
+template<size_t StackSize, bool CanReceiveSignals = {}, size_t QueuedSignals = {}, size_t SignalActions = {},
+ typename Function, typename... Args>
+StaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions, Function, Args...>
+makeAndStartStaticThread(const uint8_t priority, Function&& function, Args&&... args)
+{
+ auto thread = makeStaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions>(priority,
+ std::forward<Function>(function), std::forward<Args>(args)...);
+ thread.start(); /// \todo make sure this never fails
+ return thread;
+}
+
+/// \}
+
+template<size_t StackSize, bool CanReceiveSignals, size_t QueuedSignals, size_t SignalActions, typename Function,
+ typename... Args>
+StaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions, Function, Args...>::
+StaticThread(const uint8_t priority, const SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args) :
+ Base{{&stack_, internal::dummyDeleter<decltype(stack_)>}, sizeof(stack_), priority, schedulingPolicy, nullptr,
+ std::forward<Function>(function), std::forward<Args>(args)...}
+{
+
+}
+
+template<size_t StackSize, size_t QueuedSignals, size_t SignalActions, typename Function, typename... Args>
+StaticThread<StackSize, true, QueuedSignals, SignalActions, Function, Args...>::StaticThread(const uint8_t priority,
+ const SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args) :
+ Base{{&stack_, internal::dummyDeleter<decltype(stack_)>}, sizeof(stack_), priority, schedulingPolicy,
+ &static_cast<SignalsReceiver&>(staticSignalsReceiver_), std::forward<Function>(function),
+ std::forward<Args>(args)...},
+ staticSignalsReceiver_{}
+{
+
+}
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_STATICTHREAD_HPP_
diff --git a/include/distortos/ThisThread-Signals.hpp b/include/distortos/ThisThread-Signals.hpp
new file mode 100644
index 0000000..b0a808d
--- /dev/null
+++ b/include/distortos/ThisThread-Signals.hpp
@@ -0,0 +1,279 @@
+/**
+ * \file
+ * \brief ThisThread::Signals namespace 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_THISTHREAD_SIGNALS_HPP_
+#define INCLUDE_DISTORTOS_THISTHREAD_SIGNALS_HPP_
+
+#include "distortos/SignalInformation.hpp"
+#include "distortos/TickClock.hpp"
+
+#include <utility>
+
+#include <cstdint>
+
+namespace distortos
+{
+
+class SignalAction;
+class SignalSet;
+
+namespace ThisThread
+{
+
+namespace Signals
+{
+
+/// \addtogroup signals
+/// \{
+
+/**
+ * \brief Generates signal for current thread.
+ *
+ * Similar to raise() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html
+ *
+ * Adds the signalNumber to set of pending signals of current thread.
+ *
+ * \param [in] signalNumber is the signal that will be generated, [0; 31]
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - reception of signals is disabled for current thread;
+ */
+
+int generateSignal(uint8_t signalNumber);
+
+/**
+ * \brief Gets set of currently pending signals for current thread.
+ *
+ * Similar to sigpending() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpending.html
+ *
+ * This function shall return the set of signals that are blocked from delivery and are pending on the current thread.
+ *
+ * \return set of currently pending signals for current thread
+ */
+
+SignalSet getPendingSignalSet();
+
+/**
+ * \brief Gets SignalAction associated with given signal number.
+ *
+ * Similar to sigaction() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html
+ *
+ * \param [in] signalNumber is the signal for which the association is requested, [0; 31]
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalAction that is associated with
+ * \a signalNumber, default-constructed object if no association was found;
+ * error codes:
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - reception or catching/handling of signals are disabled for current thread;
+ */
+
+std::pair<int, SignalAction> getSignalAction(uint8_t signalNumber);
+
+/**
+ * \brief Gets signal mask for current thread.
+ *
+ * Similar to pthread_sigmask() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html#
+ *
+ * \return SignalSet with signal mask for current thread
+ */
+
+SignalSet getSignalMask();
+
+/**
+ * \brief Queues signal for current thread.
+ *
+ * Similar to sigqueue() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigqueue.html
+ *
+ * Adds the signalNumber and signal value (sigval union) to queue of SignalInformation objects.
+ *
+ * \param [in] signalNumber is the signal that will be queued, [0; 31]
+ * \param [in] value is the signal value
+ *
+ * \return 0 on success, error code otherwise:
+ * - EAGAIN - no resources are available to queue the signal, maximal number of signals is already queued in
+ * associated queue of SignalInformation objects;
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - reception or queuing of signals are disabled for current thread;
+ */
+
+int queueSignal(uint8_t signalNumber, sigval value);
+
+/**
+ * \brief Sets association for given signal number.
+ *
+ * Similar to sigaction() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html
+ *
+ * \param [in] signalNumber is the signal for which the association will be set, [0; 31]
+ * \param [in] signalAction is a reference to SignalAction that will be associated with given signal number, object in
+ * internal storage is copy-constructed
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalAction that was associated with
+ * \a signalNumber, default-constructed object if no association was found;
+ * error codes:
+ * - EAGAIN - no resources are available to associate \a signalNumber with \a signalAction;
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - reception or catching/handling of signals are disabled for current thread;
+ */
+
+std::pair<int, SignalAction> setSignalAction(uint8_t signalNumber, const SignalAction& signalAction);
+
+/**
+ * \brief Sets signal mask for current thread.
+ *
+ * Similar to pthread_sigmask() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html#
+ *
+ * \param [in] signalMask is the SignalSet with new signal mask for current thread
+ *
+ * \return 0 on success, error code otherwise:
+ * - ENOTSUP - reception or catching/handling of signals are disabled for current thread;
+ */
+
+int setSignalMask(SignalSet signalMask);
+
+/**
+ * \brief Tries to accept pending signals.
+ *
+ * Similar to sigtimedwait() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigtimedwait.html
+ *
+ * This function shall select the lowest pending signal from provided set, atomically clear it from current thread's set
+ * of pending signals and return that signal number. If no signal in provided set is pending at the time of the call,
+ * then this function shall return immediately with an error.
+ *
+ * \param [in] signalSet is a reference to set of signals that may be accepted
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalInformation object for accepted signal;
+ * error codes:
+ * - EAGAIN - no signal specified by \a signalSet was pending;
+ * - ENOTSUP - reception of signals is disabled for current thread;
+ */
+
+std::pair<int, SignalInformation> tryWait(const SignalSet& signalSet);
+
+/**
+ * \brief Tries to wait for signals for given duration of time.
+ *
+ * Similar to sigtimedwait() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigtimedwait.html
+ *
+ * This function shall select the lowest pending signal from provided set, atomically clear it from current thread's set
+ * of pending signals and return that signal number. If no signal in provided set is pending at the time of the call,
+ * the thread shall be suspended until one or more becomes pending or until given duration of time expires.
+ *
+ * \param [in] signalSet is a reference to set of signals that will be waited for
+ * \param [in] duration is the duration after which the wait for signals will be terminated
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalInformation object for accepted signal;
+ * error codes:
+ * - EINTR - the wait was interrupted by an unmasked, caught signal;
+ * - ENOTSUP - reception of signals is disabled for current thread;
+ * - ETIMEDOUT - no signal specified by \a signalSet was generated before the specified \a duration passed;
+ */
+
+std::pair<int, SignalInformation> tryWaitFor(const SignalSet& signalSet, TickClock::duration duration);
+
+/**
+ * \brief Tries to wait for signals for given duration of time.
+ *
+ * Template variant of tryWaitFor(const SignalSet&, TickClock::duration).
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] signalSet is a reference to set of signals that will be waited for
+ * \param [in] duration is the duration after which the wait for signals will be terminated
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalInformation object for accepted signal;
+ * error codes:
+ * - EINTR - the wait was interrupted by an unmasked, caught signal;
+ * - ENOTSUP - reception of signals is disabled for current thread;
+ * - ETIMEDOUT - no signal specified by \a signalSet was generated before the specified \a duration passed;
+ */
+
+template<typename Rep, typename Period>
+std::pair<int, SignalInformation> tryWaitFor(const SignalSet& signalSet,
+ const std::chrono::duration<Rep, Period> duration)
+{
+ return tryWaitFor(signalSet, std::chrono::duration_cast<TickClock::duration>(duration));
+}
+
+/**
+ * \brief Tries to wait for signals until given time point.
+ *
+ * Similar to sigtimedwait() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigtimedwait.html
+ *
+ * This function shall select the lowest pending signal from provided set, atomically clear it from current thread's set
+ * of pending signals and return that signal number. If no signal in provided set is pending at the time of the call,
+ * the thread shall be suspended until one or more becomes pending or until given time point is reached
+ *
+ * \param [in] signalSet is a reference to set of signals that will be waited for
+ * \param [in] timePoint is the time point at which the wait for signals will be terminated
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalInformation object for accepted signal;
+ * error codes:
+ * - EINTR - the wait was interrupted by an unmasked, caught signal;
+ * - ENOTSUP - reception of signals is disabled for current thread;
+ * - ETIMEDOUT - no signal specified by \a signalSet was generated before specified \a timePoint;
+ */
+
+std::pair<int, SignalInformation> tryWaitUntil(const SignalSet& signalSet, TickClock::time_point timePoint);
+
+/**
+ * \brief Tries to wait for signals until given time point.
+ *
+ * Template variant of tryWaitUntil(const SignalSet&, TickClock::time_point).
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] signalSet is a reference to set of signals that will be waited for
+ * \param [in] timePoint is the time point at which the wait for signals will be terminated
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalInformation object for accepted signal;
+ * error codes:
+ * - EINTR - the wait was interrupted by an unmasked, caught signal;
+ * - ENOTSUP - reception of signals is disabled for current thread;
+ * - ETIMEDOUT - no signal specified by \a signalSet was generated before specified \a timePoint;
+ */
+
+template<typename Duration>
+std::pair<int, SignalInformation> tryWaitUntil(const SignalSet& signalSet,
+ const std::chrono::time_point<TickClock, Duration> timePoint)
+{
+ return tryWaitUntil(signalSet, std::chrono::time_point_cast<TickClock::duration>(timePoint));
+}
+
+/**
+ * \brief Waits for signals.
+ *
+ * Similar to sigwait() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigwait.html
+ *
+ * This function shall select the lowest pending signal from provided set, atomically clear it from current thread's set
+ * of pending signals and return that signal number. If no signal in provided set is pending at the time of the call,
+ * the thread shall be suspended until one or more becomes pending.
+ *
+ * \param [in] signalSet is a reference to set of signals that will be waited for
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalInformation object for accepted signal;
+ * error codes:
+ * - EINTR - the wait was interrupted by an unmasked, caught signal;
+ * - ENOTSUP - reception of signals is disabled for current thread;
+ */
+
+std::pair<int, SignalInformation> wait(const SignalSet& signalSet);
+
+/// \}
+
+} // namespace Signals
+
+} // namespace ThisThread
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_THISTHREAD_SIGNALS_HPP_
diff --git a/include/distortos/ThisThread.hpp b/include/distortos/ThisThread.hpp
new file mode 100644
index 0000000..5528412
--- /dev/null
+++ b/include/distortos/ThisThread.hpp
@@ -0,0 +1,158 @@
+/**
+ * \file
+ * \brief ThisThread namespace 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_THISTHREAD_HPP_
+#define INCLUDE_DISTORTOS_THISTHREAD_HPP_
+
+#include "distortos/TickClock.hpp"
+
+namespace distortos
+{
+
+class Thread;
+
+namespace ThisThread
+{
+
+/// \addtogroup threads
+/// \{
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+/**
+ * \brief Detaches calling (current) 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 calling (current) thread from its 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 - current thread is already detached;
+ * - ENOTSUP - current thread cannot be detached;
+ */
+
+int detach();
+
+#endif // def CONFIG_THREAD_DETACH_ENABLE
+
+/**
+ * \return reference to Thread object of currently active thread
+ */
+
+Thread& get();
+
+/**
+ * \return effective priority of calling (current) thread
+ */
+
+uint8_t getEffectivePriority();
+
+/**
+ * \return priority of calling (current) thread
+ */
+
+uint8_t getPriority();
+
+/**
+ * Changes priority of calling (current) thread.
+ *
+ * \param [in] priority is the new priority for 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 = {});
+
+/**
+ * \brief Makes the calling (current) thread sleep for at least given duration.
+ *
+ * Current thread's state is changed to "sleeping".
+ *
+ * \note To fulfill the "at least" requirement, one additional tick is always added to the sleep duration.
+ *
+ * \param [in] duration is the duration after which the thread will be woken
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINTR - the sleep was interrupted by an unmasked, caught signal;
+ */
+
+int sleepFor(TickClock::duration duration);
+
+/**
+ * \brief Makes the calling (current) thread sleep for at least given duration.
+ *
+ * Current thread's state is changed to "sleeping".
+ *
+ * \note To fulfill the "at least" requirement, one additional tick is always added to the sleep duration.
+ *
+ * \tparam Rep is type of tick counter
+ * \tparam Period is std::ratio type representing the tick period of the clock, in seconds
+ *
+ * \param [in] duration is the duration after which the thread will be woken
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINTR - the sleep was interrupted by an unmasked, caught signal;
+ */
+
+template<typename Rep, typename Period>
+int sleepFor(const std::chrono::duration<Rep, Period> duration)
+{
+ return sleepFor(std::chrono::duration_cast<TickClock::duration>(duration));
+}
+
+/**
+ * \brief Makes the calling (current) thread sleep until some time point is reached.
+ *
+ * Current thread's state is changed to "sleeping".
+ *
+ * \param [in] timePoint is the time point at which the thread will be woken
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINTR - the sleep was interrupted by an unmasked, caught signal;
+ */
+
+int sleepUntil(TickClock::time_point timePoint);
+
+/**
+ * \brief Makes the calling (current) thread sleep until some time point is reached.
+ *
+ * Current thread's state is changed to "sleeping".
+ *
+ * \tparam Duration is a std::chrono::duration type used to measure duration
+ *
+ * \param [in] timePoint is the time point at which the thread will be woken
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINTR - the sleep was interrupted by an unmasked, caught signal;
+ */
+
+template<typename Duration>
+int sleepUntil(const std::chrono::time_point<TickClock, Duration> timePoint)
+{
+ return sleepUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint));
+}
+
+/**
+ * \brief Yields time slot of the scheduler to next thread.
+ */
+
+void yield();
+
+/// \}
+
+} // namespace ThisThread
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_THISTHREAD_HPP_
diff --git a/include/distortos/Thread.hpp b/include/distortos/Thread.hpp
new file mode 100644
index 0000000..54139c1
--- /dev/null
+++ b/include/distortos/Thread.hpp
@@ -0,0 +1,194 @@
+/**
+ * \file
+ * \brief Thread 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_THREAD_HPP_
+#define INCLUDE_DISTORTOS_THREAD_HPP_
+
+#include "distortos/distortosConfiguration.h"
+
+#include "distortos/SchedulingPolicy.hpp"
+#include "distortos/SignalSet.hpp"
+#include "distortos/ThreadState.hpp"
+
+#include <csignal>
+
+namespace distortos
+{
+
+/**
+ * \brief Thread class is a pure abstract interface for threads
+ *
+ * \ingroup threads
+ */
+
+class Thread
+{
+public:
+
+ /**
+ * \brief Thread's destructor
+ */
+
+ virtual ~Thread() = 0;
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+ /**
+ * \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;
+ * - ENOTSUP - this thread cannot be detached;
+ */
+
+ virtual int detach() = 0;
+
+#endif // def CONFIG_THREAD_DETACH_ENABLE
+
+ /**
+ * \brief Generates signal for thread.
+ *
+ * Similar to pthread_kill() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html
+ *
+ * Adds the signalNumber to set of pending signals. If this thread is currently waiting for this signal, it will be
+ * unblocked.
+ *
+ * \param [in] signalNumber is the signal that will be generated, [0; 31]
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - reception of signals is disabled for this thread;
+ *
+ * \ingroup signals
+ */
+
+ virtual int generateSignal(uint8_t signalNumber) = 0;
+
+ /**
+ * \return effective priority of thread
+ */
+
+ virtual uint8_t getEffectivePriority() const = 0;
+
+ /**
+ * \brief Gets set of currently pending signals.
+ *
+ * Similar to sigpending() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpending.html
+ *
+ * This function shall return the set of signals that are blocked from delivery and are pending on the thread.
+ *
+ * \return set of currently pending signals
+ *
+ * \ingroup signals
+ */
+
+ virtual SignalSet getPendingSignalSet() const = 0;
+
+ /**
+ * \return priority of thread
+ */
+
+ virtual uint8_t getPriority() const = 0;
+
+ /**
+ * \return scheduling policy of the thread
+ */
+
+ virtual SchedulingPolicy getSchedulingPolicy() const = 0;
+
+ /**
+ * \return current state of thread
+ */
+
+ virtual ThreadState getState() const = 0;
+
+ /**
+ * \brief Waits for thread termination.
+ *
+ * Similar to std::thread::join() - http://en.cppreference.com/w/cpp/thread/thread/join
+ * Similar to POSIX pthread_join() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html
+ *
+ * Blocks current thread until this thread finishes its execution. The results of multiple simultaneous calls to
+ * join() on the same target thread are undefined.
+ *
+ * \return 0 on success, error code otherwise:
+ * - EDEADLK - deadlock condition was detected,
+ * - EINVAL - this thread is not joinable,
+ * - ...
+ *
+ * \ingroup synchronization
+ */
+
+ virtual int join() = 0;
+
+ /**
+ * \brief Queues signal for thread.
+ *
+ * Similar to sigqueue() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigqueue.html
+ *
+ * Adds the signalNumber and signal value (sigval union) to queue of SignalInformation objects. If this thread is
+ * currently waiting for this signal, it will be unblocked.
+ *
+ * \param [in] signalNumber is the signal that will be queued, [0; 31]
+ * \param [in] value is the signal value
+ *
+ * \return 0 on success, error code otherwise:
+ * - EAGAIN - no resources are available to queue the signal, maximal number of signals is already queued in
+ * associated queue of SignalInformation objects;
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - reception or queuing of signals are disabled for this thread;
+ *
+ * \ingroup signals
+ */
+
+ virtual int queueSignal(uint8_t signalNumber, sigval value) = 0;
+
+ /**
+ * \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.
+ */
+
+ virtual void setPriority(uint8_t priority, bool alwaysBehind = {}) = 0;
+
+ /**
+ * param [in] schedulingPolicy is the new scheduling policy of the thread
+ */
+
+ virtual void setSchedulingPolicy(SchedulingPolicy schedulingPolicy) = 0;
+
+ /**
+ * \brief Starts the thread.
+ *
+ * This operation can be performed on threads in "New" state only.
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - thread is already started;
+ * - error codes returned by scheduler::Scheduler::add();
+ */
+
+ virtual int start() = 0;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_THREAD_HPP_
diff --git a/include/distortos/ThreadCommon.hpp b/include/distortos/ThreadCommon.hpp
new file mode 100644
index 0000000..8f34290
--- /dev/null
+++ b/include/distortos/ThreadCommon.hpp
@@ -0,0 +1,230 @@
+/**
+ * \file
+ * \brief ThreadCommon 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_THREADCOMMON_HPP_
+#define INCLUDE_DISTORTOS_THREADCOMMON_HPP_
+
+#include "distortos/internal/scheduler/ThreadControlBlock.hpp"
+
+#include "distortos/Semaphore.hpp"
+#include "distortos/Thread.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief ThreadCommon class implements common functionality of threads
+ *
+ * \ingroup threads
+ */
+
+class ThreadCommon : public Thread
+{
+public:
+
+ /// unique_ptr (with deleter) to storage for stack
+ using StackStorageUniquePointer = architecture::Stack::StorageUniquePointer;
+
+ /**
+ * \brief ThreadCommon's 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 internal::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
+ */
+
+ ThreadCommon(architecture::Stack&& stack, uint8_t priority, SchedulingPolicy schedulingPolicy,
+ internal::ThreadGroupControlBlock* threadGroupControlBlock, SignalsReceiver* signalsReceiver);
+
+ /**
+ * \brief ThreadCommon's destructor
+ */
+
+ ~ThreadCommon() override;
+
+ /**
+ * \brief Generates signal for thread.
+ *
+ * Similar to pthread_kill() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html
+ *
+ * Adds the signalNumber to set of pending signals. If this thread is currently waiting for this signal, it will be
+ * unblocked.
+ *
+ * \param [in] signalNumber is the signal that will be generated, [0; 31]
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - reception of signals is disabled for this thread;
+ *
+ * \ingroup signals
+ */
+
+ int generateSignal(uint8_t signalNumber) override;
+
+ /**
+ * \return effective priority of thread
+ */
+
+ uint8_t getEffectivePriority() const override;
+
+ /**
+ * \brief Gets set of currently pending signals.
+ *
+ * Similar to sigpending() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpending.html
+ *
+ * This function shall return the set of signals that are blocked from delivery and are pending on the thread.
+ *
+ * \return set of currently pending signals
+ *
+ * \ingroup signals
+ */
+
+ SignalSet getPendingSignalSet() const override;
+
+ /**
+ * \return priority of thread
+ */
+
+ uint8_t getPriority() const override;
+
+ /**
+ * \return scheduling policy of the thread
+ */
+
+ SchedulingPolicy getSchedulingPolicy() const override;
+
+ /**
+ * \return current state of thread
+ */
+
+ ThreadState getState() const override;
+
+ /**
+ * \brief Waits for thread termination.
+ *
+ * Similar to std::thread::join() - http://en.cppreference.com/w/cpp/thread/thread/join
+ * Similar to POSIX pthread_join() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html
+ *
+ * Blocks current thread until this thread finishes its execution. The results of multiple simultaneous calls to
+ * join() on the same target thread are undefined.
+ *
+ * \return 0 on success, error code otherwise:
+ * - EDEADLK - deadlock condition was detected,
+ * - EINVAL - this thread is not joinable,
+ * - ...
+ *
+ * \ingroup synchronization
+ */
+
+ int join() override;
+
+ /**
+ * \brief Queues signal for thread.
+ *
+ * Similar to sigqueue() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigqueue.html
+ *
+ * Adds the signalNumber and signal value (sigval union) to queue of SignalInformation objects. If this thread is
+ * currently waiting for this signal, it will be unblocked.
+ *
+ * \param [in] signalNumber is the signal that will be queued, [0; 31]
+ * \param [in] value is the signal value
+ *
+ * \return 0 on success, error code otherwise:
+ * - EAGAIN - no resources are available to queue the signal, maximal number of signals is already queued in
+ * associated queue of SignalInformation objects;
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - reception or queuing of signals are disabled for this thread;
+ *
+ * \ingroup signals
+ */
+
+ int queueSignal(uint8_t signalNumber, sigval value) override;
+
+ /**
+ * \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 = {}) override;
+
+ /**
+ * param [in] schedulingPolicy is the new scheduling policy of the thread
+ */
+
+ void setSchedulingPolicy(SchedulingPolicy schedulingPolicy) override;
+
+ /**
+ * \brief Starts the thread.
+ *
+ * This operation can be performed on threads in "New" state only.
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - thread is already started;
+ * - error codes returned by internal::Scheduler::add();
+ */
+
+ int start() override;
+
+ ThreadCommon(const ThreadCommon&) = delete;
+ ThreadCommon(ThreadCommon&&) = default;
+ const ThreadCommon& operator=(const ThreadCommon&) = delete;
+ ThreadCommon& operator=(ThreadCommon&&) = delete;
+
+protected:
+
+ /**
+ * \return reference to internal ThreadControlBlock object
+ */
+
+ internal::ThreadControlBlock& getThreadControlBlock()
+ {
+ return threadControlBlock_;
+ }
+
+ /**
+ * \return const reference to internal ThreadControlBlock object
+ */
+
+ const internal::ThreadControlBlock& getThreadControlBlock() const
+ {
+ return threadControlBlock_;
+ }
+
+ /**
+ * \brief Termination hook function of thread
+ *
+ * \param [in] thread is a reference to Thread object, this must be ThreadCommon!
+ */
+
+ static void terminationHook(Thread& thread);
+
+private:
+
+ /// internal ThreadControlBlock object
+ internal::ThreadControlBlock threadControlBlock_;
+
+ /// semaphore used by join()
+ Semaphore joinSemaphore_;
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_THREADCOMMON_HPP_
diff --git a/include/distortos/ThreadState.hpp b/include/distortos/ThreadState.hpp
new file mode 100644
index 0000000..15a92e3
--- /dev/null
+++ b/include/distortos/ThreadState.hpp
@@ -0,0 +1,54 @@
+/**
+ * \file
+ * \brief ThreadState enum 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_THREADSTATE_HPP_
+#define INCLUDE_DISTORTOS_THREADSTATE_HPP_
+
+#include <cstdint>
+
+namespace distortos
+{
+
+/**
+ * \brief state of the thread
+ *
+ * \ingroup threads
+ */
+
+enum class ThreadState : uint8_t
+{
+ /// state in which thread is created, before being added to Scheduler
+ created,
+ /// thread is runnable
+ runnable,
+ /// thread is terminated
+ terminated,
+ /// thread is sleeping
+ sleeping,
+ /// thread is blocked on Semaphore
+ blockedOnSemaphore,
+ /// thread is suspended
+ suspended,
+ /// thread is blocked on Mutex
+ blockedOnMutex,
+ /// thread is blocked on ConditionVariable
+ blockedOnConditionVariable,
+ /// thread is waiting for signal
+ waitingForSignal,
+ /// thread is blocked on OnceFlag
+ blockedOnOnceFlag,
+ /// internal thread object was detached
+ detached,
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_THREADSTATE_HPP_
diff --git a/include/distortos/TickClock.hpp b/include/distortos/TickClock.hpp
new file mode 100644
index 0000000..7f1ace0
--- /dev/null
+++ b/include/distortos/TickClock.hpp
@@ -0,0 +1,56 @@
+/**
+ * \file
+ * \brief TickClock 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_TICKCLOCK_HPP_
+#define INCLUDE_DISTORTOS_TICKCLOCK_HPP_
+
+#include "distortos/distortosConfiguration.h"
+
+#include <chrono>
+
+namespace distortos
+{
+
+/**
+ * \brief TickClock is a std::chrono clock, equivalent of std::chrono::steady_clock
+ *
+ * \ingroup clocks
+ */
+
+class TickClock
+{
+public:
+
+ /// type of tick counter
+ using rep = uint64_t;
+
+ /// std::ratio type representing the tick period of the clock, in seconds
+ using period = std::ratio<1, CONFIG_TICK_FREQUENCY>;
+
+ /// basic duration type of clock
+ using duration = std::chrono::duration<rep, period>;
+
+ /// basic time_point type of clock
+ using time_point = std::chrono::time_point<TickClock>;
+
+ /**
+ * \return time_point representing the current value of the clock
+ */
+
+ static time_point now();
+
+ /// this is a steady clock - it cannot be adjusted
+ static constexpr bool is_steady {true};
+};
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_TICKCLOCK_HPP_
diff --git a/include/distortos/UndetachableThread.hpp b/include/distortos/UndetachableThread.hpp
new file mode 100644
index 0000000..772b9aa
--- /dev/null
+++ b/include/distortos/UndetachableThread.hpp
@@ -0,0 +1,57 @@
+/**
+ * \file
+ * \brief UndetachableThread 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_UNDETACHABLETHREAD_HPP_
+#define INCLUDE_DISTORTOS_UNDETACHABLETHREAD_HPP_
+
+#include "distortos/ThreadCommon.hpp"
+
+namespace distortos
+{
+
+/**
+ * \brief UndetachableThread class is a ThreadCommon that cannot be detached
+ *
+ * \ingroup threads
+ */
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+class UndetachableThread : public ThreadCommon
+{
+public:
+
+ using ThreadCommon::ThreadCommon;
+
+ /**
+ * \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 ENOTSUP - this thread cannot be detached;
+ */
+
+ int detach() override;
+};
+
+#else // !def CONFIG_THREAD_DETACH_ENABLE
+
+using UndetachableThread = ThreadCommon;
+
+#endif // !def CONFIG_THREAD_DETACH_ENABLE
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_UNDETACHABLETHREAD_HPP_
diff --git a/include/distortos/architecture/InterruptMaskingLock.hpp b/include/distortos/architecture/InterruptMaskingLock.hpp
new file mode 100644
index 0000000..6f8253b
--- /dev/null
+++ b/include/distortos/architecture/InterruptMaskingLock.hpp
@@ -0,0 +1,34 @@
+/**
+ * \file
+ * \brief InterruptMaskingLock 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_ARCHITECTURE_INTERRUPTMASKINGLOCK_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_INTERRUPTMASKINGLOCK_HPP_
+
+#include "distortos/architecture/InterruptMaskingUnmaskingLock.hpp"
+#include "distortos/architecture/enableInterruptMasking.hpp"
+
+namespace distortos
+{
+
+namespace architecture
+{
+
+/// InterruptMaskingLock class is a RAII wrapper for enableInterruptMasking() / restoreInterruptMasking()
+class InterruptMaskingLock : private InterruptMaskingUnmaskingLock<enableInterruptMasking>
+{
+
+};
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_INTERRUPTMASKINGLOCK_HPP_
diff --git a/include/distortos/architecture/InterruptMaskingUnmaskingLock.hpp b/include/distortos/architecture/InterruptMaskingUnmaskingLock.hpp
new file mode 100644
index 0000000..65bd0f0
--- /dev/null
+++ b/include/distortos/architecture/InterruptMaskingUnmaskingLock.hpp
@@ -0,0 +1,73 @@
+/**
+ * \file
+ * \brief InterruptMaskingUnmaskingLock 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_ARCHITECTURE_INTERRUPTMASKINGUNMASKINGLOCK_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_INTERRUPTMASKINGUNMASKINGLOCK_HPP_
+
+#include "distortos/architecture/restoreInterruptMasking.hpp"
+
+namespace distortos
+{
+
+namespace architecture
+{
+
+/**
+ * \brief InterruptMaskingUnmaskingLock class is a RAII wrapper for interrupt mask manipulation.
+ *
+ * \tparam Function is a reference to function which modifies interrupt mask and returns InterruptMask;
+ * enableInterruptMasking() or disableInterruptMasking() should be used
+ */
+
+template<InterruptMask (& Function)()>
+class InterruptMaskingUnmaskingLock
+{
+public:
+
+ /**
+ * \brief InterruptMaskingUnmaskingLock's constructor
+ *
+ * Enables/disables interrupt masking, saving current interrupt mask for use in destructor.
+ */
+
+ InterruptMaskingUnmaskingLock() :
+ interruptMask_{Function()}
+ {
+
+ }
+
+ /**
+ * \brief InterruptMaskingUnmaskingLock's destructor
+ *
+ * Restores previous interrupt masking state by restoring interrupt mask saved in constructor.
+ */
+
+ ~InterruptMaskingUnmaskingLock()
+ {
+ restoreInterruptMasking(interruptMask_);
+ }
+
+ InterruptMaskingUnmaskingLock(const InterruptMaskingUnmaskingLock&) = delete;
+ InterruptMaskingUnmaskingLock(InterruptMaskingUnmaskingLock&&) = delete;
+ InterruptMaskingUnmaskingLock& operator=(const InterruptMaskingUnmaskingLock&) = delete;
+ InterruptMaskingUnmaskingLock& operator=(InterruptMaskingUnmaskingLock&&) = delete;
+
+private:
+
+ /// interrupt mask
+ const InterruptMask interruptMask_;
+};
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_INTERRUPTMASKINGUNMASKINGLOCK_HPP_
diff --git a/include/distortos/architecture/InterruptUnmaskingLock.hpp b/include/distortos/architecture/InterruptUnmaskingLock.hpp
new file mode 100644
index 0000000..263bbea
--- /dev/null
+++ b/include/distortos/architecture/InterruptUnmaskingLock.hpp
@@ -0,0 +1,34 @@
+/**
+ * \file
+ * \brief InterruptUnmaskingLock 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_ARCHITECTURE_INTERRUPTUNMASKINGLOCK_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_INTERRUPTUNMASKINGLOCK_HPP_
+
+#include "distortos/architecture/InterruptMaskingUnmaskingLock.hpp"
+#include "distortos/architecture/disableInterruptMasking.hpp"
+
+namespace distortos
+{
+
+namespace architecture
+{
+
+/// InterruptUnmaskingLock class is a RAII wrapper for disableInterruptMasking() / restoreInterruptMasking()
+class InterruptUnmaskingLock : private InterruptMaskingUnmaskingLock<disableInterruptMasking>
+{
+
+};
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_INTERRUPTUNMASKINGLOCK_HPP_
diff --git a/include/distortos/architecture/Stack.hpp b/include/distortos/architecture/Stack.hpp
new file mode 100644
index 0000000..bd23452
--- /dev/null
+++ b/include/distortos/architecture/Stack.hpp
@@ -0,0 +1,122 @@
+/**
+ * \file
+ * \brief Stack 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_ARCHITECTURE_STACK_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_STACK_HPP_
+
+#include <memory>
+
+namespace distortos
+{
+
+class Thread;
+
+namespace architecture
+{
+
+/// Stack class is an abstraction of architecture's stack
+class Stack
+{
+public:
+
+ /// unique_ptr (with deleter) to storage
+ using StorageUniquePointer = std::unique_ptr<void, void(&)(void*)>;
+
+ /**
+ * \brief Stack's constructor
+ *
+ * This function initializes valid architecture-specific stack in provided storage. This requires following steps:
+ * - adjustment of storage's address to suit architecture's alignment requirements,
+ * - adjustment of storage's size to suit architecture's divisibility requirements,
+ * - creating hardware and software stack frame in suitable place in the stack,
+ * - calculation of stack pointer register value.
+ *
+ * After this constructor completes, stack is ready for context switching.
+ *
+ * \param [in] storageUniquePointer is a rvalue reference to StorageUniquePointer with storage for stack (\a size
+ * bytes long) and appropriate deleter
+ * \param [in] size is the size of stack's storage, bytes
+ * \param [in] thread is a reference to Thread object passed to function
+ * \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
+ */
+
+ Stack(StorageUniquePointer&& storageUniquePointer, size_t size, Thread& thread, void (& run)(Thread&),
+ void (* preTerminationHook)(Thread&), void (& terminationHook)(Thread&));
+
+ /**
+ * \brief Stack's constructor
+ *
+ * This function adopts existing valid architecture-specific stack in provided storage. No adjustments are done,
+ * no stack frame is created and stack pointer register's value is not calculated.
+ *
+ * This is meant to adopt main()'s stack.
+ *
+ * \param [in] storage is a pointer to stack's storage
+ * \param [in] size is the size of stack's storage, bytes
+ */
+
+ Stack(void* storage, size_t size);
+
+ /**
+ * \brief Stack's destructor
+ */
+
+ ~Stack();
+
+ /**
+ * \brief Gets current value of stack pointer.
+ *
+ * \return current value of stack pointer
+ */
+
+ void* getStackPointer() const
+ {
+ return stackPointer_;
+ }
+
+ /**
+ * \brief Sets value of stack pointer.
+ *
+ * \param [in] stackPointer is the new value of stack pointer
+ */
+
+ void setStackPointer(void* const stackPointer)
+ {
+ stackPointer_ = stackPointer;
+ }
+
+ Stack(const Stack&) = delete;
+ Stack(Stack&&) = default;
+ const Stack& operator=(const Stack&) = delete;
+ Stack& operator=(Stack&&) = delete;
+
+private:
+
+ /// storage for stack
+ StorageUniquePointer storageUniquePointer_;
+
+ /// adjusted address of stack's storage
+ void* const adjustedStorage_;
+
+ /// adjusted size of stack's storage
+ const size_t adjustedSize_;
+
+ /// current value of stack pointer register
+ void* stackPointer_;
+};
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_STACK_HPP_
diff --git a/include/distortos/architecture/disableInterruptMasking.hpp b/include/distortos/architecture/disableInterruptMasking.hpp
new file mode 100644
index 0000000..d82eda1
--- /dev/null
+++ b/include/distortos/architecture/disableInterruptMasking.hpp
@@ -0,0 +1,37 @@
+/**
+ * \file
+ * \brief disableInterruptMasking() 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_ARCHITECTURE_DISABLEINTERRUPTMASKING_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_DISABLEINTERRUPTMASKING_HPP_
+
+#include "distortos/architecture/parameters.hpp"
+
+namespace distortos
+{
+
+namespace architecture
+{
+
+/**
+ * \brief Disables interrupt masking.
+ *
+ * Enables normal-priority interrupts.
+ *
+ * \return previous value of interrupts' mask, must be used for matched restoreInterruptMasking() call
+ */
+
+InterruptMask disableInterruptMasking();
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_DISABLEINTERRUPTMASKING_HPP_
diff --git a/include/distortos/architecture/enableInterruptMasking.hpp b/include/distortos/architecture/enableInterruptMasking.hpp
new file mode 100644
index 0000000..8fb6566
--- /dev/null
+++ b/include/distortos/architecture/enableInterruptMasking.hpp
@@ -0,0 +1,40 @@
+/**
+ * \file
+ * \brief enableInterruptMasking() 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_ARCHITECTURE_ENABLEINTERRUPTMASKING_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_ENABLEINTERRUPTMASKING_HPP_
+
+#include "distortos/architecture/parameters.hpp"
+
+namespace distortos
+{
+
+namespace architecture
+{
+
+/**
+ * \brief Enables interrupt masking.
+ *
+ * Disables normal-priority interrupts.
+ *
+ * \note High-priority interrupts are not controlled by distortos, so they may be left enabled. Support for that feature
+ * is architecture-dependent.
+ *
+ * \return previous value of interrupts' mask, must be used for matched restoreInterruptMasking() call
+ */
+
+InterruptMask enableInterruptMasking();
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_ENABLEINTERRUPTMASKING_HPP_
diff --git a/include/distortos/architecture/getMainStack.hpp b/include/distortos/architecture/getMainStack.hpp
new file mode 100644
index 0000000..6f75c2b
--- /dev/null
+++ b/include/distortos/architecture/getMainStack.hpp
@@ -0,0 +1,37 @@
+/**
+ * \file
+ * \brief getMainStack() 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_ARCHITECTURE_GETMAINSTACK_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_GETMAINSTACK_HPP_
+
+#include <utility>
+
+#include <cstddef>
+
+namespace distortos
+{
+
+namespace architecture
+{
+
+/**
+ * \brief Gets the stack used to run main().
+ *
+ * \return beginning of stack and its size in bytes
+ */
+
+std::pair<void*, size_t> getMainStack();
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_GETMAINSTACK_HPP_
diff --git a/include/distortos/architecture/initializeStack.hpp b/include/distortos/architecture/initializeStack.hpp
new file mode 100644
index 0000000..6cc73ae
--- /dev/null
+++ b/include/distortos/architecture/initializeStack.hpp
@@ -0,0 +1,50 @@
+/**
+ * \file
+ * \brief initializeStack() 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_ARCHITECTURE_INITIALIZESTACK_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_INITIALIZESTACK_HPP_
+
+#include <cstddef>
+
+namespace distortos
+{
+
+class Thread;
+
+namespace architecture
+{
+
+/**
+ * \brief Architecture-specific stack initialization.
+ *
+ * This function fills provided buffer with hardware and software stack frame and calculates value of stack pointer
+ * register. After this function completes, stack is ready for context switching.
+ *
+ * \attention buffer and size must be properly adjusted for architecture requirements
+ *
+ * \param [in] buffer is a pointer to stack's buffer
+ * \param [in] size is the size of stack's buffer, bytes
+ * \param [in] thread is a reference to Thread object passed to function
+ * \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
+ *
+ * \return value that can be used as thread's stack pointer, ready for context switching
+ */
+
+void* initializeStack(void* buffer, size_t size, Thread& thread, void (& run)(Thread&),
+ void (* preTerminationHook)(Thread&), void (& terminationHook)(Thread&));
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_INITIALIZESTACK_HPP_
diff --git a/include/distortos/architecture/lowLevelInitialization.hpp b/include/distortos/architecture/lowLevelInitialization.hpp
new file mode 100644
index 0000000..4c9d3d2
--- /dev/null
+++ b/include/distortos/architecture/lowLevelInitialization.hpp
@@ -0,0 +1,34 @@
+/**
+ * \file
+ * \brief lowLevelInitialization() 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_ARCHITECTURE_LOWLEVELINITIALIZATION_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_LOWLEVELINITIALIZATION_HPP_
+
+namespace distortos
+{
+
+namespace architecture
+{
+
+/**
+ * \brief Low level architecture initialization.
+ *
+ * This function is called before constructors for global and static objects from __libc_init_array() via address in
+ * distortosPreinitArray[].
+ */
+
+void lowLevelInitialization();
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_LOWLEVELINITIALIZATION_HPP_
diff --git a/include/distortos/architecture/requestContextSwitch.hpp b/include/distortos/architecture/requestContextSwitch.hpp
new file mode 100644
index 0000000..bc92b6b
--- /dev/null
+++ b/include/distortos/architecture/requestContextSwitch.hpp
@@ -0,0 +1,35 @@
+/**
+ * \file
+ * \brief requestContextSwitch() 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_ARCHITECTURE_REQUESTCONTEXTSWITCH_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_REQUESTCONTEXTSWITCH_HPP_
+
+namespace distortos
+{
+
+namespace architecture
+{
+
+/**
+ * \brief Architecture-specific request for context switch.
+ *
+ * Causes the architecture to do context save, call scheduler::getScheduler().switchContext() and do context restore.
+ * The call to scheduler::getScheduler().switchContext() must be done from the context in which such call is valid
+ * (usually system interrupt).
+ */
+
+void requestContextSwitch();
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_REQUESTCONTEXTSWITCH_HPP_
diff --git a/include/distortos/architecture/requestFunctionExecution.hpp b/include/distortos/architecture/requestFunctionExecution.hpp
new file mode 100644
index 0000000..69c9eda
--- /dev/null
+++ b/include/distortos/architecture/requestFunctionExecution.hpp
@@ -0,0 +1,53 @@
+/**
+ * \file
+ * \brief requestFunctionExecution() 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_ARCHITECTURE_REQUESTFUNCTIONEXECUTION_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_REQUESTFUNCTIONEXECUTION_HPP_
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class ThreadControlBlock;
+
+} // namespace internal
+
+namespace architecture
+{
+
+/**
+ * \brief Requests execution of provided function in the specified thread.
+ *
+ * Main use case for this function is to request execution of signals delivery function. In such case it is called when
+ * an unblocked signal, which is not ignored, is generated or queued for specified thread.
+ *
+ * It must arrange for given function to be executed in specified thread as soon as possible. This generally requires
+ * dealing with following scenarios:
+ * - current thread is sending the request to itself - in that case just execute function right away;
+ * - current thread is sending the request to non-current thread;
+ * - interrupt is sending the request to current thread;
+ * - interrupt is sending the request to non-current thread;
+ *
+ * \param [in] threadControlBlock is a reference to internal::ThreadControlBlock of thread in which \a function should
+ * be executed
+ * \param [in] function is a reference to function that should be executed in thread associated with
+ * \a threadControlBlock
+ */
+
+void requestFunctionExecution(internal::ThreadControlBlock& threadControlBlock, void (& function)());
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_REQUESTFUNCTIONEXECUTION_HPP_
diff --git a/include/distortos/architecture/restoreInterruptMasking.hpp b/include/distortos/architecture/restoreInterruptMasking.hpp
new file mode 100644
index 0000000..268159b
--- /dev/null
+++ b/include/distortos/architecture/restoreInterruptMasking.hpp
@@ -0,0 +1,39 @@
+/**
+ * \file
+ * \brief restoreInterruptMasking() 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_ARCHITECTURE_RESTOREINTERRUPTMASKING_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_RESTOREINTERRUPTMASKING_HPP_
+
+#include "distortos/architecture/parameters.hpp"
+
+namespace distortos
+{
+
+namespace architecture
+{
+
+/**
+ * \brief Restores interrupt masking.
+ *
+ * Restores previous interrupt masking state (before matching enableInterruptMasking() or disableInterruptMasking() was
+ * called), enabling some (maybe all, maybe none) interrupts.
+ *
+ * \param [in] interruptMask is the value of interrupts' mask, must come from previous call to enableInterruptMasking()
+ * or disableInterruptMasking()
+ */
+
+void restoreInterruptMasking(InterruptMask interruptMask);
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_RESTOREINTERRUPTMASKING_HPP_
diff --git a/include/distortos/architecture/startScheduling.hpp b/include/distortos/architecture/startScheduling.hpp
new file mode 100644
index 0000000..20db514
--- /dev/null
+++ b/include/distortos/architecture/startScheduling.hpp
@@ -0,0 +1,33 @@
+/**
+ * \file
+ * \brief startScheduling() 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_ARCHITECTURE_STARTSCHEDULING_HPP_
+#define INCLUDE_DISTORTOS_ARCHITECTURE_STARTSCHEDULING_HPP_
+
+namespace distortos
+{
+
+namespace architecture
+{
+
+/**
+ * \brief Architecture-specific start of scheduling.
+ *
+ * Initializes all required hardware/software to perform context switching and starts the scheduling.
+ */
+
+void startScheduling();
+
+} // namespace architecture
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_ARCHITECTURE_STARTSCHEDULING_HPP_
diff --git a/include/distortos/board/lowLevelInitialization.hpp b/include/distortos/board/lowLevelInitialization.hpp
new file mode 100644
index 0000000..6007422
--- /dev/null
+++ b/include/distortos/board/lowLevelInitialization.hpp
@@ -0,0 +1,36 @@
+/**
+ * \file
+ * \brief board::lowLevelInitialization() declaration
+ *
+ * \author Copyright (C) 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_BOARD_LOWLEVELINITIALIZATION_HPP_
+#define INCLUDE_DISTORTOS_BOARD_LOWLEVELINITIALIZATION_HPP_
+
+namespace distortos
+{
+
+namespace board
+{
+
+/**
+ * \brief Low level board initialization.
+ *
+ * This function is called before constructors for global and static objects from __libc_init_array() via address in
+ * distortosPreinitArray[].
+ *
+ * \note Use of this function is optional - it may be left undefined, in which case it will not be called.
+ */
+
+void lowLevelInitialization() __attribute__ ((weak));
+
+} // namespace board
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_BOARD_LOWLEVELINITIALIZATION_HPP_
diff --git a/include/distortos/callOnce.hpp b/include/distortos/callOnce.hpp
new file mode 100644
index 0000000..ed1cd1d
--- /dev/null
+++ b/include/distortos/callOnce.hpp
@@ -0,0 +1,50 @@
+/**
+ * \file
+ * \brief callOnce() 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_CALLONCE_HPP_
+#define INCLUDE_DISTORTOS_CALLONCE_HPP_
+
+#include "distortos/OnceFlag.hpp"
+
+#if DISTORTOS_CALLONCE_SUPPORTED == 1 || DOXYGEN == 1
+
+namespace distortos
+{
+
+/**
+ * \brief Executes the callable object exactly once, even if called from multiple threads.
+ *
+ * Similar to std::call_once() - http://en.cppreference.com/w/cpp/thread/call_once
+ * Similar to POSIX pthread_once() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_once.html#
+ *
+ * \note This function requires GCC 4.9.
+ *
+ * \tparam Function is the function object that will be executed
+ * \tparam Args are the arguments for \a Function
+ *
+ * \param [in] onceFlag is a reference to shared OnceFlag object
+ * \param [in] function is the function object that will be executed
+ * \param [in] args are arguments for \a function
+ *
+ * \ingroup synchronization
+ */
+
+template<typename Function, typename... Args>
+void callOnce(OnceFlag& onceFlag, Function&& function, Args&&... args)
+{
+ onceFlag.callOnceControlBlock_(std::forward<Function>(function), std::forward<Args>(args)...);
+}
+
+} // namespace distortos
+
+#endif // DISTORTOS_CALLONCE_SUPPORTED == 1 || DOXYGEN == 1
+
+#endif // INCLUDE_DISTORTOS_CALLONCE_HPP_
diff --git a/include/distortos/chip/lowLevelInitialization.hpp b/include/distortos/chip/lowLevelInitialization.hpp
new file mode 100644
index 0000000..f9e28ac
--- /dev/null
+++ b/include/distortos/chip/lowLevelInitialization.hpp
@@ -0,0 +1,34 @@
+/**
+ * \file
+ * \brief chip::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_CHIP_LOWLEVELINITIALIZATION_HPP_
+#define INCLUDE_DISTORTOS_CHIP_LOWLEVELINITIALIZATION_HPP_
+
+namespace distortos
+{
+
+namespace chip
+{
+
+/**
+ * \brief Low level chip initialization.
+ *
+ * This function is called before constructors for global and static objects from __libc_init_array() via address in
+ * distortosPreinitArray[].
+ */
+
+void lowLevelInitialization();
+
+} // namespace chip
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_CHIP_LOWLEVELINITIALIZATION_HPP_
diff --git a/include/distortos/devices/io/InputPin.hpp b/include/distortos/devices/io/InputPin.hpp
new file mode 100644
index 0000000..9838998
--- /dev/null
+++ b/include/distortos/devices/io/InputPin.hpp
@@ -0,0 +1,48 @@
+/**
+ * \file
+ * \brief InputPin class header
+ *
+ * \author Copyright (C) 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_DEVICES_IO_INPUTPIN_HPP_
+#define INCLUDE_DISTORTOS_DEVICES_IO_INPUTPIN_HPP_
+
+namespace distortos
+{
+
+namespace devices
+{
+
+/**
+ * InputPin class is an interface for single input pin
+ *
+ * \ingroup devices
+ */
+
+class InputPin
+{
+public:
+
+ /**
+ * \brief InputPin's destructor
+ */
+
+ virtual ~InputPin() = 0;
+
+ /**
+ * \return current state of pin
+ */
+
+ virtual bool get() const = 0;
+};
+
+} // namespace devices
+
+} // namespace devices
+
+#endif // INCLUDE_DISTORTOS_DEVICES_IO_INPUTPIN_HPP_
diff --git a/include/distortos/devices/io/OutputPin.hpp b/include/distortos/devices/io/OutputPin.hpp
new file mode 100644
index 0000000..6651d9d
--- /dev/null
+++ b/include/distortos/devices/io/OutputPin.hpp
@@ -0,0 +1,46 @@
+/**
+ * \file
+ * \brief OutputPin class header
+ *
+ * \author Copyright (C) 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_DEVICES_IO_OUTPUTPIN_HPP_
+#define INCLUDE_DISTORTOS_DEVICES_IO_OUTPUTPIN_HPP_
+
+#include "distortos/devices/io/InputPin.hpp"
+
+namespace distortos
+{
+
+namespace devices
+{
+
+/**
+ * OutputPin class is an interface for single output pin
+ *
+ * \ingroup devices
+ */
+
+class OutputPin : public InputPin
+{
+public:
+
+ /**
+ * \brief Sets state of pin.
+ *
+ * \param [in] state is the new state of pin
+ */
+
+ virtual void set(bool state) = 0;
+};
+
+} // namespace devices
+
+} // namespace devices
+
+#endif // INCLUDE_DISTORTOS_DEVICES_IO_OUTPUTPIN_HPP_
diff --git a/include/distortos/distortosVersion.h b/include/distortos/distortosVersion.h
new file mode 100644
index 0000000..554758d
--- /dev/null
+++ b/include/distortos/distortosVersion.h
@@ -0,0 +1,37 @@
+/**
+ * \file
+ * \brief distortos version
+ *
+ * \author Copyright (C) 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_DISTORTOSVERSION_H_
+#define INCLUDE_DISTORTOS_DISTORTOSVERSION_H_
+
+/// major version of distortos
+#define DISTORTOS_VERSION_MAJOR 0
+
+/// minor version of distortos
+#define DISTORTOS_VERSION_MINOR 2
+
+/// patch version of distortos
+#define DISTORTOS_VERSION_PATCH 0
+
+/// distortos version as a 32-bit variable
+#define DISTORTOS_VERSION ((DISTORTOS_VERSION_MAJOR << 16) | (DISTORTOS_VERSION_MINOR << 8) | DISTORTOS_VERSION_PATCH)
+
+/// internals of STRINGIZE() macro
+#define STRINGIZE_INTERNAL(x) #x
+
+/// macro used for stringification
+#define STRINGIZE(x) STRINGIZE_INTERNAL(x)
+
+/// distortos version as string
+#define DISTORTOS_VERSION_STRING \
+ STRINGIZE(DISTORTOS_VERSION_MAJOR) "." STRINGIZE(DISTORTOS_VERSION_MINOR) "." STRINGIZE(DISTORTOS_VERSION_PATCH)
+
+#endif /* INCLUDE_DISTORTOS_DISTORTOSVERSION_H_ */
diff --git a/include/distortos/internal/memory/DeferredThreadDeleter.hpp b/include/distortos/internal/memory/DeferredThreadDeleter.hpp
new file mode 100644
index 0000000..bb38ebc
--- /dev/null
+++ b/include/distortos/internal/memory/DeferredThreadDeleter.hpp
@@ -0,0 +1,121 @@
+/**
+ * \file
+ * \brief DeferredThreadDeleter 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_MEMORY_DEFERREDTHREADDELETER_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_MEMORY_DEFERREDTHREADDELETER_HPP_
+
+#include "distortos/distortosConfiguration.h"
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+#include "distortos/Mutex.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// DeferredThreadDeleter class can be used to defer deletion of dynamic detached threads
+class DeferredThreadDeleter
+{
+public:
+
+ /**
+ * \brief DeferredThreadDeleter's constructor
+ */
+
+ constexpr DeferredThreadDeleter() :
+ list_{},
+ mutex_{Mutex::Type::normal, Mutex::Protocol::priorityInheritance},
+ notEmpty_{}
+ {
+
+ }
+
+ /**
+ * \brief DeferredThreadDeleter's function call operator
+ *
+ * Adds thread to internal list of threads scheduled for deferred deletion and marks the list as "not empty".
+ *
+ * \note The object must be locked (with a successful call to DeferredThreadDeleter::lock()) before this function is
+ * used!
+ *
+ * \param [in] threadControlBlock is a reference to ThreadControlBlock object associated with dynamic and detached
+ * thread that has terminated its execution
+ *
+ * \return 0 on success, error code otherwise:
+ * - error codes returned by Mutex::unlock();
+ */
+
+ int operator()(ThreadControlBlock& threadControlBlock);
+
+ /**
+ * \brief Locks the object, preparing it for adding thread to internal list.
+ *
+ * Locks the mutex that synchronizes access to internal list. Locking (performed in this function) and unlocking
+ * (performed at the end of function call operator) are separated, because the locking must be done while the thread
+ * is still runnable, while the transfer to internal list is performed when the thread is not in this state.
+ *
+ * \note This function must be called before function call operator is used!
+ *
+ * \return 0 on success, error code otherwise:
+ * - error codes returned by Mutex::lock();
+ */
+
+ int lock();
+
+ /**
+ * \brief Tries to perform deferred deletion of threads.
+ *
+ * Does nothing is the list is not marked as "not empty". Otherwise this function first tries to lock following two
+ * mutexes:
+ * - mutex that protects dynamic memory allocator;
+ * - mutex that synchronizes access to list of threads scheduled for deferred deletion;
+ * If any Mutex::tryLock() call fails, this function just returns (unlocking any mutexes is necessary). Otherwise
+ * the threads are removed from the list and deleted, while the list's "not empty" marker is cleared.
+ *
+ * \return 0 on success, error code otherwise:
+ * - error codes returned by Mutex::tryLock();
+ * - error codes returned by Mutex::unlock();
+ */
+
+ int tryCleanup();
+
+private:
+
+ /**
+ * \brief Internals of tryCleanup().
+ *
+ * \return 0 on success, error code otherwise:
+ * - error codes returned by Mutex::tryLock();
+ * - error codes returned by Mutex::unlock();
+ */
+
+ int tryCleanupInternal();
+
+ /// list of threads scheduled for deferred deletion
+ ThreadList::UnsortedIntrusiveList list_;
+
+ /// mutex that synchronizes access to the \a list_
+ Mutex mutex_;
+
+ /// true if \a list_ is not empty, false otherwise
+ bool notEmpty_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // def CONFIG_THREAD_DETACH_ENABLE
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_MEMORY_DEFERREDTHREADDELETER_HPP_
diff --git a/include/distortos/internal/memory/dummyDeleter.hpp b/include/distortos/internal/memory/dummyDeleter.hpp
new file mode 100644
index 0000000..3cee5cf
--- /dev/null
+++ b/include/distortos/internal/memory/dummyDeleter.hpp
@@ -0,0 +1,48 @@
+/**
+ * \file
+ * \brief dummyDeleter() 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_MEMORY_DUMMYDELETER_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_MEMORY_DUMMYDELETER_HPP_
+
+#include <type_traits>
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/*---------------------------------------------------------------------------------------------------------------------+
+| global functions' declarations
++---------------------------------------------------------------------------------------------------------------------*/
+
+/**
+ * \brief A "no-op" dummy deleter that can be used with std::unique_ptr and automatic storage that is trivially
+ * destructible.
+ *
+ * \tparam T is the real type of storage, must be trivially destructible
+ * \tparam U is the type of \a storage pointer
+ *
+ * \param [in] storage is a pointer to storage
+ */
+
+template<typename T, typename U>
+void dummyDeleter(U*)
+{
+ static_assert(std::is_trivially_destructible<T>::value == true,
+ "internal::dummyDeleter() cannot be used with types that are not trivially destructible!");
+}
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_MEMORY_DUMMYDELETER_HPP_
diff --git a/include/distortos/internal/memory/getDeferredThreadDeleter.hpp b/include/distortos/internal/memory/getDeferredThreadDeleter.hpp
new file mode 100644
index 0000000..30fea99
--- /dev/null
+++ b/include/distortos/internal/memory/getDeferredThreadDeleter.hpp
@@ -0,0 +1,39 @@
+/**
+ * \file
+ * \brief getDeferredThreadDeleter() 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_MEMORY_GETDEFERREDTHREADDELETER_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_MEMORY_GETDEFERREDTHREADDELETER_HPP_
+
+#include "distortos/distortosConfiguration.h"
+
+#ifdef CONFIG_THREAD_DETACH_ENABLE
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class DeferredThreadDeleter;
+
+/**
+ * \return reference to main instance of DeferredThreadDeleter
+ */
+
+DeferredThreadDeleter& getDeferredThreadDeleter();
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // def CONFIG_THREAD_DETACH_ENABLE
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_MEMORY_GETDEFERREDTHREADDELETER_HPP_
diff --git a/include/distortos/internal/memory/getMallocMutex.hpp b/include/distortos/internal/memory/getMallocMutex.hpp
new file mode 100644
index 0000000..0ba5621
--- /dev/null
+++ b/include/distortos/internal/memory/getMallocMutex.hpp
@@ -0,0 +1,33 @@
+/**
+ * \file
+ * \brief getMallocMutex() 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_MEMORY_GETMALLOCMUTEX_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_MEMORY_GETMALLOCMUTEX_HPP_
+
+namespace distortos
+{
+
+class Mutex;
+
+namespace internal
+{
+
+/**
+ * \return reference to main instance of Mutex used for malloc() and free() locking
+ */
+
+Mutex& getMallocMutex();
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_MEMORY_GETMALLOCMUTEX_HPP_
diff --git a/include/distortos/internal/memory/storageDeleter.hpp b/include/distortos/internal/memory/storageDeleter.hpp
new file mode 100644
index 0000000..da7173f
--- /dev/null
+++ b/include/distortos/internal/memory/storageDeleter.hpp
@@ -0,0 +1,44 @@
+/**
+ * \file
+ * \brief storageDeleter() definition
+ *
+ * \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_MEMORY_STORAGEDELETER_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_MEMORY_STORAGEDELETER_HPP_
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/*---------------------------------------------------------------------------------------------------------------------+
+| global functions' declarations
++---------------------------------------------------------------------------------------------------------------------*/
+
+/**
+ * \brief Templated deleter that can be used with std::unique_ptr and dynamic storage allocated with new T[].
+ *
+ * \tparam T is the real type of allocated storage
+ * \tparam U is the type of \a storage pointer
+ *
+ * \param [in] storage is a pointer to storage that will be deleted
+ */
+
+template<typename T, typename U>
+void storageDeleter(U* const storage)
+{
+ delete[] reinterpret_cast<T*>(storage);
+}
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_MEMORY_STORAGEDELETER_HPP_
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_
diff --git a/include/distortos/internal/synchronization/BoundQueueFunctor.hpp b/include/distortos/internal/synchronization/BoundQueueFunctor.hpp
new file mode 100644
index 0000000..35a9d14
--- /dev/null
+++ b/include/distortos/internal/synchronization/BoundQueueFunctor.hpp
@@ -0,0 +1,89 @@
+/**
+ * \file
+ * \brief BoundQueueFunctor 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_SYNCHRONIZATION_BOUNDQUEUEFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_BOUNDQUEUEFUNCTOR_HPP_
+
+#include "distortos/internal/synchronization/QueueFunctor.hpp"
+
+#include <utility>
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/**
+ * \brief BoundQueueFunctor is a type-erased QueueFunctor which calls its bound functor to execute actions on queue's
+ * storage
+ *
+ * \tparam F is the type of bound functor, it will be called with <em>void*</em> as only argument
+ */
+
+template<typename F>
+class BoundQueueFunctor : public QueueFunctor
+{
+public:
+
+ /**
+ * \brief BoundQueueFunctor's constructor
+ *
+ * \param [in] boundFunctor is a rvalue reference to bound functor which will be used to move-construct internal
+ * bound functor
+ */
+
+ constexpr explicit BoundQueueFunctor(F&& boundFunctor) :
+ boundFunctor_{std::move(boundFunctor)}
+ {
+
+ }
+
+ /**
+ * \brief Calls the bound functor which will execute some action on queue's storage (like copy-constructing,
+ * swapping, destroying, emplacing, ...)
+ *
+ * \param [in,out] storage is a pointer to storage with/for element
+ */
+
+ void operator()(void* const storage) const override
+ {
+ boundFunctor_(storage);
+ }
+
+private:
+
+ /// bound functor
+ F boundFunctor_;
+};
+
+/**
+ * \brief Helper factory function to make BoundQueueFunctor object with deduced template arguments
+ *
+ * \tparam F is the type of bound functor, it will be called with <em>void*</em> as only argument
+ *
+ * \param [in] boundFunctor is a rvalue reference to bound functor which will be used to move-construct internal bound
+ * functor
+ *
+ * \return BoundQueueFunctor object with deduced template arguments
+ */
+
+template<typename F>
+constexpr BoundQueueFunctor<F> makeBoundQueueFunctor(F&& boundFunctor)
+{
+ return BoundQueueFunctor<F>{std::move(boundFunctor)};
+}
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_BOUNDQUEUEFUNCTOR_HPP_
diff --git a/include/distortos/internal/synchronization/CallOnceControlBlock.hpp b/include/distortos/internal/synchronization/CallOnceControlBlock.hpp
new file mode 100644
index 0000000..1684faf
--- /dev/null
+++ b/include/distortos/internal/synchronization/CallOnceControlBlock.hpp
@@ -0,0 +1,172 @@
+/**
+ * \file
+ * \brief CallOnceControlBlock 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_SYNCHRONIZATION_CALLONCECONTROLBLOCK_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_CALLONCECONTROLBLOCK_HPP_
+
+#include "estd/invoke.hpp"
+#include "estd/TypeErasedFunctor.hpp"
+
+#include <sys/features.h>
+
+namespace distortos
+{
+
+/// GCC 4.9 is needed for CallOnceControlBlock::operator()() function - and thus for OnceFlag and callOnce() - earlier
+/// versions don't support parameter pack expansion in lambdas
+#define DISTORTOS_CALLONCE_SUPPORTED __GNUC_PREREQ(4, 9)
+
+#if DISTORTOS_CALLONCE_SUPPORTED == 1 || DOXYGEN == 1
+
+namespace internal
+{
+
+class ThreadList;
+
+/// CallOnceControlBlock class implements functionality of OnceFlag class and callOnce()
+/// \note This class requires GCC 4.9.
+class CallOnceControlBlock
+{
+public:
+
+ /**
+ * \brief CallOnceControlBlock's constructor
+ */
+
+ constexpr CallOnceControlBlock() :
+ blockedList_{},
+ done_{}
+ {
+
+ }
+
+ /**
+ * \brief CallOnceControlBlock's function call operator
+ *
+ * Does nothing if any function was already called for this object. In other case provided function and arguments
+ * are wrapped in a type-erased functor and passed to callOnceImplementation().
+ *
+ * \tparam Function is the function object that will be executed
+ * \tparam Args are the arguments for \a Function
+ *
+ * \param [in] function is the function object that will be executed
+ * \param [in] args are arguments for \a function
+ */
+
+ template<typename Function, typename... Args>
+ void operator()(Function&& function, Args&&... args);
+
+private:
+
+ /// Functor is a type-erased interface for functors which execute bounded function with bounded arguments
+ class Functor : public estd::TypeErasedFunctor<void()>
+ {
+
+ };
+
+ /**
+ * \brief BoundedFunctor is a type-erased Functor which calls its bounded functor
+ *
+ * \tparam F is the type of bounded functor
+ */
+
+ template<typename F>
+ class BoundedFunctor : public Functor
+ {
+ public:
+
+ /**
+ * \brief BoundedFunctor's constructor
+ *
+ * \param [in] boundedFunctor is a rvalue reference to bounded functor which will be used to move-construct
+ * internal bounded functor
+ */
+
+ constexpr explicit BoundedFunctor(F&& boundedFunctor) :
+ boundedFunctor_{std::move(boundedFunctor)}
+ {
+
+ }
+
+ /**
+ * \brief BoundedFunctor's function call operator
+ *
+ * Calls the bounded functor.
+ */
+
+ void operator()() const override
+ {
+ boundedFunctor_();
+ }
+
+ private:
+
+ /// bounded functor
+ F boundedFunctor_;
+ };
+
+ /**
+ * \brief Helper factory function to make BoundedFunctor object with deduced template arguments
+ *
+ * \tparam F is the type of bounded functor
+ *
+ * \param [in] boundedFunctor is a rvalue reference to bounded functor which will be used to move-construct internal
+ * bounded functor
+ *
+ * \return BoundedFunctor object with deduced template arguments
+ */
+
+ template<typename F>
+ constexpr static BoundedFunctor<F> makeBoundedFunctor(F&& boundedFunctor)
+ {
+ return BoundedFunctor<F>{std::move(boundedFunctor)};
+ }
+
+ /**
+ * \brief Implements callOnce() using type-erased functor.
+ *
+ * Does nothing if any function was already called for this object. If the function is currently being executed, but
+ * not yet done, then the calling thread is blocked. In other case the function is executed and - after it is done -
+ * all blocked threads are unblocked.
+ *
+ * \param [in] functor is a reference to functor which will execute bounded function with bounded arguments
+ */
+
+ void callOnceImplementation(const Functor& functor);
+
+ /// pointer to stack-allocated list of ThreadControlBlock objects blocked on associated OnceFlag
+ ThreadList* blockedList_;
+
+ /// tells whether any function was already called for this object (true) or not (false)
+ bool done_;
+};
+
+template<typename Function, typename... Args>
+void CallOnceControlBlock::operator()(Function&& function, Args&&... args)
+{
+ if (done_ == true) // function already executed?
+ return;
+
+ const auto functor = makeBoundedFunctor(
+ [&function, &args...]()
+ {
+ estd::invoke(std::forward<Function>(function), std::forward<Args>(args)...);
+ });
+ callOnceImplementation(functor);
+}
+
+} // namespace internal
+
+#endif // DISTORTOS_CALLONCE_SUPPORTED == 1 || DOXYGEN == 1
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_CALLONCECONTROLBLOCK_HPP_
diff --git a/include/distortos/internal/synchronization/CopyConstructQueueFunctor.hpp b/include/distortos/internal/synchronization/CopyConstructQueueFunctor.hpp
new file mode 100644
index 0000000..7c29c8a
--- /dev/null
+++ b/include/distortos/internal/synchronization/CopyConstructQueueFunctor.hpp
@@ -0,0 +1,67 @@
+/**
+ * \file
+ * \brief CopyConstructQueueFunctor 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_SYNCHRONIZATION_COPYCONSTRUCTQUEUEFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_COPYCONSTRUCTQUEUEFUNCTOR_HPP_
+
+#include "distortos/internal/synchronization/QueueFunctor.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/**
+ * CopyConstructQueueFunctor is a functor used for pushing of data to the queue using copy-construction
+ *
+ * \tparam T is the type of data pushed to the queue
+ */
+
+template<typename T>
+class CopyConstructQueueFunctor : public QueueFunctor
+{
+public:
+
+ /**
+ * \brief CopyConstructQueueFunctor's constructor
+ *
+ * \param [in] value is a reference to object that will be used as argument of copy constructor
+ */
+
+ constexpr explicit CopyConstructQueueFunctor(const T& value) :
+ value_{value}
+ {
+
+ }
+
+ /**
+ * \brief Copy-constructs the element in the queue's storage
+ *
+ * \param [in,out] storage is a pointer to storage for element
+ */
+
+ void operator()(void* const storage) const override
+ {
+ new (storage) T{value_};
+ }
+
+private:
+
+ /// reference to object that will be used as argument of copy constructor
+ const T& value_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_COPYCONSTRUCTQUEUEFUNCTOR_HPP_
diff --git a/include/distortos/internal/synchronization/FifoQueueBase.hpp b/include/distortos/internal/synchronization/FifoQueueBase.hpp
new file mode 100644
index 0000000..f45eec8
--- /dev/null
+++ b/include/distortos/internal/synchronization/FifoQueueBase.hpp
@@ -0,0 +1,145 @@
+/**
+ * \file
+ * \brief FifoQueueBase 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_SYNCHRONIZATION_FIFOQUEUEBASE_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_FIFOQUEUEBASE_HPP_
+
+#include "distortos/Semaphore.hpp"
+
+#include "distortos/internal/synchronization/QueueFunctor.hpp"
+#include "distortos/internal/synchronization/SemaphoreFunctor.hpp"
+
+#include <memory>
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// FifoQueueBase class implements basic functionality of FifoQueue template class
+class FifoQueueBase
+{
+public:
+
+ /// unique_ptr (with deleter) to storage
+ using StorageUniquePointer = std::unique_ptr<void, void(&)(void*)>;
+
+ /**
+ * \brief FifoQueueBase's constructor
+ *
+ * \param [in] storageUniquePointer is a rvalue reference to StorageUniquePointer with storage for queue elements
+ * (sufficiently large for \a maxElements, each \a elementSize bytes long) and appropriate deleter
+ * \param [in] elementSize is the size of single queue element, bytes
+ * \param [in] maxElements is the number of elements in storage
+ */
+
+ FifoQueueBase(StorageUniquePointer&& storageUniquePointer, size_t elementSize, size_t maxElements);
+
+ /**
+ * \brief FifoQueueBase's destructor
+ */
+
+ ~FifoQueueBase();
+
+ /**
+ * \return size of single queue element, bytes
+ */
+
+ size_t getElementSize() const
+ {
+ return elementSize_;
+ }
+
+ /**
+ * \brief Implementation of pop() using type-erased functor
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a popSemaphore_
+ * \param [in] functor is a reference to QueueFunctor which will execute actions related to popping - it will get
+ * readPosition_ as argument
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pop(const SemaphoreFunctor& waitSemaphoreFunctor, const QueueFunctor& functor)
+ {
+ return popPush(waitSemaphoreFunctor, functor, popSemaphore_, pushSemaphore_, readPosition_);
+ }
+
+ /**
+ * \brief Implementation of push() using type-erased functor
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
+ * \param [in] functor is a reference to QueueFunctor which will execute actions related to pushing - it will get
+ * writePosition_ as argument
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int push(const SemaphoreFunctor& waitSemaphoreFunctor, const QueueFunctor& functor)
+ {
+ return popPush(waitSemaphoreFunctor, functor, pushSemaphore_, popSemaphore_, writePosition_);
+ }
+
+private:
+
+ /**
+ * \brief Implementation of pop() and push() using type-erased functor
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a waitSemaphore
+ * \param [in] functor is a reference to QueueFunctor which will execute actions related to popping/pushing - it
+ * will get \a storage as argument
+ * \param [in] waitSemaphore is a reference to semaphore that will be waited for, \a popSemaphore_ for pop(), \a
+ * pushSemaphore_ for push()
+ * \param [in] postSemaphore is a reference to semaphore that will be posted after the operation, \a pushSemaphore_
+ * for pop(), \a popSemaphore_ for push()
+ * \param [in] storage is a reference to appropriate pointer to storage, which will be passed to \a functor, \a
+ * readPosition_ for pop(), \a writePosition_ for push()
+ *
+ * \return zero if operation was successful, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int popPush(const SemaphoreFunctor& waitSemaphoreFunctor, const QueueFunctor& functor, Semaphore& waitSemaphore,
+ Semaphore& postSemaphore, void*& storage);
+
+ /// semaphore guarding access to "pop" functions - its value is equal to the number of available elements
+ Semaphore popSemaphore_;
+
+ /// semaphore guarding access to "push" functions - its value is equal to the number of free slots
+ Semaphore pushSemaphore_;
+
+ /// storage for queue elements
+ const StorageUniquePointer storageUniquePointer_;
+
+ /// pointer to past-the-last element of storage for queue elements
+ const void* const storageEnd_;
+
+ /// pointer to first element available for reading
+ void* readPosition_;
+
+ /// pointer to first free slot available for writing
+ void* writePosition_;
+
+ /// size of single queue element, bytes
+ const size_t elementSize_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_FIFOQUEUEBASE_HPP_
diff --git a/include/distortos/internal/synchronization/MemcpyPopQueueFunctor.hpp b/include/distortos/internal/synchronization/MemcpyPopQueueFunctor.hpp
new file mode 100644
index 0000000..29113a5
--- /dev/null
+++ b/include/distortos/internal/synchronization/MemcpyPopQueueFunctor.hpp
@@ -0,0 +1,65 @@
+/**
+ * \file
+ * \brief MemcpyPopQueueFunctor 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_SYNCHRONIZATION_MEMCPYPOPQUEUEFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MEMCPYPOPQUEUEFUNCTOR_HPP_
+
+#include "distortos/internal/synchronization/QueueFunctor.hpp"
+
+#include <cstddef>
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// MemcpyPopQueueFunctor is a functor used for popping of data from the raw queue with memecpy()
+class MemcpyPopQueueFunctor : public QueueFunctor
+{
+public:
+
+ /**
+ * \brief MemcpyPopQueueFunctor's constructor
+ *
+ * \param [out] buffer is a pointer to buffer for popped element
+ * \param [in] size is the size of \a buffer, bytes
+ */
+
+ constexpr MemcpyPopQueueFunctor(void* const buffer, const size_t size) :
+ buffer_{buffer},
+ size_{size}
+ {
+
+ }
+
+ /**
+ * \brief Copies the data from raw queue's storage (with memcpy()).
+ *
+ * \param [in,out] storage is a pointer to storage for element
+ */
+
+ void operator()(void* storage) const override;
+
+private:
+
+ /// pointer to buffer for popped element
+ void* const buffer_;
+
+ /// size of \a buffer_, bytes
+ const size_t size_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MEMCPYPOPQUEUEFUNCTOR_HPP_
diff --git a/include/distortos/internal/synchronization/MemcpyPushQueueFunctor.hpp b/include/distortos/internal/synchronization/MemcpyPushQueueFunctor.hpp
new file mode 100644
index 0000000..89fb4b0
--- /dev/null
+++ b/include/distortos/internal/synchronization/MemcpyPushQueueFunctor.hpp
@@ -0,0 +1,65 @@
+/**
+ * \file
+ * \brief MemcpyPushQueueFunctor 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_SYNCHRONIZATION_MEMCPYPUSHQUEUEFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MEMCPYPUSHQUEUEFUNCTOR_HPP_
+
+#include "distortos/internal/synchronization/QueueFunctor.hpp"
+
+#include <cstddef>
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// MemcpyPushQueueFunctor is a functor used for pushing of data to the raw queue with memcpy()
+class MemcpyPushQueueFunctor : public QueueFunctor
+{
+public:
+
+ /**
+ * \brief MemcpyPushQueueFunctor's constructor
+ *
+ * \param [in] data is a pointer to data that will be pushed to raw queue
+ * \param [in] size is the size of \a data, bytes
+ */
+
+ constexpr MemcpyPushQueueFunctor(const void* const data, const size_t size) :
+ data_{data},
+ size_{size}
+ {
+
+ }
+
+ /**
+ * \brief Copies the data to raw queue's storage (with memcpy()).
+ *
+ * \param [in,out] storage is a pointer to storage for element
+ */
+
+ void operator()(void* storage) const override;
+
+private:
+
+ /// pointer to data that will be pushed to raw queue
+ const void* const data_;
+
+ /// size of \a data_, bytes
+ const size_t size_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MEMCPYPUSHQUEUEFUNCTOR_HPP_
diff --git a/include/distortos/internal/synchronization/MessageQueueBase.hpp b/include/distortos/internal/synchronization/MessageQueueBase.hpp
new file mode 100644
index 0000000..e0bd4e5
--- /dev/null
+++ b/include/distortos/internal/synchronization/MessageQueueBase.hpp
@@ -0,0 +1,221 @@
+/**
+ * \file
+ * \brief MessageQueueBase 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_SYNCHRONIZATION_MESSAGEQUEUEBASE_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MESSAGEQUEUEBASE_HPP_
+
+#include "distortos/Semaphore.hpp"
+
+#include "distortos/internal/synchronization/QueueFunctor.hpp"
+#include "distortos/internal/synchronization/SemaphoreFunctor.hpp"
+
+#include "estd/SortedIntrusiveForwardList.hpp"
+
+#include <memory>
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// MessageQueueBase class implements basic functionality of MessageQueue template class
+class MessageQueueBase
+{
+public:
+
+ /// entry in the MessageQueueBase
+ struct Entry
+ {
+ /**
+ * \brief Entry's constructor
+ *
+ * \param [in] priorityy is the priority of the entry
+ * \param [in] storagee is the storage for the entry
+ */
+
+ constexpr Entry(const uint8_t priorityy, void* const storagee) :
+ node{},
+ priority{priorityy},
+ storage{storagee}
+ {
+
+ }
+
+ /// node for intrusive forward list
+ estd::IntrusiveForwardListNode node;
+
+ /// priority of the entry
+ uint8_t priority;
+
+ /// storage for the entry
+ void* storage;
+ };
+
+ /// type of uninitialized storage for Entry
+ using EntryStorage = typename std::aligned_storage<sizeof(Entry), alignof(Entry)>::type;
+
+ /// unique_ptr (with deleter) to EntryStorage[]
+ using EntryStorageUniquePointer = std::unique_ptr<EntryStorage[], void(&)(EntryStorage*)>;
+
+ /**
+ * type of uninitialized storage for value
+ *
+ * \tparam T is the type of data in queue
+ */
+
+ template<typename T>
+ using ValueStorage = typename std::aligned_storage<sizeof(T), alignof(T)>::type;
+
+ /// unique_ptr (with deleter) to storage
+ using ValueStorageUniquePointer = std::unique_ptr<void, void(&)(void*)>;
+
+ /// functor which gives descending priority order of elements on the list
+ struct DescendingPriority
+ {
+ /**
+ * \brief DescendingPriority's constructor
+ */
+
+ constexpr DescendingPriority()
+ {
+
+ }
+
+ /**
+ * \brief DescendingPriority'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 priority is less than right's priority
+ */
+
+ bool operator()(const Entry& left, const Entry& right) const
+ {
+ return left.priority < right.priority;
+ }
+ };
+
+ /// type of entry list
+ using EntryList = estd::SortedIntrusiveForwardList<DescendingPriority, Entry, &Entry::node>;
+
+ /// type of free entry list
+ using FreeEntryList = EntryList::UnsortedIntrusiveForwardList;
+
+ /**
+ * \brief InternalFunctor is a type-erased interface for functors which execute common code of pop() and push()
+ * operations.
+ *
+ * The functor will be called by MessageQueueBase internals with references to \a entryList_ and \a freeEntryList_.
+ * It should perform common actions and execute the QueueFunctor passed from callers.
+ */
+
+ class InternalFunctor : public estd::TypeErasedFunctor<void(EntryList&, FreeEntryList&)>
+ {
+
+ };
+
+ /**
+ * \brief MessageQueueBase's constructor
+ *
+ * \param [in] entryStorageUniquePointer is a rvalue reference to EntryStorageUniquePointer with storage for queue
+ * entries (sufficiently large for \a maxElements EntryStorage objects) and appropriate deleter
+ * \param [in] valueStorageUniquePointer is a rvalue reference to ValueStorageUniquePointer with storage for queue
+ * elements (sufficiently large for \a maxElements, each \a elementSize bytes long) and appropriate deleter
+ * \param [in] elementSize is the size of single queue element, bytes
+ * \param [in] maxElements is the number of elements in \a entryStorage array and valueStorage memory block
+ */
+
+ MessageQueueBase(EntryStorageUniquePointer&& entryStorageUniquePointer,
+ ValueStorageUniquePointer&& valueStorageUniquePointer, size_t elementSize, size_t maxElements);
+
+ /**
+ * \brief MessageQueueBase's destructor
+ */
+
+ ~MessageQueueBase();
+
+ /**
+ * \brief Implementation of pop() using type-erased functor
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a popSemaphore_
+ * \param [out] priority is a reference to variable that will be used to return priority of popped value
+ * \param [in] functor is a reference to QueueFunctor which will execute actions related to popping - it will get a
+ * pointer to storage with element
+ *
+ * \return zero if element was popped successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int pop(const SemaphoreFunctor& waitSemaphoreFunctor, uint8_t& priority, const QueueFunctor& functor);
+
+ /**
+ * \brief Implementation of push() using type-erased functor
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a pushSemaphore_
+ * \param [in] priority is the priority of new element
+ * \param [in] functor is a reference to QueueFunctor which will execute actions related to pushing - it will get a
+ * pointer to storage for element
+ *
+ * \return zero if element was pushed successfully, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int push(const SemaphoreFunctor& waitSemaphoreFunctor, uint8_t priority, const QueueFunctor& functor);
+
+private:
+
+ /**
+ * \brief Implementation of pop() and push() using type-erased internal functor
+ *
+ * \param [in] waitSemaphoreFunctor is a reference to SemaphoreFunctor which will be executed with \a waitSemaphore
+ * \param [in] internalFunctor is a reference to InternalFunctor which will execute actions related to
+ * popping/pushing
+ * \param [in] waitSemaphore is a reference to semaphore that will be waited for, \a popSemaphore_ for pop(), \a
+ * pushSemaphore_ for push()
+ * \param [in] postSemaphore is a reference to semaphore that will be posted after the operation, \a pushSemaphore_
+ * for pop(), \a popSemaphore_ for push()
+ *
+ * \return zero if operation was successful, error code otherwise:
+ * - error codes returned by \a waitSemaphoreFunctor's operator() call;
+ * - error codes returned by Semaphore::post();
+ */
+
+ int popPush(const SemaphoreFunctor& waitSemaphoreFunctor, const InternalFunctor& internalFunctor,
+ Semaphore& waitSemaphore, Semaphore& postSemaphore);
+
+ /// semaphore guarding access to "pop" functions - its value is equal to the number of available elements
+ Semaphore popSemaphore_;
+
+ /// semaphore guarding access to "push" functions - its value is equal to the number of free slots
+ Semaphore pushSemaphore_;
+
+ /// storage for queue entries
+ const EntryStorageUniquePointer entryStorageUniquePointer_;
+
+ /// storage for queue elements
+ const ValueStorageUniquePointer valueStorageUniquePointer_;
+
+ /// list of available entries, sorted in descending order of priority
+ EntryList entryList_;
+
+ /// list of "free" entries
+ FreeEntryList freeEntryList_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MESSAGEQUEUEBASE_HPP_
diff --git a/include/distortos/internal/synchronization/MoveConstructQueueFunctor.hpp b/include/distortos/internal/synchronization/MoveConstructQueueFunctor.hpp
new file mode 100644
index 0000000..ff6587f
--- /dev/null
+++ b/include/distortos/internal/synchronization/MoveConstructQueueFunctor.hpp
@@ -0,0 +1,69 @@
+/**
+ * \file
+ * \brief MoveConstructQueueFunctor 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_SYNCHRONIZATION_MOVECONSTRUCTQUEUEFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MOVECONSTRUCTQUEUEFUNCTOR_HPP_
+
+#include "distortos/internal/synchronization/QueueFunctor.hpp"
+
+#include <utility>
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/**
+ * MoveConstructQueueFunctor is a functor used for pushing of data to the queue using move-construction
+ *
+ * \tparam T is the type of data pushed to the queue
+ */
+
+template<typename T>
+class MoveConstructQueueFunctor : public QueueFunctor
+{
+public:
+
+ /**
+ * \brief MoveConstructQueueFunctor's constructor
+ *
+ * \param [in] value is a rvalue reference to object that will be used as argument of move constructor
+ */
+
+ constexpr explicit MoveConstructQueueFunctor(T&& value) :
+ value_{std::move(value)}
+ {
+
+ }
+
+ /**
+ * \brief Move-constructs the element in the queue's storage
+ *
+ * \param [in,out] storage is a pointer to storage for element
+ */
+
+ void operator()(void* const storage) const override
+ {
+ new (storage) T{std::move(value_)};
+ }
+
+private:
+
+ /// rvalue reference to object that will be used as argument of move constructor
+ T&& value_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MOVECONSTRUCTQUEUEFUNCTOR_HPP_
diff --git a/include/distortos/internal/synchronization/MutexControlBlock.hpp b/include/distortos/internal/synchronization/MutexControlBlock.hpp
new file mode 100644
index 0000000..93c3ee6
--- /dev/null
+++ b/include/distortos/internal/synchronization/MutexControlBlock.hpp
@@ -0,0 +1,184 @@
+/**
+ * \file
+ * \brief MutexControlBlock 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_SYNCHRONIZATION_MUTEXCONTROLBLOCK_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MUTEXCONTROLBLOCK_HPP_
+
+#include "distortos/internal/scheduler/ThreadList.hpp"
+
+#include "distortos/internal/synchronization/MutexListNode.hpp"
+
+#include "distortos/TickClock.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// MutexControlBlock class is a control block for Mutex
+class MutexControlBlock : public MutexListNode
+{
+public:
+
+ /// mutex protocols
+ enum class Protocol : uint8_t
+ {
+ /// no protocol, similar to PTHREAD_PRIO_NONE
+ none,
+ /// priority inheritance protocol, similar to PTHREAD_PRIO_INHERIT
+ priorityInheritance,
+ /// priority protection protocol (Immediate Ceiling Priority Protocol), similar to PTHREAD_PRIO_PROTECT
+ priorityProtect,
+ };
+
+ /**
+ * \brief MutexControlBlock constructor
+ *
+ * \param [in] protocol is the mutex protocol
+ * \param [in] priorityCeiling is the priority ceiling of mutex, ignored when protocol != Protocol::priorityProtect
+ */
+
+ constexpr MutexControlBlock(const Protocol protocol, const uint8_t priorityCeiling) :
+ MutexListNode{},
+ blockedList_{},
+ owner_{},
+ protocol_{protocol},
+ priorityCeiling_{priorityCeiling}
+ {
+
+ }
+
+ /**
+ * \brief Blocks current thread, transferring it to blockedList_.
+ *
+ * \return 0 on success, error code otherwise:
+ * - values returned by Scheduler::block();
+ */
+
+ int block();
+
+ /**
+ * \brief Blocks current thread with timeout, transferring it to blockedList_.
+ *
+ * \param [in] timePoint is the time point at which the thread will be unblocked (if not already unblocked)
+ *
+ * \return 0 on success, error code otherwise:
+ * - values returned by Scheduler::blockUntil();
+ */
+
+ int blockUntil(TickClock::time_point timePoint);
+
+ /**
+ * \brief Gets "boosted priority" of the mutex.
+ *
+ * "Boosted priority" of the mutex depends on the selected priority protocol:
+ * - None - 0,
+ * - PriorityInheritance - effective priority of the highest priority thread blocked on this mutex or 0 if no
+ * threads are blocked,
+ * - PriorityProtect - priority ceiling.
+ *
+ * \return "boosted priority" of the mutex
+ */
+
+ uint8_t getBoostedPriority() const;
+
+ /**
+ * \return owner of the mutex, nullptr if mutex is currently unlocked
+ */
+
+ ThreadControlBlock* getOwner() const
+ {
+ return owner_;
+ }
+
+ /**
+ * \return priority ceiling of mutex, valid only when protocol_ == Protocol::priorityProtect
+ */
+
+ uint8_t getPriorityCeiling() const
+ {
+ return priorityCeiling_;
+ }
+
+ /**
+ * \return mutex protocol
+ */
+
+ Protocol getProtocol() const
+ {
+ return protocol_;
+ }
+
+ /**
+ * \brief Performs actual locking of previously unlocked mutex.
+ *
+ * \attention mutex must be unlocked
+ */
+
+ void lock();
+
+ /**
+ * \brief Performs unlocking or transfer of lock from current owner to next thread on the list.
+ *
+ * Mutex is unlocked if blockedList_ is empty, otherwise the ownership is transfered to the next thread.
+ *
+ * \attention mutex must be locked
+ */
+
+ void unlockOrTransferLock();
+
+private:
+
+ /**
+ * \brief Performs action required for priority inheritance before actually blocking on the mutex.
+ *
+ * This must be called in block() and blockUntil() before actually blocking of the calling thread.
+ *
+ * \attantion mutex's protocol must be PriorityInheritance
+ */
+
+ void priorityInheritanceBeforeBlock() const;
+
+ /**
+ * \brief Performs transfer of lock from current owner to next thread on the list.
+ *
+ * \attention mutex must be locked and blockedList_ must not be empty
+ */
+
+ void transferLock();
+
+ /**
+ * \brief Performs actual unlocking of previously locked mutex.
+ *
+ * \attention mutex must be locked and blockedList_ must be empty
+ */
+
+ void unlock();
+
+ /// ThreadControlBlock objects blocked on mutex
+ ThreadList blockedList_;
+
+ /// owner of the mutex
+ ThreadControlBlock* owner_;
+
+ /// mutex protocol
+ Protocol protocol_;
+
+ /// priority ceiling of mutex, valid only when protocol_ == Protocol::priorityProtect
+ uint8_t priorityCeiling_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MUTEXCONTROLBLOCK_HPP_
diff --git a/include/distortos/internal/synchronization/MutexList.hpp b/include/distortos/internal/synchronization/MutexList.hpp
new file mode 100644
index 0000000..18d5794
--- /dev/null
+++ b/include/distortos/internal/synchronization/MutexList.hpp
@@ -0,0 +1,32 @@
+/**
+ * \file
+ * \brief MutexList 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_SYNCHRONIZATION_MUTEXLIST_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MUTEXLIST_HPP_
+
+#include "distortos/internal/synchronization/MutexListNode.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class MutexControlBlock;
+
+/// intrusive list of mutexes (mutex control blocks)
+using MutexList = estd::IntrusiveList<MutexListNode, &MutexListNode::node, MutexControlBlock>;
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MUTEXLIST_HPP_
diff --git a/include/distortos/internal/synchronization/MutexListNode.hpp b/include/distortos/internal/synchronization/MutexListNode.hpp
new file mode 100644
index 0000000..049eb76
--- /dev/null
+++ b/include/distortos/internal/synchronization/MutexListNode.hpp
@@ -0,0 +1,53 @@
+/**
+ * \file
+ * \brief MutexListNode 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_SYNCHRONIZATION_MUTEXLISTNODE_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MUTEXLISTNODE_HPP_
+
+#include "estd/IntrusiveList.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/**
+ * \brief MutexListNode class is a base for MutexControlBlock that serves as a node in intrusive list of mutexes (mutex
+ * control blocks)
+ *
+ * This class is needed to break circular dependency - MutexList is contained in ThreadControlBlock and ThreadList is
+ * contained in MutexControlBlock.
+ */
+
+class MutexListNode
+{
+public:
+
+ /**
+ * \brief MutexListNode's constructor
+ */
+
+ constexpr MutexListNode() :
+ node{}
+ {
+
+ }
+
+ /// node for intrusive list
+ estd::IntrusiveListNode node;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_MUTEXLISTNODE_HPP_
diff --git a/include/distortos/internal/synchronization/QueueFunctor.hpp b/include/distortos/internal/synchronization/QueueFunctor.hpp
new file mode 100644
index 0000000..7c14a59
--- /dev/null
+++ b/include/distortos/internal/synchronization/QueueFunctor.hpp
@@ -0,0 +1,40 @@
+/**
+ * \file
+ * \brief QueueFunctor 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_SYNCHRONIZATION_QUEUEFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_QUEUEFUNCTOR_HPP_
+
+#include "estd/TypeErasedFunctor.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/**
+ * \brief QueueFunctor is a type-erased interface for functors which execute some action on queue's storage (like
+ * copy-constructing, swapping, destroying, emplacing, ...).
+ *
+ * The functor will be called by queue internals with one argument - \a storage - which is a pointer to storage with/for
+ * element
+ */
+
+class QueueFunctor : public estd::TypeErasedFunctor<void(void*)>
+{
+
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_SYNCHRONIZATION_QUEUEFUNCTOR_HPP_
diff --git a/include/distortos/internal/synchronization/SemaphoreFunctor.hpp b/include/distortos/internal/synchronization/SemaphoreFunctor.hpp
new file mode 100644
index 0000000..0b937ff
--- /dev/null
+++ b/include/distortos/internal/synchronization/SemaphoreFunctor.hpp
@@ -0,0 +1,43 @@
+/**
+ * \file
+ * \brief SemaphoreFunctor 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_SYNCHRONIZATION_SEMAPHOREFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SEMAPHOREFUNCTOR_HPP_
+
+#include "estd/TypeErasedFunctor.hpp"
+
+namespace distortos
+{
+
+class Semaphore;
+
+namespace internal
+{
+
+/**
+ * \brief SemaphoreFunctor is a type-erased interface for functors which execute some action on semaphore (wait(),
+ * tryWait(), tryWaitFor(), tryWaitUntil(), ...).
+ *
+ * The functor will be called with one argument - \a semaphore - which is a reference to Semaphore object on which the
+ * action will be executed. Functor's operator should return zero if the action was executed successfully, error code
+ * otherwise.
+ */
+
+class SemaphoreFunctor : public estd::TypeErasedFunctor<int(Semaphore&)>
+{
+
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SEMAPHOREFUNCTOR_HPP_
diff --git a/include/distortos/internal/synchronization/SemaphoreTryWaitForFunctor.hpp b/include/distortos/internal/synchronization/SemaphoreTryWaitForFunctor.hpp
new file mode 100644
index 0000000..88580de
--- /dev/null
+++ b/include/distortos/internal/synchronization/SemaphoreTryWaitForFunctor.hpp
@@ -0,0 +1,62 @@
+/**
+ * \file
+ * \brief SemaphoreTryWaitForFunctor 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_SYNCHRONIZATION_SEMAPHORETRYWAITFORFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SEMAPHORETRYWAITFORFUNCTOR_HPP_
+
+#include "distortos/internal/synchronization/SemaphoreFunctor.hpp"
+
+#include "distortos/TickClock.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// SemaphoreTryWaitForFunctor class is a SemaphoreFunctor which calls Semaphore::tryWaitFor() with bounded duration
+class SemaphoreTryWaitForFunctor : public SemaphoreFunctor
+{
+public:
+
+ /**
+ * \brief SemaphoreTryWaitForFunctor's constructor
+ *
+ * \param [in] duration is the bounded duration for Semaphore::tryWaitFor() call
+ */
+
+ constexpr explicit SemaphoreTryWaitForFunctor(const TickClock::duration duration) :
+ duration_{duration}
+ {
+
+ }
+
+ /**
+ * \brief Calls Semaphore::tryWaitFor() with bounded duration
+ *
+ * \param [in] semaphore is a reference to Semaphore object for which Semaphore::tryWaitFor() will be called
+ *
+ * \return value returned by Semaphore::tryWaitFor()
+ */
+
+ int operator()(Semaphore& semaphore) const override;
+
+private:
+
+ /// bounded duration for Semaphore::tryWaitFor() call
+ const TickClock::duration duration_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SEMAPHORETRYWAITFORFUNCTOR_HPP_
diff --git a/include/distortos/internal/synchronization/SemaphoreTryWaitFunctor.hpp b/include/distortos/internal/synchronization/SemaphoreTryWaitFunctor.hpp
new file mode 100644
index 0000000..4084563
--- /dev/null
+++ b/include/distortos/internal/synchronization/SemaphoreTryWaitFunctor.hpp
@@ -0,0 +1,43 @@
+/**
+ * \file
+ * \brief SemaphoreTryWaitFunctor 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_SYNCHRONIZATION_SEMAPHORETRYWAITFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SEMAPHORETRYWAITFUNCTOR_HPP_
+
+#include "distortos/internal/synchronization/SemaphoreFunctor.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// SemaphoreTryWaitFunctor class is a SemaphoreFunctor which calls Semaphore::tryWait()
+class SemaphoreTryWaitFunctor : public SemaphoreFunctor
+{
+public:
+
+ /**
+ * \brief Calls Semaphore::tryWait()
+ *
+ * \param [in] semaphore is a reference to Semaphore object for which Semaphore::tryWait() will be called
+ *
+ * \return value returned by Semaphore::tryWait()
+ */
+
+ int operator()(Semaphore& semaphore) const override;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SEMAPHORETRYWAITFUNCTOR_HPP_
diff --git a/include/distortos/internal/synchronization/SemaphoreTryWaitUntilFunctor.hpp b/include/distortos/internal/synchronization/SemaphoreTryWaitUntilFunctor.hpp
new file mode 100644
index 0000000..a8eaab2
--- /dev/null
+++ b/include/distortos/internal/synchronization/SemaphoreTryWaitUntilFunctor.hpp
@@ -0,0 +1,63 @@
+/**
+ * \file
+ * \brief SemaphoreTryWaitUntilFunctor 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_SYNCHRONIZATION_SEMAPHORETRYWAITUNTILFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SEMAPHORETRYWAITUNTILFUNCTOR_HPP_
+
+#include "distortos/internal/synchronization/SemaphoreFunctor.hpp"
+
+#include "distortos/TickClock.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// SemaphoreTryWaitUntilFunctor class is a SemaphoreFunctor which calls Semaphore::tryWaitUntil() with bounded time
+/// point
+class SemaphoreTryWaitUntilFunctor : public SemaphoreFunctor
+{
+public:
+
+ /**
+ * \brief SemaphoreTryWaitUntilFunctor's constructor
+ *
+ * \param [in] timePoint is the bounded time point for Semaphore::tryWaitUntil() call
+ */
+
+ constexpr explicit SemaphoreTryWaitUntilFunctor(const TickClock::time_point timePoint) :
+ timePoint_{timePoint}
+ {
+
+ }
+
+ /**
+ * \brief Calls Semaphore::tryWaitUntil() with bounded time point.
+ *
+ * \param [in] semaphore is a reference to Semaphore object for which Semaphore::tryWaitUntil() will be called
+ *
+ * \return value returned by Semaphore::tryWaitUntil()
+ */
+
+ int operator()(Semaphore& semaphore) const override;
+
+private:
+
+ /// bounded time point for Semaphore::tryWaitUntil() call
+ const TickClock::time_point timePoint_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SEMAPHORETRYWAITUNTILFUNCTOR_HPP_
diff --git a/include/distortos/internal/synchronization/SemaphoreWaitFunctor.hpp b/include/distortos/internal/synchronization/SemaphoreWaitFunctor.hpp
new file mode 100644
index 0000000..a787b2b
--- /dev/null
+++ b/include/distortos/internal/synchronization/SemaphoreWaitFunctor.hpp
@@ -0,0 +1,43 @@
+/**
+ * \file
+ * \brief SemaphoreWaitFunctor 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_SYNCHRONIZATION_SEMAPHOREWAITFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SEMAPHOREWAITFUNCTOR_HPP_
+
+#include "distortos/internal/synchronization/SemaphoreFunctor.hpp"
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/// SemaphoreWaitFunctor class is a SemaphoreFunctor which calls Semaphore::wait()
+class SemaphoreWaitFunctor : public SemaphoreFunctor
+{
+public:
+
+ /**
+ * \brief Calls Semaphore::wait()
+ *
+ * \param [in] semaphore is a reference to Semaphore object for which Semaphore::wait() will be called
+ *
+ * \return value returned by Semaphore::wait()
+ */
+
+ int operator()(Semaphore& semaphore) const override;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SEMAPHOREWAITFUNCTOR_HPP_
diff --git a/include/distortos/internal/synchronization/SignalInformationQueue.hpp b/include/distortos/internal/synchronization/SignalInformationQueue.hpp
new file mode 100644
index 0000000..7a9d08a
--- /dev/null
+++ b/include/distortos/internal/synchronization/SignalInformationQueue.hpp
@@ -0,0 +1,123 @@
+/**
+ * \file
+ * \brief SignalInformationQueue 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_SYNCHRONIZATION_SIGNALINFORMATIONQUEUE_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SIGNALINFORMATIONQUEUE_HPP_
+
+#include "distortos/SignalInformation.hpp"
+
+#include "estd/IntrusiveForwardList.hpp"
+
+#include <memory>
+
+namespace distortos
+{
+
+class SignalSet;
+
+namespace internal
+{
+
+/// SignalInformationQueue class can be used for queuing of SignalInformation objects
+class SignalInformationQueue
+{
+public:
+
+ /// single node of internal forward list - estd::IntrusiveForwardListNode and SignalInformation
+ struct QueueNode
+ {
+ /// node for intrusive forward list
+ estd::IntrusiveForwardListNode node;
+
+ /// queued SignalInformation
+ SignalInformation signalInformation;
+ };
+
+ /// type of uninitialized storage for QueueNode
+ using Storage = typename std::aligned_storage<sizeof(QueueNode), alignof(QueueNode)>::type;
+
+ /// unique_ptr (with deleter) to Storage[]
+ using StorageUniquePointer = std::unique_ptr<Storage[], void(&)(Storage*)>;
+
+ /**
+ * \brief SignalInformationQueue's constructor
+ *
+ * \param [in] storageUniquePointer is a rvalue reference to StorageUniquePointer with storage for queue elements
+ * (sufficiently large for \a maxElements Storage objects) and appropriate deleter
+ * \param [in] maxElements is the number of elements in \a storage array
+ */
+
+ SignalInformationQueue(StorageUniquePointer&& storageUniquePointer, size_t maxElements);
+
+ /**
+ * \brief SignalInformationQueue's destructor
+ */
+
+ ~SignalInformationQueue();
+
+ /**
+ * \brief Accepts (dequeues) one of signals that are queued.
+ *
+ * This should be called when the signal is "accepted".
+ *
+ * \param [in] signalNumber is the signal that will be accepted, [0; 31]
+ *
+ * \return pair with return code (0 on success, error code otherwise) and dequeued SignalInformation object;
+ * error codes:
+ * - EAGAIN - no SignalInformation object with signal number equal to \a signalNumber was queued;
+ */
+
+ std::pair<int, SignalInformation> acceptQueuedSignal(uint8_t signalNumber);
+
+ /**
+ * \return set of currently queued signals
+ */
+
+ SignalSet getQueuedSignalSet() const;
+
+ /**
+ * \brief Adds the signalNumber and signal value (sigval union) to list of queued SignalInformation objects.
+ *
+ * \param [in] signalNumber is the signal that will be queued, [0; 31]
+ * \param [in] value is the signal value
+ *
+ * \return 0 on success, error code otherwise:
+ * - EAGAIN - no resources are available to queue the signal, \a maxElements signals are already queued;
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ int queueSignal(uint8_t signalNumber, sigval value);
+
+ SignalInformationQueue(const SignalInformationQueue&) = delete;
+ SignalInformationQueue(SignalInformationQueue&&) = default;
+ const SignalInformationQueue& operator=(const SignalInformationQueue&) = delete;
+ SignalInformationQueue& operator=(SignalInformationQueue&&) = delete;
+
+private:
+
+ /// type of container with SignalInformation objects
+ using List = estd::IntrusiveForwardList<QueueNode, &QueueNode::node>;
+
+ /// storage for queue elements
+ StorageUniquePointer storageUniquePointer_;
+
+ /// list of queued SignalInformation objects
+ List signalInformationList_;
+
+ /// list of "free" SignalInformation objects
+ List freeSignalInformationList_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SIGNALINFORMATIONQUEUE_HPP_
diff --git a/include/distortos/internal/synchronization/SignalsCatcherControlBlock.hpp b/include/distortos/internal/synchronization/SignalsCatcherControlBlock.hpp
new file mode 100644
index 0000000..6676216
--- /dev/null
+++ b/include/distortos/internal/synchronization/SignalsCatcherControlBlock.hpp
@@ -0,0 +1,213 @@
+/**
+ * \file
+ * \brief SignalsCatcherControlBlock 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_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_
+
+#include "distortos/SignalAction.hpp"
+
+#include <memory>
+
+namespace distortos
+{
+
+namespace internal
+{
+
+class SignalsReceiverControlBlock;
+class ThreadControlBlock;
+
+/// SignalsCatcherControlBlock class is a structure required by threads for "catching" and "handling" of signals
+class SignalsCatcherControlBlock
+{
+public:
+
+ /// association of signal numbers (as SignalSet) with SignalAction
+ using Association = std::pair<SignalSet, SignalAction>;
+
+ /// type of uninitialized storage for Association objects
+ using Storage = std::aligned_storage<sizeof(Association), alignof(Association)>::type;
+
+ /// unique_ptr (with deleter) to Storage[]
+ using StorageUniquePointer = std::unique_ptr<Storage[], void(&)(Storage*)>;
+
+ /**
+ * \brief SignalsCatcherControlBlock's constructor
+ *
+ * \param [in] storageUniquePointer is a rvalue reference to StorageUniquePointer with storage for Association
+ * objects (sufficiently large for \a storageSize elements) and appropriate deleter
+ * \param [in] storageSize is the number of elements in \a storage array
+ */
+
+ SignalsCatcherControlBlock(StorageUniquePointer&& storageUniquePointer, size_t storageSize);
+
+ /**
+ * \brief SignalsCatcherControlBlock's destructor
+ */
+
+ ~SignalsCatcherControlBlock();
+
+ /**
+ * \brief Hook function executed when delivery of signals is started.
+ *
+ * Clears "delivery pending" flag.
+ *
+ * \attention This function should be called only by SignalsReceiverControlBlock::deliveryOfSignalsFinishedHook().
+ */
+
+ void deliveryOfSignalsStartedHook()
+ {
+ deliveryIsPending_ = false;
+ }
+
+ /**
+ * \brief Gets SignalAction associated with given signal number.
+ *
+ * \param [in] signalNumber is the signal for which the association is requested, [0; 31]
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalAction that is associated with
+ * \a signalNumber, default-constructed object if no association was found;
+ * error codes:
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ std::pair<int, SignalAction> getAssociation(uint8_t signalNumber) const;
+
+ /**
+ * \return SignalSet with signal mask for associated thread
+ */
+
+ SignalSet getSignalMask() const
+ {
+ return signalMask_;
+ }
+
+ /**
+ * \brief Part of SignalsReceiverControlBlock::postGenerate() specific to catching unmasked signals.
+ *
+ * Requests delivery of signals to associated thread if there is some non-default signal handler for the signal.
+ *
+ * \param [in] signalNumber is the unmasked signal that was generated, [0; 31]
+ * \param [in] threadControlBlock is a reference to associated ThreadControlBlock
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ int postGenerate(uint8_t signalNumber, ThreadControlBlock& threadControlBlock);
+
+ /**
+ * \brief Sets association for given signal number.
+ *
+ * \param [in] signalNumber is the signal for which the association will be set, [0; 31]
+ * \param [in] signalAction is a reference to SignalAction that will be associated with given signal number, object
+ * in internal storage is copy-constructed
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalAction that was associated with
+ * \a signalNumber, default-constructed object if no association was found;
+ * error codes:
+ * - EAGAIN - no resources are available to associate \a signalNumber with \a signalAction;
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ std::pair<int, SignalAction> setAssociation(uint8_t signalNumber, const SignalAction& signalAction);
+
+ /**
+ * \brief Sets signal mask for associated thread.
+ *
+ * If any pending signal is unblocked and \a owner doesn't equal nullptr, then delivery of signals to associated
+ * thread will be requested.
+ *
+ * \param [in] signalMask is the SignalSet with new signal mask for associated thread
+ * \param [in] owner selects whether delivery of signals will be requested if any pending signal is unblocked
+ * (pointer to owner SignalsReceiverControlBlock object) or not (nullptr)
+ */
+
+ void setSignalMask(SignalSet signalMask, const SignalsReceiverControlBlock* owner);
+
+ SignalsCatcherControlBlock(const SignalsCatcherControlBlock&) = delete;
+ SignalsCatcherControlBlock(SignalsCatcherControlBlock&&) = default;
+ const SignalsCatcherControlBlock& operator=(const SignalsCatcherControlBlock&) = delete;
+ SignalsCatcherControlBlock& operator=(SignalsCatcherControlBlock&&) = delete;
+
+private:
+
+ /**
+ * \brief Clears association for given signal number.
+ *
+ * \param [in] signalNumber is the signal for which the association will be cleared, [0; 31]
+ *
+ * \return SignalAction that was associated with \a signalNumber, default-constructed object if no association was
+ * found
+ */
+
+ SignalAction clearAssociation(uint8_t signalNumber);
+
+ /**
+ * \brief Clears given association for given signal number.
+ *
+ * \param [in] signalNumber is the signal for which the association will be cleared, [0; 31]
+ * \param [in] association is a reference to Association object from <em>[associationsBegin_; associationsEnd_)</em>
+ * range that will be removed
+ *
+ * \return SignalAction from \a association
+ */
+
+ SignalAction clearAssociation(uint8_t signalNumber, Association& association);
+
+ /**
+ * \return pointer to first element of range of Association objects
+ */
+
+ Association* getAssociationsBegin() const
+ {
+ return reinterpret_cast<Association*>(storageUniquePointer_.get());
+ }
+
+ /**
+ * \brief Requests delivery of signals to associated thread.
+ *
+ * Delivery of signals (via special function executed in the associated thread) is requested only if it's not
+ * already pending. The thread is unblocked if it was blocked.
+ *
+ * \param [in] threadControlBlock is a reference to associated ThreadControlBlock
+ */
+
+ void requestDeliveryOfSignals(ThreadControlBlock& threadControlBlock);
+
+ /// storage for Association objects
+ StorageUniquePointer storageUniquePointer_;
+
+ /// SignalSet with signal mask for associated thread
+ SignalSet signalMask_;
+
+ /// union binds \a associationsEnd_ and \a storageBegin_ - these point to the same address
+ union
+ {
+ /// pointer to "one past the last" element of range of Association objects
+ Association* associationsEnd_;
+
+ /// pointer to first element of range of Storage objects
+ Storage* storageBegin_;
+ };
+
+ /// pointer to "one past the last" element of range of Storage objects
+ Storage* storageEnd_;
+
+ /// true if signal delivery is pending, false otherwise
+ bool deliveryIsPending_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_
diff --git a/include/distortos/internal/synchronization/SignalsReceiverControlBlock.hpp b/include/distortos/internal/synchronization/SignalsReceiverControlBlock.hpp
new file mode 100644
index 0000000..c70d79d
--- /dev/null
+++ b/include/distortos/internal/synchronization/SignalsReceiverControlBlock.hpp
@@ -0,0 +1,243 @@
+/**
+ * \file
+ * \brief SignalsReceiverControlBlock 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_SYNCHRONIZATION_SIGNALSRECEIVERCONTROLBLOCK_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SIGNALSRECEIVERCONTROLBLOCK_HPP_
+
+#include "distortos/SignalSet.hpp"
+
+#include <cstdint>
+
+union sigval;
+
+namespace distortos
+{
+
+class SignalAction;
+class SignalInformation;
+class SignalInformationQueueWrapper;
+class SignalsCatcher;
+
+namespace internal
+{
+
+class SignalInformationQueue;
+class SignalsCatcherControlBlock;
+class ThreadControlBlock;
+
+/// SignalsReceiverControlBlock class is a structure required by threads for "receiving" of signals
+class SignalsReceiverControlBlock
+{
+public:
+
+ /**
+ * \brief SignalsReceiverControlBlock's constructor
+ *
+ * \param [in] signalInformationQueueWrapper is a pointer to SignalInformationQueueWrapper for this receiver,
+ * nullptr to disable queuing of signals for this receiver
+ * \param [in] signalsCatcher is a pointer to SignalsCatcher for this receiver, nullptr if this receiver cannot
+ * catch/handle signals
+ */
+
+ explicit SignalsReceiverControlBlock(SignalInformationQueueWrapper* signalInformationQueueWrapper,
+ SignalsCatcher* signalsCatcher);
+
+ /**
+ * \brief Accepts (clears) one of signals that are pending.
+ *
+ * This should be called when the signal is "accepted".
+ *
+ * \param [in] signalNumber is the signal that will be accepted, [0; 31]
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalInformation object for accepted
+ * signal; error codes:
+ * - EAGAIN - no signal specified by \a signalNumber was pending;
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ std::pair<int, SignalInformation> acceptPendingSignal(uint8_t signalNumber);
+
+ /**
+ * \brief Hook function executed when delivery of signals is started.
+ *
+ * Calls SignalsCatcherControlBlock::deliveryOfSignalsStartedHook().
+ *
+ * \attention This function should be called only by the function that delivers signals (<em>deliverSignals()</em>).
+ *
+ * \return 0 on success, error code otherwise:
+ * - ENOTSUP - catching/handling of signals is disabled for this receiver;
+ */
+
+ int deliveryOfSignalsStartedHook() const;
+
+ /**
+ * \brief Generates signal for associated thread.
+ *
+ * Similar to pthread_kill() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html
+ *
+ * Adds the signalNumber to set of pending signals. If associated thread is currently waiting for this signal, it
+ * will be unblocked.
+ *
+ * \param [in] signalNumber is the signal that will be generated, [0; 31]
+ * \param [in] threadControlBlock is a reference to associated ThreadControlBlock
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ int generateSignal(uint8_t signalNumber, ThreadControlBlock& threadControlBlock);
+
+ /**
+ * \return set of currently pending signals
+ */
+
+ SignalSet getPendingSignalSet() const;
+
+ /**
+ * \brief Gets SignalAction associated with given signal number.
+ *
+ * Similar to sigaction() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html
+ *
+ * \param [in] signalNumber is the signal for which the association is requested, [0; 31]
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalAction that is associated with
+ * \a signalNumber, default-constructed object if no association was found;
+ * error codes:
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - catching/handling of signals is disabled for this receiver;
+ */
+
+ std::pair<int, SignalAction> getSignalAction(uint8_t signalNumber) const;
+
+ /**
+ * \brief Gets signal mask for associated thread.
+ *
+ * Similar to pthread_sigmask() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html#
+ *
+ * \return SignalSet with signal mask for associated thread
+ */
+
+ SignalSet getSignalMask() const;
+
+ /**
+ * \brief Queues signal for associated thread.
+ *
+ * Similar to sigqueue() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigqueue.html
+ *
+ * Queues the signalNumber and signal value (sigval union) in associated SignalInformationQueue object. If
+ * associated thread is currently waiting for this signal, it will be unblocked.
+ *
+ * \param [in] signalNumber is the signal that will be queued, [0; 31]
+ * \param [in] value is the signal value
+ * \param [in] threadControlBlock is a reference to associated ThreadControlBlock
+ *
+ * \return 0 on success, error code otherwise:
+ * - EAGAIN - no resources are available to queue the signal, maximal number of signals is already queued in
+ * associated SignalInformationQueue object;
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - queuing of signals is disabled for this receiver;
+ */
+
+ int queueSignal(uint8_t signalNumber, sigval value, ThreadControlBlock& threadControlBlock) const;
+
+ /**
+ * \brief Sets association for given signal number.
+ *
+ * Similar to sigaction() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html
+ *
+ * \param [in] signalNumber is the signal for which the association will be set, [0; 31]
+ * \param [in] signalAction is a reference to SignalAction that will be associated with given signal number, object
+ * in internal storage is copy-constructed
+ *
+ * \return pair with return code (0 on success, error code otherwise) and SignalAction that was associated with
+ * \a signalNumber, default-constructed object if no association was found;
+ * error codes:
+ * - EAGAIN - no resources are available to associate \a signalNumber with \a signalAction;
+ * - EINVAL - \a signalNumber value is invalid;
+ * - ENOTSUP - catching/handling of signals is disabled for this receiver;
+ */
+
+ std::pair<int, SignalAction> setSignalAction(uint8_t signalNumber, const SignalAction& signalAction);
+
+ /**
+ * \brief Sets signal mask for associated thread.
+ *
+ * Similar to pthread_sigmask() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html#
+ *
+ * \param [in] signalMask is the SignalSet with new signal mask for associated thread
+ * \param [in] requestDelivery selects whether delivery of signals will be requested if any pending signal is
+ * unblocked (true) or not (false)
+ *
+ * \return 0 on success, error code otherwise:
+ * - ENOTSUP - catching/handling of signals is disabled for this receiver;
+ */
+
+ int setSignalMask(SignalSet signalMask, bool requestDelivery);
+
+ /**
+ * \param [in] signalSet is a pointer to set of signals that will be "waited for", nullptr when wait was terminated
+ */
+
+ void setWaitingSignalSet(const SignalSet* const signalSet)
+ {
+ waitingSignalSet_ = signalSet;
+ }
+
+private:
+
+ /**
+ * \brief Checks whether signal is ignored.
+ *
+ * Signal is ignored if it has no SignalAction object associated. Signal is never ignored if catching/handling of
+ * signals is disabled for this receiver.
+ *
+ * \param [in] signalNumber is the signal for which the check will be performed, [0; 31]
+ *
+ * \return pair with return code (0 on success, error code otherwise) and boolean telling whether the signal is
+ * ignored (true) or not (false);
+ * error codes:
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ std::pair<int, bool> isSignalIgnored(uint8_t signalNumber) const;
+
+ /**
+ * \brief Actions executed after signal is "generated" with generateSignal() or queueSignal().
+ *
+ * If associated thread is currently waiting for the signal that was generated, it will be unblocked.
+ *
+ * \param [in] signalNumber is the signal that was generated, [0; 31]
+ * \param [in] threadControlBlock is a reference to associated ThreadControlBlock
+ *
+ * \return 0 on success, error code otherwise:
+ * - EINVAL - \a signalNumber value is invalid;
+ */
+
+ int postGenerate(uint8_t signalNumber, ThreadControlBlock& threadControlBlock) const;
+
+ /// set of pending signals
+ SignalSet pendingSignalSet_;
+
+ /// pointer to set of "waited for" signals, nullptr if associated thread is not waiting for any signals
+ const SignalSet* waitingSignalSet_;
+
+ /// pointer to SignalsCatcherControlBlock for this receiver, nullptr if this receiver cannot catch/handle signals
+ SignalsCatcherControlBlock* signalsCatcherControlBlock_;
+
+ /// pointer to SignalInformationQueue for this receiver, nullptr if this receiver cannot queue signals
+ SignalInformationQueue* signalInformationQueue_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SIGNALSRECEIVERCONTROLBLOCK_HPP_
diff --git a/include/distortos/internal/synchronization/SwapPopQueueFunctor.hpp b/include/distortos/internal/synchronization/SwapPopQueueFunctor.hpp
new file mode 100644
index 0000000..1009f3c
--- /dev/null
+++ b/include/distortos/internal/synchronization/SwapPopQueueFunctor.hpp
@@ -0,0 +1,74 @@
+/**
+ * \file
+ * \brief SwapPopQueueFunctor 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_SYNCHRONIZATION_SWAPPOPQUEUEFUNCTOR_HPP_
+#define INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SWAPPOPQUEUEFUNCTOR_HPP_
+
+#include "distortos/internal/synchronization/QueueFunctor.hpp"
+
+#include <utility>
+
+namespace distortos
+{
+
+namespace internal
+{
+
+/**
+ * SwapPopQueueFunctor is a functor used for popping of data from the queue using swap
+ *
+ * \tparam T is the type of data popped from the queue
+ */
+
+template<typename T>
+class SwapPopQueueFunctor : public QueueFunctor
+{
+public:
+
+ /**
+ * \brief SwapPopQueueFunctor's constructor
+ *
+ * \param [out] value is a reference to object that will be used to return popped value, its contents are swapped
+ * with the value in the queue's storage and destructed when no longer needed
+ */
+
+ constexpr explicit SwapPopQueueFunctor(T& value) :
+ value_{value}
+ {
+
+ }
+
+ /**
+ * \brief Swaps the element in the queue's storage with the value provided by user and destroys this value when no
+ * longer needed.
+ *
+ * \param [in,out] storage is a pointer to storage with element
+ */
+
+ void operator()(void* const storage) const override
+ {
+ auto& swappedValue = *reinterpret_cast<T*>(storage);
+ using std::swap;
+ swap(value_, swappedValue);
+ swappedValue.~T();
+ }
+
+private:
+
+ /// reference to object that will be used to return popped value
+ T& value_;
+};
+
+} // namespace internal
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_INTERNAL_SYNCHRONIZATION_SWAPPOPQUEUEFUNCTOR_HPP_
diff --git a/include/distortos/statistics.hpp b/include/distortos/statistics.hpp
new file mode 100644
index 0000000..68645ef
--- /dev/null
+++ b/include/distortos/statistics.hpp
@@ -0,0 +1,38 @@
+/**
+ * \file
+ * \brief statistics namespace 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_STATISTICS_HPP_
+#define INCLUDE_DISTORTOS_STATISTICS_HPP_
+
+#include <cstdint>
+
+namespace distortos
+{
+
+namespace statistics
+{
+
+/// \addtogroup statistics
+/// \{
+
+/**
+ * \return number of context switches
+ */
+
+uint64_t getContextSwitchCount();
+
+/// \}
+
+} // namespace statistics
+
+} // namespace distortos
+
+#endif // INCLUDE_DISTORTOS_STATISTICS_HPP_
diff --git a/include/estd/ContiguousRange.hpp b/include/estd/ContiguousRange.hpp
new file mode 100644
index 0000000..adfc8a0
--- /dev/null
+++ b/include/estd/ContiguousRange.hpp
@@ -0,0 +1,164 @@
+/**
+ * \file
+ * \brief ContiguousRange template 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 ESTD_CONTIGUOUSRANGE_HPP_
+#define ESTD_CONTIGUOUSRANGE_HPP_
+
+#include <iterator>
+
+namespace estd
+{
+
+/**
+ * \brief ContiguousRange template class is a pair of iterators to contiguous sequence of elements in memory
+ *
+ * \tparam T is the type of data in the range
+ */
+
+template<typename T>
+class ContiguousRange
+{
+public:
+
+ /// value_type type
+ using value_type = T;
+
+ /// pointer type
+ using pointer = value_type*;
+
+ /// const_pointer type
+ using const_pointer = const value_type*;
+
+ /// reference type
+ using reference = value_type&;
+
+ /// const_reference type
+ using const_reference = const value_type&;
+
+ /// iterator type
+ using iterator = value_type*;
+
+ /// const_iterator type
+ using const_iterator = const value_type*;
+
+ /// size_type type
+ using size_type = std::size_t;
+
+ /// difference_type type
+ using difference_type = std::ptrdiff_t;
+
+ /// reverse_iterator type
+ using reverse_iterator = std::reverse_iterator<iterator>;
+
+ /// const_reverse_iterator type
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+ /**
+ * \brief ContiguousRange's constructor.
+ *
+ * \param [in] beginn is an iterator to first element in the range
+ * \param [in] endd is an iterator to "one past the last" element in the range
+ */
+
+ constexpr ContiguousRange(const iterator beginn, const iterator endd) noexcept :
+ begin_{beginn},
+ end_{endd}
+ {
+
+ }
+
+ /**
+ * \brief Empty ContiguousRange's constructor.
+ */
+
+ constexpr explicit ContiguousRange() noexcept :
+ ContiguousRange{nullptr, nullptr}
+ {
+
+ }
+
+ /**
+ * \brief ContiguousRange's constructor using C-style array.
+ *
+ * \tparam N is the number of elements in the array
+ *
+ * \param [in] array is the array used to initialize the range
+ */
+
+ template<size_t N>
+ constexpr explicit ContiguousRange(T (& array)[N]) noexcept :
+ ContiguousRange{array, array + N}
+ {
+
+ }
+
+ /**
+ * \brief ContiguousRange's constructor using single value
+ *
+ * \param [in] value is a reference to variable used to initialize the range
+ */
+
+ constexpr explicit ContiguousRange(T& value) noexcept :
+ ContiguousRange{&value, &value + 1}
+ {
+
+ }
+
+ /**
+ * \return iterator to first element in the range
+ */
+
+ constexpr iterator begin() const noexcept
+ {
+ return begin_;
+ }
+
+ /**
+ * \return iterator to "one past the last" element in the range
+ */
+
+ constexpr iterator end() const noexcept
+ {
+ return end_;
+ }
+
+ /**
+ * \return number of elements in the range
+ */
+
+ constexpr size_type size() const noexcept
+ {
+ return end_ - begin_;
+ }
+
+ /**
+ * \param [in] i is the index of element that will be accessed
+ *
+ * \return reference to element at given index
+ */
+
+ reference operator[](const size_type i) const noexcept
+ {
+ return begin_[i];
+ }
+
+private:
+
+ /// iterator to first element in the range
+ iterator begin_;
+
+ /// iterator to "one past the last" element in the range
+ iterator end_;
+};
+
+} // namespace estd
+
+#endif // ESTD_CONTIGUOUSRANGE_HPP_
diff --git a/include/estd/IntegerSequence.hpp b/include/estd/IntegerSequence.hpp
new file mode 100644
index 0000000..a0776f5
--- /dev/null
+++ b/include/estd/IntegerSequence.hpp
@@ -0,0 +1,229 @@
+/**
+ * \file
+ * \brief IntegerSequence template 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 ESTD_INTEGERSEQUENCE_HPP_
+#define ESTD_INTEGERSEQUENCE_HPP_
+
+#include <type_traits>
+
+namespace estd
+{
+
+/**
+ * \brief Compile-time sequence of integers
+ *
+ * Similar to std::integer_sequence from C++14 - http://en.cppreference.com/w/cpp/utility/integer_sequence
+ *
+ * \tparam T is an integer type to use for the elements of the sequence
+ * \tparam Integers is a non-type parameter pack representing the sequence
+ */
+
+template<typename T, T... Integers>
+class IntegerSequence
+{
+public:
+
+ /// integer type used for the elements of the sequence
+ using value_type = T;
+
+ /**
+ * \return number of elements in the sequence
+ */
+
+ constexpr static std::size_t size() noexcept
+ {
+ return sizeof...(Integers);
+ };
+};
+
+/**
+ * \brief Compile-time sequence of std::size_t elements
+ *
+ * Similar to std::index_sequence from C++14 - http://en.cppreference.com/w/cpp/utility/integer_sequence
+ *
+ * \tparam Indexes is a non-type parameter pack representing the sequence
+ */
+
+template<std::size_t... Indexes>
+using IndexSequence = IntegerSequence<std::size_t, Indexes...>;
+
+namespace internal
+{
+
+/**
+ * \brief IntegerSequence with two internal type aliases.
+ *
+ * \tparam T is an integer type to use for the elements of the sequence
+ * \tparam Integers is a non-type parameter pack representing the sequence
+ */
+
+template<typename T, T... Integers>
+struct TypedSequence : IntegerSequence<T, Integers...>
+{
+ /// type of base class
+ using base = IntegerSequence<T, Integers...>;
+
+ /// type of class
+ using type = TypedSequence;
+};
+
+/**
+ * \brief TypedSequence with doubled number of elements
+ *
+ * \tparam Sequence is the type of sequence that will be doubled
+ */
+
+template<typename Sequence>
+struct DoubledIntegerSequence;
+
+/**
+ * \brief TypedSequence with doubled number of elements
+ *
+ * Specialization for TypedSequence.
+ *
+ * \tparam T is an integer type to use for the elements of the sequence
+ * \tparam Integers is a non-type parameter pack representing the sequence
+ */
+
+template<typename T, T... Integers>
+struct DoubledIntegerSequence<TypedSequence<T, Integers...>>
+{
+ /// TypedSequence with doubled number of elements - TypedSequence<T, 0, 1, ..., N - 1> is turned into
+ /// TypedSequence<T, 0, 1, ..., N - 1, N, N + 1, ..., 2 * N - 1>
+ using type = TypedSequence<T, Integers..., (sizeof...(Integers) + Integers)...>;
+};
+
+/**
+ * \brief TypedSequence optionally extended by one element
+ *
+ * \tparam Extend selects whether the sequence will be extended by one element (true) or not (false)
+ * \tparam Sequence is the type of sequence that will optionally be extended
+ */
+
+template<bool Extend, typename Sequence>
+struct ExtendedIntegerSequence
+{
+ /// same as \a Sequence
+ using type = Sequence;
+};
+
+/**
+ * \brief TypedSequence optionally extended by one element
+ *
+ * Specialization for the case with extending.
+ *
+ * \tparam T is an integer type to use for the elements of the sequence
+ * \tparam Integers is a non-type parameter pack representing the sequence
+ */
+
+template<typename T, T... Integers>
+struct ExtendedIntegerSequence<true, TypedSequence<T, Integers...>>
+{
+ /// sequence extended by one element - TypedSequence<T, 0, 1, ..., N - 1> is turned into
+ /// TypedSequence<T, 0, 1, ..., N - 1, N>
+ using type = TypedSequence<T, Integers..., sizeof...(Integers)>;
+};
+
+/**
+ * \brief Implementation of generator of IntegerSequence types
+ *
+ * Generates TypedSequence<T, 0, 1, ..., N - 1> type.
+ *
+ * \tparam T is an integer type to use for the elements of the sequence
+ * \tparam N is the requested number of elements in the sequence
+ */
+
+template<typename T, std::size_t N>
+struct MakeIntegerSequenceImplementation :
+ ExtendedIntegerSequence<N % 2 != 0,
+ typename DoubledIntegerSequence<typename MakeIntegerSequenceImplementation<T, N / 2>::type>::type>
+{
+
+};
+
+/**
+ * \brief Implementation of generator of IntegerSequence types
+ *
+ * Specialization for terminal case - 0 elements - generates TypedSequence<T> type.
+ *
+ * \tparam T is an integer type to use for the elements of the sequence
+ */
+
+template<typename T>
+struct MakeIntegerSequenceImplementation<T, 0>
+{
+ /// empty TypedSequence<T> type
+ using type = TypedSequence<T>;
+};
+
+/**
+ * \brief Wrapper for MakeIntegerSequenceImplementation that ensures \a N is non-negative
+ *
+ * Generates TypedSequence<T, 0, 1, ..., N - 1> type.
+ *
+ * \tparam T is an integer type to use for the elements of the sequence
+ * \tparam N is the requested number of elements in the sequence, must be non-negative
+ */
+
+template<typename T, T N>
+struct MakeIntegerSequenceImplementationWrapper :
+ std::enable_if<N >= 0, MakeIntegerSequenceImplementation<T, static_cast<std::size_t>(N)>>::type
+{
+ static_assert(N >= 0, "Number of elements in the sequence must be non-negative!");
+};
+
+} // namespace internal
+
+/**
+ * \brief Generator of IntegerSequence types
+ *
+ * Similar to std::make_integer_sequence from C++14 - http://en.cppreference.com/w/cpp/utility/integer_sequence
+ *
+ * Whole implementation is based on code from http://stackoverflow.com/a/20101039/157344
+ *
+ * Generates IntegerSequence<T, 0, 1, ..., N - 1> type.
+ *
+ * \tparam T is an integer type to use for the elements of the sequence
+ * \tparam N is the requested number of elements in the sequence
+ */
+
+template<typename T, T N>
+using MakeIntegerSequence = typename internal::MakeIntegerSequenceImplementationWrapper<T, N>::type::base;
+
+/**
+ * \brief Generator of IndexSequence types
+ *
+ * Similar to std::make_index_sequence from C++14 - http://en.cppreference.com/w/cpp/utility/integer_sequence
+ *
+ * Generates IndexSequence<0, 1, ..., N - 1> type.
+ *
+ * \tparam N is the requested number of elements in the sequence
+ */
+
+template<std::size_t N>
+using MakeIndexSequence = MakeIntegerSequence<std::size_t, N>;
+
+/**
+ * \brief Generator of IndexSequence types
+ *
+ * Similar to std::index_sequence_for from C++14 - http://en.cppreference.com/w/cpp/utility/integer_sequence
+ *
+ * Generates IndexSequence<0, 1, ..., sizeof...(T) - 1> type.
+ *
+ * \tparam T is the type parameter pack for which an index sequence of the same length will be generated
+ */
+
+template<typename... T>
+using IndexSequenceFor = MakeIndexSequence<sizeof...(T)>;
+
+} // namespace estd
+
+#endif // ESTD_INTEGERSEQUENCE_HPP_
diff --git a/include/estd/IntrusiveForwardList.hpp b/include/estd/IntrusiveForwardList.hpp
new file mode 100644
index 0000000..faa98d1
--- /dev/null
+++ b/include/estd/IntrusiveForwardList.hpp
@@ -0,0 +1,1120 @@
+/**
+ * \file
+ * \brief IntrusiveForwardList template 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 ESTD_INTRUSIVEFORWARDLIST_HPP_
+#define ESTD_INTRUSIVEFORWARDLIST_HPP_
+
+#include <iterator>
+
+#include <cstddef>
+
+namespace estd
+{
+
+namespace internal
+{
+
+class IntrusiveForwardListBase;
+
+}
+
+/**
+ * \brief IntrusiveForwardListNode class is the node that is needed for the object to be linked in IntrusiveForwardList
+ *
+ * To some extent, this class can be considered to be a limited (raw) iterator.
+ *
+ * The object that wants to be linked in IntrusiveForwardList must contain a variable of this type - one for each
+ * intrusive forward list that will be used with object.
+ */
+
+class IntrusiveForwardListNode
+{
+public:
+
+ /// AccessKey class is used to limit access to IntrusiveForwardListNode's linkAfter() and unlinkNext() functions -
+ /// only internal::IntrusiveForwardListBase can link/unlink nodes
+ class AccessKey
+ {
+ friend class internal::IntrusiveForwardListBase;
+
+ /**
+ * \brief AccessKey's constructor
+ */
+
+ constexpr AccessKey()
+ {
+
+ }
+
+ AccessKey(const AccessKey&) = delete;
+ AccessKey(AccessKey&&) = delete;
+ const AccessKey& operator=(const AccessKey&) = delete;
+ AccessKey& operator=(AccessKey&&) = delete;
+ };
+
+ /**
+ * \brief IntrusiveForwardListNode's constructor
+ */
+
+ constexpr IntrusiveForwardListNode() :
+ nextNode_{}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveForwardListNode's move constructor
+ *
+ * \param [in] other is a rvalue reference to IntrusiveForwardListNode used as source of move construction
+ */
+
+ IntrusiveForwardListNode(IntrusiveForwardListNode&& other) :
+ nextNode_{other.nextNode_}
+ {
+ other.reset();
+ }
+
+ /**
+ * \return pointer to next node on the list
+ */
+
+ IntrusiveForwardListNode* getNextNode() const
+ {
+ return nextNode_;
+ }
+
+ /**
+ * \return true if the node is linked in some list, false otherwise
+ */
+
+ bool isLinked() const
+ {
+ return nextNode_ != nullptr;
+ }
+
+ /**
+ * \brief Links the node in the list after \a position.
+ *
+ * \note Access to this function is restricted only to functions from internal::IntrusiveForwardListBase class
+ *
+ * \param [in] position is a pointer to node after which this node will be linked
+ * \param [in] accessKey is used to limit access to this function
+ */
+
+ void linkAfter(IntrusiveForwardListNode* const position, AccessKey)
+ {
+ nextNode_ = position->getNextNode();
+ position->nextNode_ = this;
+ }
+
+ /**
+ * \brief Swaps contents with another node.
+ *
+ * \param [in] other is a reference to IntrusiveForwardListNode with which contents of this node will be swapped
+ */
+
+ void swap(IntrusiveForwardListNode& other)
+ {
+ using std::swap;
+ swap(nextNode_, other.nextNode_);
+ }
+
+ /**
+ * \brief Unlinks the node following this one from the list.
+ *
+ * \note Access to this function is restricted only to functions from internal::IntrusiveForwardListBase class
+ *
+ * \param [in] accessKey is used to limit access to this function
+ */
+
+ void unlinkNext(AccessKey)
+ {
+ auto& nextNode = *nextNode_;
+ nextNode_ = nextNode.nextNode_;
+
+ nextNode.reset();
+ }
+
+ IntrusiveForwardListNode(const IntrusiveForwardListNode&) = delete;
+ const IntrusiveForwardListNode& operator=(const IntrusiveForwardListNode&) = delete;
+ IntrusiveForwardListNode& operator=(IntrusiveForwardListNode&&) = delete;
+
+private:
+
+ /**
+ * \brief Resets the node to the same state as right after construction.
+ */
+
+ void reset()
+ {
+ nextNode_ = {};
+ }
+
+ /// pointer to next node on the list
+ IntrusiveForwardListNode* nextNode_;
+};
+
+/**
+ * \brief Swaps contents of two nodes.
+ *
+ * \param [in] left is a reference to IntrusiveForwardListNode with which contents of \a right will be swapped
+ * \param [in] right is a reference to IntrusiveForwardListNode with which contents of \a left will be swapped
+ */
+
+inline void swap(IntrusiveForwardListNode& left, IntrusiveForwardListNode& right)
+{
+ left.swap(right);
+}
+
+namespace internal
+{
+
+/**
+ * \brief IntrusiveForwardListBase class provides base functionalities for IntrusiveForwardList class, but without any
+ * knowledge about types
+ *
+ * This class tries to provide an interface similar to std::forward_list.
+ */
+
+class IntrusiveForwardListBase
+{
+public:
+
+ /**
+ * \brief IntrusiveForwardListBase's constructor
+ */
+
+ constexpr IntrusiveForwardListBase() :
+ rootNode_{}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveForwardListBase's destructor
+ *
+ * Unlinks all nodes from the list.
+ */
+
+ ~IntrusiveForwardListBase()
+ {
+ clear();
+ }
+
+ /**
+ * \return pointer to "one before the first" node on the list
+ */
+
+ IntrusiveForwardListNode* before_begin()
+ {
+ return &rootNode_;
+ }
+
+ /**
+ * \return const pointer to "one before the first" node on the list
+ */
+
+ const IntrusiveForwardListNode* before_begin() const
+ {
+ return &rootNode_;
+ }
+
+ /**
+ * \return pointer to first node on the list
+ */
+
+ IntrusiveForwardListNode* begin()
+ {
+ return rootNode_.getNextNode();
+ }
+
+ /**
+ * \return const pointer to first node on the list
+ */
+
+ const IntrusiveForwardListNode* begin() const
+ {
+ return rootNode_.getNextNode();
+ }
+
+ /**
+ * \return const pointer to "one before the first" node on the list
+ */
+
+ const IntrusiveForwardListNode* cbefore_begin() const
+ {
+ return before_begin();
+ }
+
+ /**
+ * \return const pointer to first node on the list
+ */
+
+ const IntrusiveForwardListNode* cbegin() const
+ {
+ return begin();
+ }
+
+ /**
+ * \return const pointer to "one past the last" node on the list
+ */
+
+ const IntrusiveForwardListNode* cend() const
+ {
+ return end();
+ }
+
+ /**
+ * \brief Unlinks all nodes from the list.
+ */
+
+ void clear()
+ {
+ while (empty() == false)
+ pop_front();
+ }
+
+ /**
+ * \return true is the list is empty, false otherwise
+ */
+
+ bool empty() const
+ {
+ return begin() == end();
+ }
+
+ /**
+ * \return pointer to "one past the last" node on the list
+ */
+
+ IntrusiveForwardListNode* end()
+ {
+ return nullptr;
+ }
+
+ /**
+ * \return const pointer to "one past the last" node on the list
+ */
+
+ const IntrusiveForwardListNode* end() const
+ {
+ return nullptr;
+ }
+
+ /**
+ * \brief Unlinks the first node from the list.
+ */
+
+ void pop_front()
+ {
+ erase_after(before_begin());
+ }
+
+ /**
+ * \brief Links the node at the beginning of the list.
+ *
+ * \param [in] newNode is a reference to node that will be linked in the list
+ */
+
+ void push_front(IntrusiveForwardListNode& newNode)
+ {
+ insert_after(before_begin(), newNode);
+ }
+
+ /**
+ * \brief Swaps contents with another list.
+ *
+ * \param [in] other is a reference to IntrusiveForwardListBase with which contents of this list will be swapped
+ */
+
+ void swap(IntrusiveForwardListBase& other)
+ {
+ rootNode_.swap(other.rootNode_);
+ }
+
+ /**
+ * \brief Unlinks the node following \a position from the list.
+ *
+ * \note No instance of the list is needed for this operation.
+ *
+ * \param [in] position is a pointer to the node preceding the one which will be unlinked from the list
+ *
+ * \return pointer to the node that was following the node which was unlinked
+ */
+
+ static IntrusiveForwardListNode* erase_after(IntrusiveForwardListNode* const position)
+ {
+ position->unlinkNext({});
+ return position->getNextNode();
+ }
+
+ /**
+ * \brief Links the node in the list after \a position.
+ *
+ * \note No instance of the list is needed for this operation.
+ *
+ * \param [in] position is a pointer to node after which \a newNode will be linked
+ * \param [in] newNode is a reference to node that will be linked in the list
+ */
+
+ static void insert_after(IntrusiveForwardListNode* const position, IntrusiveForwardListNode& newNode)
+ {
+ newNode.linkAfter(position, {});
+ }
+
+ /**
+ * \brief Transfers the node from one list to another list after \a position.
+ *
+ * \note No instance of any list is needed for this operation.
+ *
+ * \param [in] position is a pointer to node after which spliced node will be linked
+ * \param [in] beforeSplicedNode is a pointer to node preceding the one which will be spliced from one list to
+ * another
+ */
+
+ static void splice_after(IntrusiveForwardListNode* const position,
+ IntrusiveForwardListNode* const beforeSplicedNode)
+ {
+ const auto splicedNode = beforeSplicedNode->getNextNode();
+ erase_after(beforeSplicedNode);
+ insert_after(position, *splicedNode);
+ }
+
+ IntrusiveForwardListBase(const IntrusiveForwardListBase&) = delete;
+ IntrusiveForwardListBase(IntrusiveForwardListBase&&) = default;
+ const IntrusiveForwardListBase& operator=(const IntrusiveForwardListBase&) = delete;
+ IntrusiveForwardListBase& operator=(IntrusiveForwardListBase&&) = delete;
+
+private:
+
+ /// root node of the intrusive forward list
+ IntrusiveForwardListNode rootNode_;
+};
+
+/**
+ * \brief Swaps contents of two lists.
+ *
+ * \param [in] left is a reference to IntrusiveForwardListBase with which contents of \a right will be swapped
+ * \param [in] right is a reference to IntrusiveForwardListBase with which contents of \a left will be swapped
+ */
+
+inline void swap(IntrusiveForwardListBase& left, IntrusiveForwardListBase& right)
+{
+ left.swap(right);
+}
+
+} // namespace internal
+
+/**
+ * \brief IntrusiveForwardListIterator class is an iterator of elements on IntrusiveForwardList.
+ *
+ * This class provides an interface similar to std::forward_list::iterator.
+ *
+ * \tparam T is the type that has the IntrusiveForwardListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ */
+
+template<typename T, IntrusiveForwardListNode T::* NodePointer, typename U = T>
+class IntrusiveForwardListIterator
+{
+public:
+
+ /// difference type
+ using difference_type = ptrdiff_t;
+
+ /// category of the iterator
+ using iterator_category = std::forward_iterator_tag;
+
+ /// pointer to object "pointed to" by the iterator
+ using pointer = U*;
+
+ /// reference to object "pointed to" by the iterator
+ using reference = U&;
+
+ /// value "pointed to" by the iterator
+ using value_type = U;
+
+ /**
+ * \brief IntrusiveForwardListIterator's constructor
+ */
+
+ constexpr IntrusiveForwardListIterator() :
+ node_{}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveForwardListIterator's constructor
+ *
+ * \param [in] node is a pointer to IntrusiveForwardListNode of element that will be "pointed to" by the iterator
+ */
+
+ constexpr explicit IntrusiveForwardListIterator(IntrusiveForwardListNode* const node) :
+ node_{node}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveForwardListIterator's constructor
+ *
+ * \param [in] element is a reference to element that will be "pointed to" by the iterator
+ */
+
+ constexpr explicit IntrusiveForwardListIterator(reference element) :
+ node_{&(element.*NodePointer)}
+ {
+ static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!");
+ }
+
+ /**
+ * \brief IntrusiveForwardListIterator's binary infix pointer member access operator
+ *
+ * \return pointer to object "pointed to" by the iterator
+ */
+
+ pointer operator->() const
+ {
+ return getPointer();
+ }
+
+ /**
+ * \brief IntrusiveForwardListIterator's unary prefix dereference operator
+ *
+ * \return reference to object "pointed to" by the iterator
+ */
+
+ reference operator*() const
+ {
+ return *getPointer();
+ }
+
+ /**
+ * \brief IntrusiveForwardListIterator's unary prefix increment operator
+ *
+ * \return reference to "this" iterator
+ */
+
+ IntrusiveForwardListIterator& operator++()
+ {
+ node_ = node_->getNextNode();
+ return *this;
+ }
+
+ /**
+ * \brief IntrusiveForwardListIterator's unary postfix increment operator
+ *
+ * \return copy of "this" iterator before increment
+ */
+
+ IntrusiveForwardListIterator operator++(int)
+ {
+ const auto temporary = *this;
+ node_ = node_->getNextNode();
+ return temporary;
+ }
+
+ /**
+ * \brief IntrusiveForwardListIterator's "equal to" comparison operator
+ *
+ * \param [in] other is a const reference to IntrusiveForwardListIterator on right-hand side of equality operator
+ *
+ * \return true if both iterators are equal, false otherwise
+ */
+
+ bool operator==(const IntrusiveForwardListIterator& other) const
+ {
+ return node_ == other.node_;
+ }
+
+private:
+
+ /**
+ * \brief Converts contained pointer to IntrusiveForwardListNode to pointer to object that contains this node.
+ *
+ * \return pointer to object "pointed to" by the iterator
+ */
+
+ pointer getPointer() const
+ {
+ static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!");
+
+ const auto offset = reinterpret_cast<size_t>(&(static_cast<pointer>(nullptr)->*NodePointer));
+ return reinterpret_cast<pointer>(reinterpret_cast<size_t>(node_) - offset);
+ }
+
+ /// pointer to IntrusiveForwardListNode of the object "pointed to" by the iterator
+ IntrusiveForwardListNode* node_;
+};
+
+/**
+ * \brief IntrusiveForwardListIterator's "not equal to" comparison operator
+ *
+ * \tparam T is the type that has the IntrusiveForwardListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a const reference to IntrusiveForwardListIterator on left-hand side of comparison operator
+ * \param [in] right is a const reference to IntrusiveForwardListIterator on right-hand side of comparison operator
+ *
+ * \return true if iterators are not equal, false otherwise
+ */
+
+template<typename T, IntrusiveForwardListNode T::* NodePointer, typename U = T>
+inline bool operator!=(const IntrusiveForwardListIterator<T, NodePointer, U>& left,
+ const IntrusiveForwardListIterator<T, NodePointer, U>& right)
+{
+ return (left == right) == false;
+}
+
+/**
+ * \brief IntrusiveForwardListConstIterator class is a const iterator of elements on IntrusiveForwardList.
+ *
+ * This class provides an interface similar to std::forward_list::const_iterator.
+ *
+ * \tparam T is the type that has the IntrusiveForwardListNode variable
+ * \tparam NodePointer is a const pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ */
+
+template<typename T, const IntrusiveForwardListNode T::* NodePointer, typename U = T>
+class IntrusiveForwardListConstIterator
+{
+public:
+
+ /// difference type
+ using difference_type = ptrdiff_t;
+
+ /// category of the iterator
+ using iterator_category = std::forward_iterator_tag;
+
+ /// pointer to object "pointed to" by the iterator
+ using pointer = const U*;
+
+ /// reference to object "pointed to" by the iterator
+ using reference = const U&;
+
+ /// value "pointed to" by the iterator
+ using value_type = U;
+
+ /**
+ * \brief IntrusiveForwardListConstIterator's constructor
+ */
+
+ constexpr IntrusiveForwardListConstIterator() :
+ node_{}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveForwardListConstIterator's constructor
+ *
+ * \param [in] node is a pointer to const IntrusiveForwardListNode of element that will be "pointed to" by the
+ * iterator
+ */
+
+ constexpr explicit IntrusiveForwardListConstIterator(const IntrusiveForwardListNode* const node) :
+ node_{node}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveForwardListConstIterator's constructor
+ *
+ * \param [in] element is a const reference to element that will be "pointed to" by the iterator
+ */
+
+ constexpr explicit IntrusiveForwardListConstIterator(reference element) :
+ node_{&(element.*NodePointer)}
+ {
+ static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!");
+ }
+
+ /**
+ * \brief IntrusiveForwardListConstIterator's constructor
+ *
+ * Converts non-const iterator (IntrusiveForwardListIterator) to const iterator (IntrusiveForwardListConstIterator).
+ *
+ * \tparam NonConstNodePointer is a non-const version of \a NodePointer
+ *
+ * \param [in] iterator is a const reference to non-const iterator (IntrusiveForwardListIterator)
+ */
+
+ template<IntrusiveForwardListNode T::* NonConstNodePointer>
+ constexpr
+ IntrusiveForwardListConstIterator(const IntrusiveForwardListIterator<T, NonConstNodePointer, U>& iterator) :
+ IntrusiveForwardListConstIterator{*iterator}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveForwardListConstIterator's binary infix pointer member access operator
+ *
+ * \return pointer to object "pointed to" by the iterator
+ */
+
+ pointer operator->() const
+ {
+ return getPointer();
+ }
+
+ /**
+ * \brief IntrusiveForwardListConstIterator's unary prefix dereference operator
+ *
+ * \return reference to object "pointed to" by the iterator
+ */
+
+ reference operator*() const
+ {
+ return *getPointer();
+ }
+
+ /**
+ * \brief IntrusiveForwardListConstIterator's unary prefix increment operator
+ *
+ * \return reference to "this" iterator
+ */
+
+ IntrusiveForwardListConstIterator& operator++()
+ {
+ node_ = node_->getNextNode();
+ return *this;
+ }
+
+ /**
+ * \brief IntrusiveForwardListConstIterator's unary postfix increment operator
+ *
+ * \return copy of "this" iterator before increment
+ */
+
+ IntrusiveForwardListConstIterator operator++(int)
+ {
+ const auto temporary = *this;
+ node_ = node_->getNextNode();
+ return temporary;
+ }
+
+ /**
+ * \brief IntrusiveForwardListConstIterator's "equal to" comparison operator
+ *
+ * \param [in] other is a const reference to IntrusiveForwardListConstIterator on right-hand side of equality
+ * operator
+ *
+ * \return true if both iterators are equal, false otherwise
+ */
+
+ bool operator==(const IntrusiveForwardListConstIterator& other) const
+ {
+ return node_ == other.node_;
+ }
+
+private:
+
+ /**
+ * \brief Converts contained pointer to IntrusiveForwardListNode to pointer to object that contains this node.
+ *
+ * \return pointer to object "pointed to" by the iterator
+ */
+
+ pointer getPointer() const
+ {
+ static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!");
+
+ const auto offset = reinterpret_cast<size_t>(&(static_cast<pointer>(nullptr)->*NodePointer));
+ return reinterpret_cast<pointer>(reinterpret_cast<size_t>(node_) - offset);
+ }
+
+ /// pointer to const IntrusiveForwardListNode of the object "pointed to" by the iterator
+ const IntrusiveForwardListNode* node_;
+};
+
+/**
+ * \brief IntrusiveForwardListConstIterator's "not equal to" comparison operator
+ *
+ * \tparam T is the type that has the IntrusiveForwardListNode variable
+ * \tparam NodePointer is a const pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a const reference to IntrusiveForwardListConstIterator on left-hand side of comparison operator
+ * \param [in] right is a const reference to IntrusiveForwardListConstIterator on right-hand side of comparison operator
+ *
+ * \return true if iterators are not equal, false otherwise
+ */
+
+template<typename T, const IntrusiveForwardListNode T::* NodePointer, typename U = T>
+inline bool operator!=(const IntrusiveForwardListConstIterator<T, NodePointer, U>& left,
+ const IntrusiveForwardListConstIterator<T, NodePointer, U>& right)
+{
+ return (left == right) == false;
+}
+
+/**
+ * \brief "Equal to" comparison operator for IntrusiveForwardListIterator and IntrusiveForwardListConstIterator
+ *
+ * \tparam T is the type that has the IntrusiveForwardListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam ConstNodePointer is a const pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a const reference to IntrusiveForwardListIterator on left-hand side of comparison operator
+ * \param [in] right is a const reference to IntrusiveForwardListConstIterator on right-hand side of comparison operator
+ *
+ * \return true if both iterators are equal, false otherwise
+ */
+
+template<typename T, IntrusiveForwardListNode T::* NodePointer, const IntrusiveForwardListNode T::* ConstNodePointer,
+ typename U = T>
+inline bool operator==(const IntrusiveForwardListIterator<T, NodePointer, U>& left,
+ const IntrusiveForwardListConstIterator<T, ConstNodePointer, U>& right)
+{
+ return decltype(right){left} == right;
+}
+
+/**
+ * \brief "Not equal to" comparison operator for IntrusiveForwardListIterator and IntrusiveForwardListConstIterator
+ *
+ * \tparam T is the type that has the IntrusiveForwardListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam ConstNodePointer is a const pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a const reference to IntrusiveForwardListIterator on left-hand side of comparison operator
+ * \param [in] right is a const reference to IntrusiveForwardListConstIterator on right-hand side of comparison operator
+ *
+ * \return true if iterators are not equal, false otherwise
+ */
+
+template<typename T, IntrusiveForwardListNode T::* NodePointer, const IntrusiveForwardListNode T::* ConstNodePointer,
+ typename U = T>
+inline bool operator!=(const IntrusiveForwardListIterator<T, NodePointer, U>& left,
+ const IntrusiveForwardListConstIterator<T, ConstNodePointer, U>& right)
+{
+ return (left == right) == false;
+}
+
+/**
+ * \brief "Not equal to" comparison operator for IntrusiveForwardListConstIterator and IntrusiveForwardListIterator
+ *
+ * \tparam T is the type that has the IntrusiveForwardListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam ConstNodePointer is a const pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a const reference to IntrusiveForwardListConstIterator on left-hand side of comparison operator
+ * \param [in] right is a const reference to IntrusiveForwardListIterator on right-hand side of comparison operator
+ *
+ * \return true if iterators are not equal, false otherwise
+ */
+
+template<typename T, IntrusiveForwardListNode T::* NodePointer, const IntrusiveForwardListNode T::* ConstNodePointer,
+ typename U = T>
+inline bool operator!=(const IntrusiveForwardListConstIterator<T, ConstNodePointer, U>& left,
+ const IntrusiveForwardListIterator<T, NodePointer, U>& right)
+{
+ return right != left;
+}
+
+/**
+ * \brief IntrusiveForwardList class is an intrusive linear singly linked list.
+ *
+ * This class tries to provide an interface similar to std::forward_list.
+ *
+ * \tparam T is the type that has the IntrusiveForwardListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T; using different type than \a T can be used
+ * to break circular dependencies, because \a T must be fully defined to instantiate this class, but it is enough to
+ * forward declare \a U - it only needs to be fully defined to use member functions
+ */
+
+template<typename T, IntrusiveForwardListNode T::* NodePointer, typename U = T>
+class IntrusiveForwardList
+{
+public:
+
+ /// const iterator of elements on the list
+ using const_iterator = IntrusiveForwardListConstIterator<T, NodePointer, U>;
+
+ /// const pointer to value linked in the list
+ using const_pointer = const U*;
+
+ /// const reference to value linked in the list
+ using const_reference = const U&;
+
+ /// iterator of elements on the list
+ using iterator = IntrusiveForwardListIterator<T, NodePointer, U>;
+
+ /// pointer to value linked in the list
+ using pointer = U*;
+
+ /// reference to value linked in the list
+ using reference = U&;
+
+ /// value linked in the list
+ using value_type = U;
+
+ /**
+ * \brief IntrusiveForwardList's constructor
+ */
+
+ constexpr IntrusiveForwardList() :
+ intrusiveForwardListBase_{}
+ {
+
+ }
+
+ /**
+ * \return iterator of "one before the first" element on the list
+ */
+
+ iterator before_begin()
+ {
+ return iterator{intrusiveForwardListBase_.before_begin()};
+ }
+
+ /**
+ * \return const iterator of "one before the first" element on the list
+ */
+
+ const_iterator before_begin() const
+ {
+ return const_iterator{intrusiveForwardListBase_.before_begin()};
+ }
+
+ /**
+ * \return iterator of first element on the list
+ */
+
+ iterator begin()
+ {
+ return iterator{intrusiveForwardListBase_.begin()};
+ }
+
+ /**
+ * \return const iterator of first element on the list
+ */
+
+ const_iterator begin() const
+ {
+ return const_iterator{intrusiveForwardListBase_.begin()};
+ }
+
+ /**
+ * \return const iterator of "one before the first" element on the list
+ */
+
+ const_iterator cbefore_begin() const
+ {
+ return before_begin();
+ }
+
+ /**
+ * \return const iterator of first element on the list
+ */
+
+ const_iterator cbegin() const
+ {
+ return begin();
+ }
+
+ /**
+ * \return const iterator of "one past the last" element on the list
+ */
+
+ const_iterator cend() const
+ {
+ return end();
+ }
+
+ /**
+ * \brief Unlinks all elements from the list.
+ */
+
+ void clear()
+ {
+ intrusiveForwardListBase_.clear();
+ }
+
+ /**
+ * \return true is the list is empty, false otherwise
+ */
+
+ bool empty() const
+ {
+ return intrusiveForwardListBase_.empty();
+ }
+
+ /**
+ * \return iterator of "one past the last" element on the list
+ */
+
+ iterator end()
+ {
+ return iterator{intrusiveForwardListBase_.end()};
+ }
+
+ /**
+ * \return const iterator of "one past the last" element on the list
+ */
+
+ const_iterator end() const
+ {
+ return const_iterator{intrusiveForwardListBase_.end()};
+ }
+
+ /**
+ * \return reference to first element on the list
+ */
+
+ reference front()
+ {
+ return *begin();
+ }
+
+ /**
+ * \return const reference to first element on the list
+ */
+
+ const_reference front() const
+ {
+ return *begin();
+ }
+
+ /**
+ * \brief Unlinks the first element from the list.
+ */
+
+ void pop_front()
+ {
+ erase_after(before_begin());
+ }
+
+ /**
+ * \brief Links the element at the beginning of the list.
+ *
+ * \param [in] newElement is a reference to the element that will be linked in the list
+ */
+
+ void push_front(reference newElement)
+ {
+ insert_after(before_begin(), newElement);
+ }
+
+ /**
+ * \brief Swaps contents with another list.
+ *
+ * \param [in] other is a reference to IntrusiveForwardList with which contents of this list will be swapped
+ */
+
+ void swap(IntrusiveForwardList& other)
+ {
+ intrusiveForwardListBase_.swap(other.intrusiveForwardListBase_);
+ }
+
+ /**
+ * \brief Unlinks the element following \a position from the list.
+ *
+ * \note No instance of the list is needed for this operation.
+ *
+ * \param [in] position is an iterator preceding the element which will be unlinked from the list
+ *
+ * \return iterator of the element that was following the element which was unlinked
+ */
+
+ static iterator erase_after(const iterator position)
+ {
+ auto& positionNode = (*position).*NodePointer;
+ const auto afterNextNode = internal::IntrusiveForwardListBase::erase_after(&positionNode);
+ return iterator{afterNextNode};
+ }
+
+ /**
+ * \brief Links the element in the list after \a position.
+ *
+ * \note No instance of the list is needed for this operation.
+ *
+ * \param [in] position is an iterator of the element after which \a newNode will be linked
+ * \param [in] newElement is a reference to the element that will be linked in the list
+ *
+ * \return iterator of \a newElement
+ */
+
+ static iterator insert_after(const iterator position, reference newElement)
+ {
+ static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!");
+
+ auto& positionNode = (*position).*NodePointer;
+ auto& newElementNode = newElement.*NodePointer;
+ internal::IntrusiveForwardListBase::insert_after(&positionNode, newElementNode);
+ return iterator{&newElementNode};
+ }
+
+ /**
+ * \brief Transfers the element from one list to another list after \a position.
+ *
+ * \note No instance of any list is needed for this operation.
+ *
+ * \param [in] position is an iterator of the element after which spliced element will be linked
+ * \param [in] beforeSplicedElement is an iterator of the element preceding the one which will be spliced from one
+ * list to another
+ */
+
+ static void splice_after(const iterator position, const iterator beforeSplicedElement)
+ {
+ auto& positionNode = (*position).*NodePointer;
+ auto& beforeSplicedElementNode = (*beforeSplicedElement).*NodePointer;
+ internal::IntrusiveForwardListBase::splice_after(&positionNode, &beforeSplicedElementNode);
+ }
+
+ IntrusiveForwardList(const IntrusiveForwardList&) = delete;
+ IntrusiveForwardList(IntrusiveForwardList&&) = default;
+ const IntrusiveForwardList& operator=(const IntrusiveForwardList&) = delete;
+ IntrusiveForwardList& operator=(IntrusiveForwardList&&) = delete;
+
+private:
+
+ /// internal IntrusiveForwardListBase object
+ internal::IntrusiveForwardListBase intrusiveForwardListBase_;
+};
+
+/**
+ * \brief Swaps contents of two lists.
+ *
+ * \tparam T is the type that has the IntrusiveForwardListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a reference to IntrusiveForwardList with which contents of \a right will be swapped
+ * \param [in] right is a reference to IntrusiveForwardList with which contents of \a left will be swapped
+ */
+
+template<typename T, IntrusiveForwardListNode T::* NodePointer, typename U = T>
+inline void swap(IntrusiveForwardList<T, NodePointer, U>& left, IntrusiveForwardList<T, NodePointer, U>& right)
+{
+ left.swap(right);
+}
+
+} // namespace estd
+
+#endif // ESTD_INTRUSIVEFORWARDLIST_HPP_
diff --git a/include/estd/IntrusiveList.hpp b/include/estd/IntrusiveList.hpp
new file mode 100644
index 0000000..82597f4
--- /dev/null
+++ b/include/estd/IntrusiveList.hpp
@@ -0,0 +1,1208 @@
+/**
+ * \file
+ * \brief IntrusiveList template 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 ESTD_INTRUSIVELIST_HPP_
+#define ESTD_INTRUSIVELIST_HPP_
+
+#include <iterator>
+
+#include <cstddef>
+
+namespace estd
+{
+
+namespace internal
+{
+
+class IntrusiveListBase;
+
+}
+
+/**
+ * \brief IntrusiveListNode class is the node that is needed for the object to be linked in IntrusiveList
+ *
+ * To some extent, this class can be considered to be a limited (raw) iterator.
+ *
+ * The object that wants to be linked in IntrusiveList must contain a variable of this type - one for each intrusive
+ * list that will be used with object.
+ */
+
+class IntrusiveListNode
+{
+public:
+
+ /// LinkAccessKey class is used to limit access to IntrusiveListNode::link() function - only
+ /// internal::IntrusiveListBase can link nodes to the list
+ class LinkAccessKey
+ {
+ friend class internal::IntrusiveListBase;
+
+ /**
+ * \brief LinkAccessKey's constructor
+ */
+
+ constexpr LinkAccessKey()
+ {
+
+ }
+
+ LinkAccessKey(const LinkAccessKey&) = delete;
+ LinkAccessKey(LinkAccessKey&&) = delete;
+ const LinkAccessKey& operator=(const LinkAccessKey&) = delete;
+ LinkAccessKey& operator=(LinkAccessKey&&) = delete;
+ };
+
+ /**
+ * \brief IntrusiveListNode's constructor
+ */
+
+ constexpr IntrusiveListNode() :
+ nextNode_{this},
+ previousNode_{this}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveListNode's move constructor
+ *
+ * \param [in] other is a rvalue reference to IntrusiveListNode used as source of move construction
+ */
+
+ IntrusiveListNode(IntrusiveListNode&& other)
+ {
+ if (other.isLinked() == false)
+ {
+ reset();
+ return;
+ }
+
+ nextNode_ = other.nextNode_;
+ previousNode_ = other.previousNode_;
+ nextNode_->previousNode_ = previousNode_->nextNode_ = this;
+ other.reset();
+ }
+
+ /**
+ * \brief IntrusiveListNode's destructor
+ *
+ * Unlinks the node from the list.
+ */
+
+ ~IntrusiveListNode()
+ {
+ unlink();
+ }
+
+ /**
+ * \return reference to next node on the list
+ */
+
+ IntrusiveListNode& getNextNode() const
+ {
+ return *nextNode_;
+ }
+
+ /**
+ * \return reference to previous node on the list
+ */
+
+ IntrusiveListNode& getPreviousNode() const
+ {
+ return *previousNode_;
+ }
+
+ /**
+ * \return true if the node is linked in some list, false otherwise
+ */
+
+ bool isLinked() const
+ {
+ return nextNode_ != this;
+ }
+
+ /**
+ * \brief Links the node in the list before \a position.
+ *
+ * \note Access to this function is restricted only to functions from internal::IntrusiveListBase class
+ *
+ * \param [in] position is a reference to node before which this node will be linked
+ * \param [in] linkAccessKey is used to limit access to this function
+ */
+
+ void link(IntrusiveListNode& position, LinkAccessKey)
+ {
+ unlink();
+
+ nextNode_ = &position;
+ previousNode_ = position.previousNode_;
+ position.previousNode_->nextNode_ = this;
+ position.previousNode_ = this;
+ }
+
+ /**
+ * \brief Swaps contents with another node.
+ *
+ * \param [in] other is a reference to IntrusiveListNode with which contents of this node will be swapped
+ */
+
+ void swap(IntrusiveListNode& other)
+ {
+ const auto thisWasLinked = isLinked();
+ const auto otherWasLinked = other.isLinked();
+
+ if (thisWasLinked == true || otherWasLinked == true)
+ {
+ using std::swap;
+ swap(nextNode_, other.nextNode_);
+ swap(previousNode_, other.previousNode_);
+
+ if (thisWasLinked == true)
+ other.nextNode_->previousNode_ = other.previousNode_->nextNode_ = &other;
+ else
+ other.reset();
+
+ if (otherWasLinked == true)
+ nextNode_->previousNode_ = previousNode_->nextNode_ = this;
+ else
+ reset();
+ }
+ }
+
+ /**
+ * \brief Unlinks the node from the list.
+ */
+
+ void unlink()
+ {
+ previousNode_->nextNode_ = nextNode_;
+ nextNode_->previousNode_ = previousNode_;
+
+ reset();
+ }
+
+ IntrusiveListNode(const IntrusiveListNode&) = delete;
+ const IntrusiveListNode& operator=(const IntrusiveListNode&) = delete;
+ IntrusiveListNode& operator=(IntrusiveListNode&&) = delete;
+
+private:
+
+ /**
+ * \brief Resets the node to the same state as right after construction.
+ */
+
+ void reset()
+ {
+ nextNode_ = this;
+ previousNode_ = this;
+ }
+
+ /// reference to next node on the list
+ IntrusiveListNode* nextNode_;
+
+ /// reference to previous node on the list
+ IntrusiveListNode* previousNode_;
+};
+
+namespace internal
+{
+
+/**
+ * \brief IntrusiveListBase class provides base functionalities for IntrusiveList class, but without any knowledge about
+ * types
+ *
+ * This class tries to provide an interface similar to std::list.
+ */
+
+class IntrusiveListBase
+{
+public:
+
+ /**
+ * \brief IntrusiveListBase's constructor
+ */
+
+ constexpr IntrusiveListBase() :
+ rootNode_{}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveListBase's destructor
+ *
+ * Unlinks all nodes from the list.
+ */
+
+ ~IntrusiveListBase()
+ {
+ clear();
+ }
+
+ /**
+ * \return reference to first node on the list
+ */
+
+ IntrusiveListNode& begin()
+ {
+ return rootNode_.getNextNode();
+ }
+
+ /**
+ * \return const reference to first node on the list
+ */
+
+ const IntrusiveListNode& begin() const
+ {
+ return rootNode_.getNextNode();
+ }
+
+ /**
+ * \return const reference to first node on the list
+ */
+
+ const IntrusiveListNode& cbegin() const
+ {
+ return begin();
+ }
+
+ /**
+ * \return const reference to "one past the last" node on the list
+ */
+
+ const IntrusiveListNode& cend() const
+ {
+ return end();
+ }
+
+ /**
+ * \brief Unlinks all nodes from the list.
+ */
+
+ void clear()
+ {
+ while (empty() == false)
+ pop_front();
+ }
+
+ /**
+ * \return true is the list is empty, false otherwise
+ */
+
+ bool empty() const
+ {
+ return &begin() == &end();
+ }
+
+ /**
+ * \return reference to "one past the last" node on the list
+ */
+
+ IntrusiveListNode& end()
+ {
+ return rootNode_;
+ }
+
+ /**
+ * \return const reference to "one past the last" node on the list
+ */
+
+ const IntrusiveListNode& end() const
+ {
+ return rootNode_;
+ }
+
+ /**
+ * \brief Unlinks the last node from the list.
+ */
+
+ void pop_back()
+ {
+ erase(end().getPreviousNode());
+ }
+
+ /**
+ * \brief Unlinks the first node from the list.
+ */
+
+ void pop_front()
+ {
+ erase(begin());
+ }
+
+ /**
+ * \brief Links the node at the end of the list.
+ *
+ * \param [in] newNode is a reference to node that will be linked in the list
+ */
+
+ void push_back(IntrusiveListNode& newNode)
+ {
+ insert(end(), newNode);
+ }
+
+ /**
+ * \brief Links the node at the beginning of the list.
+ *
+ * \param [in] newNode is a reference to node that will be linked in the list
+ */
+
+ void push_front(IntrusiveListNode& newNode)
+ {
+ insert(begin(), newNode);
+ }
+
+ /**
+ * \brief Swaps contents with another list.
+ *
+ * \param [in] other is a reference to IntrusiveListBase with which contents of this list will be swapped
+ */
+
+ void swap(IntrusiveListBase& other)
+ {
+ rootNode_.swap(other.rootNode_);
+ }
+
+ /**
+ * \brief Unlinks the node at \a position from the list.
+ *
+ * \note No instance of the list is needed for this operation.
+ *
+ * \param [in] position is a reference to the node that will be unlinked from the list
+ *
+ * \return reference to the node that was following the node which was unlinked
+ */
+
+ static IntrusiveListNode& erase(IntrusiveListNode& position)
+ {
+ auto& next = position.getNextNode();
+ position.unlink();
+ return next;
+ }
+
+ /**
+ * \brief Links the node in the list before \a position.
+ *
+ * \note No instance of the list is needed for this operation.
+ *
+ * \param [in] position is a reference to node before which \a newNode will be linked
+ * \param [in] newNode is a reference to node that will be linked in the list
+ */
+
+ static void insert(IntrusiveListNode& position, IntrusiveListNode& newNode)
+ {
+ newNode.link(position, {});
+ }
+
+ /**
+ * \brief Transfers the node from one list to another list before \a position.
+ *
+ * \note No instance of any list is needed for this operation.
+ *
+ * \param [in] position is a reference to node before which \a splicedNode will be linked
+ * \param [in] splicedNode is a reference to node that will be spliced from one list to another
+ */
+
+ static void splice(IntrusiveListNode& position, IntrusiveListNode& splicedNode)
+ {
+ insert(position, splicedNode);
+ }
+
+ IntrusiveListBase(const IntrusiveListBase&) = delete;
+ IntrusiveListBase(IntrusiveListBase&&) = default;
+ const IntrusiveListBase& operator=(const IntrusiveListBase&) = delete;
+ IntrusiveListBase& operator=(IntrusiveListBase&&) = delete;
+
+private:
+
+ /// root node of the intrusive list
+ IntrusiveListNode rootNode_;
+};
+
+/**
+ * \brief Swaps contents of two lists.
+ *
+ * \param [in] left is a reference to IntrusiveListBase with which contents of \a right will be swapped
+ * \param [in] right is a reference to IntrusiveListBase with which contents of \a left will be swapped
+ */
+
+inline void swap(IntrusiveListBase& left, IntrusiveListBase& right)
+{
+ left.swap(right);
+}
+
+} // namespace internal
+
+/**
+ * \brief IntrusiveListIterator class is an iterator of elements on IntrusiveList.
+ *
+ * This class provides an interface similar to std::list::iterator.
+ *
+ * \tparam T is the type that has the IntrusiveListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ */
+
+template<typename T, IntrusiveListNode T::* NodePointer, typename U = T>
+class IntrusiveListIterator
+{
+public:
+
+ /// difference type
+ using difference_type = ptrdiff_t;
+
+ /// category of the iterator
+ using iterator_category = std::bidirectional_iterator_tag;
+
+ /// pointer to object "pointed to" by the iterator
+ using pointer = U*;
+
+ /// reference to object "pointed to" by the iterator
+ using reference = U&;
+
+ /// value "pointed to" by the iterator
+ using value_type = U;
+
+ /**
+ * \brief IntrusiveListIterator's constructor
+ */
+
+ constexpr IntrusiveListIterator() :
+ node_{}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveListIterator's constructor
+ *
+ * \param [in] node is a pointer to IntrusiveListNode of element that will be "pointed to" by the iterator
+ */
+
+ constexpr explicit IntrusiveListIterator(IntrusiveListNode* const node) :
+ node_{node}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveListIterator's constructor
+ *
+ * \param [in] element is a reference to element that will be "pointed to" by the iterator
+ */
+
+ constexpr explicit IntrusiveListIterator(reference element) :
+ node_{&(element.*NodePointer)}
+ {
+ static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!");
+ }
+
+ /**
+ * \brief IntrusiveListIterator's binary infix pointer member access operator
+ *
+ * \return pointer to object "pointed to" by the iterator
+ */
+
+ pointer operator->() const
+ {
+ return getPointer();
+ }
+
+ /**
+ * \brief IntrusiveListIterator's unary prefix dereference operator
+ *
+ * \return reference to object "pointed to" by the iterator
+ */
+
+ reference operator*() const
+ {
+ return *getPointer();
+ }
+
+ /**
+ * \brief IntrusiveListIterator's unary prefix increment operator
+ *
+ * \return reference to "this" iterator
+ */
+
+ IntrusiveListIterator& operator++()
+ {
+ node_ = &node_->getNextNode();
+ return *this;
+ }
+
+ /**
+ * \brief IntrusiveListIterator's unary postfix increment operator
+ *
+ * \return copy of "this" iterator before increment
+ */
+
+ IntrusiveListIterator operator++(int)
+ {
+ const auto temporary = *this;
+ node_ = &node_->getNextNode();
+ return temporary;
+ }
+
+ /**
+ * \brief IntrusiveListIterator's unary prefix decrement operator
+ *
+ * \return reference to "this" iterator
+ */
+
+ IntrusiveListIterator& operator--()
+ {
+ node_ = &node_->getPreviousNode();
+ return *this;
+ }
+
+ /**
+ * \brief IntrusiveListIterator's unary postfix decrement operator
+ *
+ * \return copy of "this" iterator before decrement
+ */
+
+ IntrusiveListIterator operator--(int)
+ {
+ const auto temporary = *this;
+ node_ = &node_->getPreviousNode();
+ return temporary;
+ }
+
+ /**
+ * \brief IntrusiveListIterator's "equal to" comparison operator
+ *
+ * \param [in] other is a const reference to IntrusiveListIterator on right-hand side of comparison operator
+ *
+ * \return true if both iterators are equal, false otherwise
+ */
+
+ bool operator==(const IntrusiveListIterator& other) const
+ {
+ return node_ == other.node_;
+ }
+
+private:
+
+ /**
+ * \brief Converts contained pointer to IntrusiveListNode to pointer to object that contains this node.
+ *
+ * \return pointer to object "pointed to" by the iterator
+ */
+
+ pointer getPointer() const
+ {
+ static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!");
+
+ const auto offset = reinterpret_cast<size_t>(&(static_cast<pointer>(nullptr)->*NodePointer));
+ return reinterpret_cast<pointer>(reinterpret_cast<size_t>(node_) - offset);
+ }
+
+ /// pointer to IntrusiveListNode of the object "pointed to" by the iterator
+ IntrusiveListNode* node_;
+};
+
+/**
+ * \brief IntrusiveListIterator's "not equal to" comparison operator
+ *
+ * \tparam T is the type that has the IntrusiveListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a const reference to IntrusiveListIterator on left-hand side of comparison operator
+ * \param [in] right is a const reference to IntrusiveListIterator on right-hand side of comparison operator
+ *
+ * \return true if iterators are not equal, false otherwise
+ */
+
+template<typename T, IntrusiveListNode T::* NodePointer, typename U = T>
+inline bool operator!=(const IntrusiveListIterator<T, NodePointer, U>& left,
+ const IntrusiveListIterator<T, NodePointer, U>& right)
+{
+ return (left == right) == false;
+}
+
+/**
+ * \brief IntrusiveListConstIterator class is a const iterator of elements on IntrusiveList.
+ *
+ * This class provides an interface similar to std::list::const_iterator.
+ *
+ * \tparam T is the type that has the IntrusiveListNode variable
+ * \tparam NodePointer is a const pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ */
+
+template<typename T, const IntrusiveListNode T::* NodePointer, typename U = T>
+class IntrusiveListConstIterator
+{
+public:
+
+ /// difference type
+ using difference_type = ptrdiff_t;
+
+ /// category of the iterator
+ using iterator_category = std::bidirectional_iterator_tag;
+
+ /// pointer to object "pointed to" by the iterator
+ using pointer = const U*;
+
+ /// reference to object "pointed to" by the iterator
+ using reference = const U&;
+
+ /// value "pointed to" by the iterator
+ using value_type = U;
+
+ /**
+ * \brief IntrusiveListConstIterator's constructor
+ */
+
+ constexpr IntrusiveListConstIterator() :
+ node_{}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveListConstIterator's constructor
+ *
+ * \param [in] node is a pointer to const IntrusiveListNode of element that will be "pointed to" by the iterator
+ */
+
+ constexpr explicit IntrusiveListConstIterator(const IntrusiveListNode* const node) :
+ node_{node}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveListConstIterator's constructor
+ *
+ * \param [in] element is a const reference to element that will be "pointed to" by the iterator
+ */
+
+ constexpr explicit IntrusiveListConstIterator(reference element) :
+ node_{&(element.*NodePointer)}
+ {
+ static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!");
+ }
+
+ /**
+ * \brief IntrusiveListConstIterator's constructor
+ *
+ * Converts non-const iterator (IntrusiveListIterator) to const iterator (IntrusiveListConstIterator).
+ *
+ * \tparam NonConstNodePointer is a non-const version of \a NodePointer
+ *
+ * \param [in] iterator is a const reference to non-const iterator (IntrusiveListIterator)
+ */
+
+ template<IntrusiveListNode T::* NonConstNodePointer>
+ constexpr IntrusiveListConstIterator(const IntrusiveListIterator<T, NonConstNodePointer, U>& iterator) :
+ IntrusiveListConstIterator{*iterator}
+ {
+
+ }
+
+ /**
+ * \brief IntrusiveListConstIterator's binary infix pointer member access operator
+ *
+ * \return pointer to object "pointed to" by the iterator
+ */
+
+ pointer operator->() const
+ {
+ return getPointer();
+ }
+
+ /**
+ * \brief IntrusiveListConstIterator's unary prefix dereference operator
+ *
+ * \return reference to object "pointed to" by the iterator
+ */
+
+ reference operator*() const
+ {
+ return *getPointer();
+ }
+
+ /**
+ * \brief IntrusiveListConstIterator's unary prefix increment operator
+ *
+ * \return reference to "this" iterator
+ */
+
+ IntrusiveListConstIterator& operator++()
+ {
+ node_ = &node_->getNextNode();
+ return *this;
+ }
+
+ /**
+ * \brief IntrusiveListConstIterator's unary postfix increment operator
+ *
+ * \return copy of "this" iterator before increment
+ */
+
+ IntrusiveListConstIterator operator++(int)
+ {
+ const auto temporary = *this;
+ node_ = &node_->getNextNode();
+ return temporary;
+ }
+
+ /**
+ * \brief IntrusiveListConstIterator's unary prefix decrement operator
+ *
+ * \return reference to "this" iterator
+ */
+
+ IntrusiveListConstIterator& operator--()
+ {
+ node_ = &node_->getPreviousNode();
+ return *this;
+ }
+
+ /**
+ * \brief IntrusiveListConstIterator's unary postfix decrement operator
+ *
+ * \return copy of "this" iterator before decrement
+ */
+
+ IntrusiveListConstIterator operator--(int)
+ {
+ const auto temporary = *this;
+ node_ = &node_->getPreviousNode();
+ return temporary;
+ }
+
+ /**
+ * \brief IntrusiveListConstIterator's "equal to" comparison operator
+ *
+ * \param [in] other is a const reference to IntrusiveListConstIterator on right-hand side of comparison operator
+ *
+ * \return true if both iterators are equal, false otherwise
+ */
+
+ bool operator==(const IntrusiveListConstIterator& other) const
+ {
+ return node_ == other.node_;
+ }
+
+private:
+
+ /**
+ * \brief Converts contained pointer to IntrusiveListNode to pointer to object that contains this node.
+ *
+ * \return pointer to object "pointed to" by the iterator
+ */
+
+ pointer getPointer() const
+ {
+ static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!");
+
+ const auto offset = reinterpret_cast<size_t>(&(static_cast<pointer>(nullptr)->*NodePointer));
+ return reinterpret_cast<pointer>(reinterpret_cast<size_t>(node_) - offset);
+ }
+
+ /// pointer to const IntrusiveListNode of the object "pointed to" by the iterator
+ const IntrusiveListNode* node_;
+};
+
+/**
+ * \brief IntrusiveListConstIterator's "not equal to" comparison operator
+ *
+ * \tparam T is the type that has the IntrusiveListNode variable
+ * \tparam NodePointer is a const pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a const reference to IntrusiveListConstIterator on left-hand side of comparison operator
+ * \param [in] right is a const reference to IntrusiveListConstIterator on right-hand side of comparison operator
+ *
+ * \return true if iterators are not equal, false otherwise
+ */
+
+template<typename T, const IntrusiveListNode T::* NodePointer, typename U = T>
+inline bool operator!=(const IntrusiveListConstIterator<T, NodePointer, U>& left,
+ const IntrusiveListConstIterator<T, NodePointer, U>& right)
+{
+ return (left == right) == false;
+}
+
+/**
+ * \brief "Equal to" comparison operator for IntrusiveListIterator and IntrusiveListConstIterator
+ *
+ * \tparam T is the type that has the IntrusiveListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam ConstNodePointer is a const pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a const reference to IntrusiveListIterator on left-hand side of comparison operator
+ * \param [in] right is a const reference to IntrusiveListConstIterator on right-hand side of comparison operator
+ *
+ * \return true if both iterators are equal, false otherwise
+ */
+
+template<typename T, IntrusiveListNode T::* NodePointer, const IntrusiveListNode T::* ConstNodePointer, typename U = T>
+inline bool operator==(const IntrusiveListIterator<T, NodePointer, U>& left,
+ const IntrusiveListConstIterator<T, ConstNodePointer, U>& right)
+{
+ return decltype(right){left} == right;
+}
+
+/**
+ * \brief "Not equal to" comparison operator for IntrusiveListIterator and IntrusiveListConstIterator
+ *
+ * \tparam T is the type that has the IntrusiveListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam ConstNodePointer is a const pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a const reference to IntrusiveListIterator on left-hand side of comparison operator
+ * \param [in] right is a const reference to IntrusiveListConstIterator on right-hand side of comparison operator
+ *
+ * \return true if iterators are not equal, false otherwise
+ */
+
+template<typename T, IntrusiveListNode T::* NodePointer, const IntrusiveListNode T::* ConstNodePointer, typename U = T>
+inline bool operator!=(const IntrusiveListIterator<T, NodePointer, U>& left,
+ const IntrusiveListConstIterator<T, ConstNodePointer, U>& right)
+{
+ return (left == right) == false;
+}
+
+/**
+ * \brief "Not equal to" comparison operator for IntrusiveListConstIterator and IntrusiveListIterator
+ *
+ * \tparam T is the type that has the IntrusiveListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam ConstNodePointer is a const pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a const reference to IntrusiveListConstIterator on left-hand side of comparison operator
+ * \param [in] right is a const reference to IntrusiveListIterator on right-hand side of comparison operator
+ *
+ * \return true if iterators are not equal, false otherwise
+ */
+
+template<typename T, IntrusiveListNode T::* NodePointer, const IntrusiveListNode T::* ConstNodePointer, typename U = T>
+inline bool operator!=(const IntrusiveListConstIterator<T, ConstNodePointer, U>& left,
+ const IntrusiveListIterator<T, NodePointer, U>& right)
+{
+ return right != left;
+}
+
+/**
+ * \brief IntrusiveList class is an intrusive circular doubly linked list.
+ *
+ * This class tries to provide an interface similar to std::list.
+ *
+ * \tparam T is the type that has the IntrusiveListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T; using different type than \a T can be used
+ * to break circular dependencies, because \a T must be fully defined to instantiate this class, but it is enough to
+ * forward declare \a U - it only needs to be fully defined to use member functions
+ */
+
+template<typename T, IntrusiveListNode T::* NodePointer, typename U = T>
+class IntrusiveList
+{
+public:
+
+ /// const iterator of elements on the list
+ using const_iterator = IntrusiveListConstIterator<T, NodePointer, U>;
+
+ /// const reverse iterator of elements on the list
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+ /// const pointer to value linked in the list
+ using const_pointer = const U*;
+
+ /// const reference to value linked in the list
+ using const_reference = const U&;
+
+ /// iterator of elements on the list
+ using iterator = IntrusiveListIterator<T, NodePointer, U>;
+
+ /// reverse iterator of elements on the list
+ using reverse_iterator = std::reverse_iterator<iterator>;
+
+ /// pointer to value linked in the list
+ using pointer = U*;
+
+ /// reference to value linked in the list
+ using reference = U&;
+
+ /// value linked in the list
+ using value_type = U;
+
+ /**
+ * \brief IntrusiveList's constructor
+ */
+
+ constexpr IntrusiveList() :
+ intrusiveListBase_{}
+ {
+
+ }
+
+ /**
+ * \return reference to last element on the list
+ */
+
+ reference back()
+ {
+ return *--end();
+ }
+
+ /**
+ * \return const reference to last element on the list
+ */
+
+ const_reference back() const
+ {
+ return *--end();
+ }
+
+ /**
+ * \return iterator of first element on the list
+ */
+
+ iterator begin()
+ {
+ return iterator{&intrusiveListBase_.begin()};
+ }
+
+ /**
+ * \return const iterator of first element on the list
+ */
+
+ const_iterator begin() const
+ {
+ return const_iterator{&intrusiveListBase_.begin()};
+ }
+
+ /**
+ * \return const iterator of first element on the list
+ */
+
+ const_iterator cbegin() const
+ {
+ return begin();
+ }
+
+ /**
+ * \return const iterator of "one past the last" element on the list
+ */
+
+ const_iterator cend() const
+ {
+ return end();
+ }
+
+ /**
+ * \brief Unlinks all elements from the list.
+ */
+
+ void clear()
+ {
+ intrusiveListBase_.clear();
+ }
+
+ /**
+ * \return true is the list is empty, false otherwise
+ */
+
+ bool empty() const
+ {
+ return intrusiveListBase_.empty();
+ }
+
+ /**
+ * \return iterator of "one past the last" element on the list
+ */
+
+ iterator end()
+ {
+ return iterator{&intrusiveListBase_.end()};
+ }
+
+ /**
+ * \return const iterator of "one past the last" element on the list
+ */
+
+ const_iterator end() const
+ {
+ return const_iterator{&intrusiveListBase_.end()};
+ }
+
+ /**
+ * \return reference to first element on the list
+ */
+
+ reference front()
+ {
+ return *begin();
+ }
+
+ /**
+ * \return const reference to first element on the list
+ */
+
+ const_reference front() const
+ {
+ return *begin();
+ }
+
+ /**
+ * \brief Unlinks the last element from the list.
+ */
+
+ void pop_back()
+ {
+ erase(--end());
+ }
+
+ /**
+ * \brief Unlinks the first element from the list.
+ */
+
+ void pop_front()
+ {
+ erase(begin());
+ }
+
+ /**
+ * \brief Links the element at the end of the list.
+ *
+ * \param [in] newElement is a reference to the element that will be linked in the list
+ */
+
+ void push_back(reference newElement)
+ {
+ insert(end(), newElement);
+ }
+
+ /**
+ * \brief Links the element at the beginning of the list.
+ *
+ * \param [in] newElement is a reference to the element that will be linked in the list
+ */
+
+ void push_front(reference newElement)
+ {
+ insert(begin(), newElement);
+ }
+
+ /**
+ * \brief Swaps contents with another list.
+ *
+ * \param [in] other is a reference to IntrusiveList with which contents of this list will be swapped
+ */
+
+ void swap(IntrusiveList& other)
+ {
+ intrusiveListBase_.swap(other.intrusiveListBase_);
+ }
+
+ /**
+ * \brief Unlinks the element at \a position from the list.
+ *
+ * \note No instance of the list is needed for this operation.
+ *
+ * \param [in] position is an iterator of the element that will be unlinked from the list
+ *
+ * \return iterator of the element that was following the element which was unlinked
+ */
+
+ static iterator erase(const iterator position)
+ {
+ auto& positionNode = (*position).*NodePointer;
+ auto& nextNode = internal::IntrusiveListBase::erase(positionNode);
+ return iterator{&nextNode};
+ }
+
+ /**
+ * \brief Links the element in the list before \a position.
+ *
+ * \note No instance of the list is needed for this operation.
+ *
+ * \param [in] position is an iterator of the element before which \a newNode will be linked
+ * \param [in] newElement is a reference to the element that will be linked in the list
+ *
+ * \return iterator of \a newElement
+ */
+
+ static iterator insert(const iterator position, reference newElement)
+ {
+ static_assert(std::is_convertible<U, T>::value == true, "U must be implicitly convertible to T!");
+
+ auto& positionNode = (*position).*NodePointer;
+ auto& newElementNode = newElement.*NodePointer;
+ internal::IntrusiveListBase::insert(positionNode, newElementNode);
+ return iterator{&newElementNode};
+ }
+
+ /**
+ * \brief Transfers the element from one list to another list before \a position.
+ *
+ * \note No instance of any list is needed for this operation.
+ *
+ * \param [in] position is an iterator of the element before which \a splicedElement will be linked
+ * \param [in] splicedElement is an iterator of the element that will be spliced from one list to another
+ */
+
+ static void splice(const iterator position, const iterator splicedElement)
+ {
+ auto& positionNode = (*position).*NodePointer;
+ auto& splicedElementNode = (*splicedElement).*NodePointer;
+ internal::IntrusiveListBase::splice(positionNode, splicedElementNode);
+ }
+
+ IntrusiveList(const IntrusiveList&) = delete;
+ IntrusiveList(IntrusiveList&&) = default;
+ const IntrusiveList& operator=(const IntrusiveList&) = delete;
+ IntrusiveList& operator=(IntrusiveList&&) = delete;
+
+private:
+
+ /// internal IntrusiveListBase object
+ internal::IntrusiveListBase intrusiveListBase_;
+};
+
+/**
+ * \brief Swaps contents of two lists.
+ *
+ * \tparam T is the type that has the IntrusiveListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a reference to IntrusiveList with which contents of \a right will be swapped
+ * \param [in] right is a reference to IntrusiveList with which contents of \a left will be swapped
+ */
+
+template<typename T, IntrusiveListNode T::* NodePointer, typename U = T>
+inline void swap(IntrusiveList<T, NodePointer, U>& left, IntrusiveList<T, NodePointer, U>& right)
+{
+ left.swap(right);
+}
+
+} // namespace estd
+
+#endif // ESTD_INTRUSIVELIST_HPP_
diff --git a/include/estd/ReferenceHolder.hpp b/include/estd/ReferenceHolder.hpp
new file mode 100644
index 0000000..2bb4602
--- /dev/null
+++ b/include/estd/ReferenceHolder.hpp
@@ -0,0 +1,61 @@
+/**
+ * \file
+ * \brief ReferenceHolder template 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 ESTD_REFERENCEHOLDER_HPP_
+#define ESTD_REFERENCEHOLDER_HPP_
+
+namespace estd
+{
+
+/**
+ * \brief ReferenceHolder template class is a ROMable holder of a reference.
+ *
+ * \tparam T is the type of reference held in the object
+ */
+
+template<typename T>
+class ReferenceHolder
+{
+public:
+
+ /**
+ * \brief ReferenceHolder constructor.
+ *
+ * \param [in] reference is a reference that will be held by the object
+ */
+
+ constexpr explicit ReferenceHolder(T& reference) noexcept :
+ reference_{reference}
+ {
+
+ }
+
+ /// \return reference held by the object
+ constexpr operator T&() const noexcept
+ {
+ return reference_;
+ }
+
+ /// \return reference held by the object
+ constexpr T& get() const noexcept
+ {
+ return reference_;
+ }
+
+private:
+
+ /// reference held by the object
+ T& reference_;
+};
+
+} // namespace estd
+
+#endif // ESTD_REFERENCEHOLDER_HPP_
diff --git a/include/estd/ReverseAdaptor.hpp b/include/estd/ReverseAdaptor.hpp
new file mode 100644
index 0000000..6738cac
--- /dev/null
+++ b/include/estd/ReverseAdaptor.hpp
@@ -0,0 +1,83 @@
+/**
+ * \file
+ * \brief ReverseAdaptor template 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 ESTD_REVERSEADAPTOR_HPP_
+#define ESTD_REVERSEADAPTOR_HPP_
+
+namespace estd
+{
+
+/**
+ * \brief ReverseAdaptor template class is an adaptor that "reverses" access to the container
+ *
+ * \tparam T is the type of container
+ */
+
+template<typename T>
+class ReverseAdaptor
+{
+public:
+
+ /**
+ * \brief ReverseAdaptor's constructor.
+ *
+ * \param [in] container is a reference to container
+ */
+
+ constexpr explicit ReverseAdaptor(T& container) noexcept :
+ container_{container}
+ {
+
+ }
+
+ /**
+ * \return reverse_iterator to the beginning of "reversed" container (last element of original container)
+ */
+
+ typename T::reverse_iterator begin() const noexcept
+ {
+ return container_.rbegin();
+ }
+
+ /**
+ * \return reverse_iterator to the end of "reversed" container (before-the-first element of original container)
+ */
+
+ typename T::reverse_iterator end() const noexcept
+ {
+ return container_.rend();
+ }
+
+private:
+
+ /// reference to container
+ T& container_;
+};
+
+/**
+ * \brief Helper factory function to make ReverseAdaptor object with deduced template arguments
+ *
+ * \tparam T is the type of container
+ *
+ * \param [in] container is a reference to container
+ *
+ * \return ReverseAdaptor object
+ */
+
+template<typename T>
+ReverseAdaptor<T> makeReverseAdaptor(T& container)
+{
+ return ReverseAdaptor<T>{container};
+}
+
+} // namespace estd
+
+#endif // ESTD_REVERSEADAPTOR_HPP_
diff --git a/include/estd/SortedIntrusiveForwardList.hpp b/include/estd/SortedIntrusiveForwardList.hpp
new file mode 100644
index 0000000..de35845
--- /dev/null
+++ b/include/estd/SortedIntrusiveForwardList.hpp
@@ -0,0 +1,355 @@
+/**
+ * \file
+ * \brief SortedIntrusiveForwardList template 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 ESTD_SORTEDINTRUSIVEFORWARDLIST_HPP_
+#define ESTD_SORTEDINTRUSIVEFORWARDLIST_HPP_
+
+#include "estd/IntrusiveForwardList.hpp"
+
+#include <algorithm>
+
+namespace estd
+{
+
+/**
+ * \brief SortedIntrusiveForwardList class is an IntrusiveForwardList with sorted elements
+ *
+ * This class tries to provide an interface similar to std::forward_list.
+ *
+ * \note The elements are sorted as long as the user does not modify the contents.
+ *
+ * \tparam Compare is a type of functor used for comparison, std::less results in descending order, std::greater - in
+ * ascending order
+ * \tparam T is the type that has the IntrusiveForwardListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T; using different type than \a T can be used
+ * to break circular dependencies, because \a T must be fully defined to instantiate this class, but it is enough to
+ * forward declare \a U - it only needs to be fully defined to use member functions
+ */
+
+template<typename Compare, typename T, IntrusiveForwardListNode T::* NodePointer, typename U = T>
+class SortedIntrusiveForwardList
+{
+public:
+
+ /// unsorted intrusive forward list used internally
+ using UnsortedIntrusiveForwardList = IntrusiveForwardList<T, NodePointer, U>;
+
+ /// const iterator of elements on the list
+ using const_iterator = typename UnsortedIntrusiveForwardList::const_iterator;
+
+ /// const pointer to value linked in the list
+ using const_pointer = typename UnsortedIntrusiveForwardList::const_pointer;
+
+ /// const reference to value linked in the list
+ using const_reference = typename UnsortedIntrusiveForwardList::const_reference;
+
+ /// iterator of elements on the list
+ using iterator = typename UnsortedIntrusiveForwardList::iterator;
+
+ /// pointer to value linked in the list
+ using pointer = typename UnsortedIntrusiveForwardList::pointer;
+
+ /// reference to value linked in the list
+ using reference = typename UnsortedIntrusiveForwardList::reference;
+
+ /// value linked in the list
+ using value_type = typename UnsortedIntrusiveForwardList::value_type;
+
+ /**
+ * \brief SortedIntrusiveForwardList's constructor
+ *
+ * \param [in] compare is a reference to Compare object used to copy-construct internal comparison functor
+ */
+
+ constexpr SortedIntrusiveForwardList(const Compare& compare = Compare{}) :
+ implementation_{compare}
+ {
+
+ }
+
+ /**
+ * \return iterator of "one before the first" element on the list
+ */
+
+ iterator before_begin()
+ {
+ return implementation_.intrusiveForwardList.before_begin();
+ }
+
+ /**
+ * \return const iterator of "one before the first" element on the list
+ */
+
+ const_iterator before_begin() const
+ {
+ return implementation_.intrusiveForwardList.before_begin();
+ }
+
+ /**
+ * \return iterator of first element on the list
+ */
+
+ iterator begin()
+ {
+ return implementation_.intrusiveForwardList.begin();
+ }
+
+ /**
+ * \return const iterator of first element on the list
+ */
+
+ const_iterator begin() const
+ {
+ return implementation_.intrusiveForwardList.begin();
+ }
+
+ /**
+ * \return const iterator of "one before the first" element on the list
+ */
+
+ const_iterator cbefore_begin() const
+ {
+ return implementation_.intrusiveForwardList.cbefore_begin();
+ }
+
+ /**
+ * \return const iterator of first element on the list
+ */
+
+ const_iterator cbegin() const
+ {
+ return implementation_.intrusiveForwardList.cbegin();
+ }
+
+ /**
+ * \return const iterator of "one past the last" element on the list
+ */
+
+ const_iterator cend() const
+ {
+ return implementation_.intrusiveForwardList.cend();
+ }
+
+ /**
+ * \brief Unlinks all elements from the list.
+ */
+
+ void clear()
+ {
+ implementation_.intrusiveForwardList.clear();
+ }
+
+ /**
+ * \return true is the list is empty, false otherwise
+ */
+
+ bool empty() const
+ {
+ return implementation_.intrusiveForwardList.empty();
+ }
+
+ /**
+ * \return iterator of "one past the last" element on the list
+ */
+
+ iterator end()
+ {
+ return implementation_.intrusiveForwardList.end();
+ }
+
+ /**
+ * \return const iterator of "one past the last" element on the list
+ */
+
+ const_iterator end() const
+ {
+ return implementation_.intrusiveForwardList.end();
+ }
+
+ /**
+ * \return reference to first element on the list
+ */
+
+ reference front()
+ {
+ return implementation_.intrusiveForwardList.front();
+ }
+
+ /**
+ * \return const reference to first element on the list
+ */
+
+ const_reference front() const
+ {
+ return implementation_.intrusiveForwardList.front();
+ }
+
+ /**
+ * \brief Links the element in the list, keeping it sorted.
+ *
+ * \param [in] newElement is a reference to the element that will be linked in the list
+ *
+ * \return iterator of \a newElement
+ */
+
+ iterator insert(reference newElement)
+ {
+ return UnsortedIntrusiveForwardList::insert_after(implementation_.findInsertPositionBefore(newElement),
+ newElement);
+ }
+
+ /**
+ * \brief Unlinks the first element from the list.
+ */
+
+ void pop_front()
+ {
+ implementation_.intrusiveForwardList.pop_front();
+ }
+
+ /**
+ * \brief Transfers the element from another list to this one, keeping it sorted.
+ *
+ * \param [in] beforeSplicedElement is an iterator of the element preceding the one which will be spliced from
+ * another list to this one
+ */
+
+ void splice_after(const iterator beforeSplicedElement)
+ {
+ const auto splicedElement = std::next(beforeSplicedElement);
+ UnsortedIntrusiveForwardList::splice_after(implementation_.findInsertPositionBefore(*splicedElement),
+ beforeSplicedElement);
+ }
+
+ /**
+ * \brief Swaps contents with another list.
+ *
+ * \param [in] other is a reference to SortedIntrusiveForwardList with which contents of this list will be swapped
+ */
+
+ void swap(SortedIntrusiveForwardList& other)
+ {
+ implementation_.swap(other.implementation_);
+ }
+
+ /**
+ * \brief Unlinks the element following \a position from the list.
+ *
+ * \note No instance of the list is needed for this operation.
+ *
+ * \param [in] position is an iterator preceding the element which will be unlinked from the list
+ *
+ * \return iterator of the element that was following the element which was unlinked
+ */
+
+ static iterator erase_after(const iterator position)
+ {
+ return UnsortedIntrusiveForwardList::erase_after(position);
+ }
+
+ SortedIntrusiveForwardList(const SortedIntrusiveForwardList&) = delete;
+ SortedIntrusiveForwardList(SortedIntrusiveForwardList&&) = default;
+ const SortedIntrusiveForwardList& operator=(const SortedIntrusiveForwardList&) = delete;
+ SortedIntrusiveForwardList& operator=(SortedIntrusiveForwardList&&) = delete;
+
+private:
+
+ /// Implementation struct is used primarily for "Empty Base Optimization" with \a Compare type
+ struct Implementation : public Compare
+ {
+ /**
+ * \brief Implementation's constructor
+ *
+ * \param [in] comparee is a reference to Compare object used to copy-construct internal comparison functor
+ */
+
+ constexpr Implementation(const Compare& comparee) :
+ Compare{comparee},
+ intrusiveForwardList{}
+ {
+
+ }
+
+ /**
+ * \brief Finds insert position "before" the position that satisfies sorting criteria.
+ *
+ * \param [in] newElement is a const reference to new element that is going to be inserted/spliced
+ *
+ * \return iterator for which Compare's function call operator of next value and \a newElement returns true.
+ */
+
+ iterator findInsertPositionBefore(const_reference newElement)
+ {
+ auto it = intrusiveForwardList.before_begin();
+ auto next = intrusiveForwardList.begin();
+ const auto end = intrusiveForwardList.end();
+
+ while (next != end && this->Compare::operator()(*next, newElement) == false)
+ {
+ it = next;
+ ++next;
+ }
+
+ return it;
+ }
+
+ /**
+ * \brief Swaps contents with another instance.
+ *
+ * \param [in] other is a reference to Implementation with which contents of this instance will be swapped
+ */
+
+ void swap(Implementation& other)
+ {
+ intrusiveForwardList.swap(other.intrusiveForwardList);
+ using std::swap;
+ swap(static_cast<Compare&>(*this), static_cast<Compare&>(other));
+ }
+
+ Implementation(const Implementation&) = delete;
+ Implementation(Implementation&&) = default;
+ const Implementation& operator=(const Implementation&) = delete;
+ Implementation& operator=(Implementation&&) = delete;
+
+ /// internal unsorted IntrusiveForwardList
+ UnsortedIntrusiveForwardList intrusiveForwardList;
+ };
+
+ /// internal Implementation object - unsorted IntrusiveForwardList and Compare instance
+ Implementation implementation_;
+};
+
+/**
+ * \brief Swaps contents of two lists.
+ *
+ * \tparam Compare is a type of functor used for comparison, std::less results in descending order, std::greater - in
+ * ascending order
+ * \tparam T is the type that has the IntrusiveForwardListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveForwardListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a reference to SortedIntrusiveForwardList with which contents of \a right will be swapped
+ * \param [in] right is a reference to SortedIntrusiveForwardList with which contents of \a left will be swapped
+ */
+
+template<typename Compare, typename T, IntrusiveForwardListNode T::* NodePointer, typename U = T>
+inline void swap(SortedIntrusiveForwardList<Compare, T, NodePointer, U>& left,
+ SortedIntrusiveForwardList<Compare, T, NodePointer, U>& right)
+{
+ left.swap(right);
+}
+
+} // namespace estd
+
+#endif // ESTD_SORTEDINTRUSIVEFORWARDLIST_HPP_
diff --git a/include/estd/SortedIntrusiveList.hpp b/include/estd/SortedIntrusiveList.hpp
new file mode 100644
index 0000000..1d65ee3
--- /dev/null
+++ b/include/estd/SortedIntrusiveList.hpp
@@ -0,0 +1,353 @@
+/**
+ * \file
+ * \brief SortedIntrusiveList template 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 ESTD_SORTEDINTRUSIVELIST_HPP_
+#define ESTD_SORTEDINTRUSIVELIST_HPP_
+
+#include "estd/IntrusiveList.hpp"
+
+#include <algorithm>
+
+namespace estd
+{
+
+/**
+ * \brief SortedIntrusiveList class is an IntrusiveList with sorted elements
+ *
+ * This class tries to provide an interface similar to std::list.
+ *
+ * \note The elements are sorted as long as the user does not modify the contents.
+ *
+ * \tparam Compare is a type of functor used for comparison, std::less results in descending order, std::greater - in
+ * ascending order
+ * \tparam T is the type that has the IntrusiveListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T; using different type than \a T can be used
+ * to break circular dependencies, because \a T must be fully defined to instantiate this class, but it is enough to
+ * forward declare \a U - it only needs to be fully defined to use member functions
+ */
+
+template<typename Compare, typename T, IntrusiveListNode T::* NodePointer, typename U = T>
+class SortedIntrusiveList
+{
+public:
+
+ /// unsorted intrusive list used internally
+ using UnsortedIntrusiveList = IntrusiveList<T, NodePointer, U>;
+
+ /// const iterator of elements on the list
+ using const_iterator = typename UnsortedIntrusiveList::const_iterator;
+
+ /// const reverse iterator of elements on the list
+ using const_reverse_iterator = typename UnsortedIntrusiveList::const_reverse_iterator;
+
+ /// const pointer to value linked in the list
+ using const_pointer = typename UnsortedIntrusiveList::const_pointer;
+
+ /// const reference to value linked in the list
+ using const_reference = typename UnsortedIntrusiveList::const_reference;
+
+ /// iterator of elements on the list
+ using iterator = typename UnsortedIntrusiveList::iterator;
+
+ /// reverse iterator of elements on the list
+ using reverse_iterator = typename UnsortedIntrusiveList::reverse_iterator;
+
+ /// pointer to value linked in the list
+ using pointer = typename UnsortedIntrusiveList::pointer;
+
+ /// reference to value linked in the list
+ using reference = typename UnsortedIntrusiveList::reference;
+
+ /// value linked in the list
+ using value_type = typename UnsortedIntrusiveList::value_type;
+
+ /**
+ * \brief SortedIntrusiveList's constructor
+ *
+ * \param [in] compare is a reference to Compare object used to copy-construct internal comparison functor
+ */
+
+ constexpr SortedIntrusiveList(const Compare& compare = Compare{}) :
+ implementation_{compare}
+ {
+
+ }
+
+ /**
+ * \return reference to last element on the list
+ */
+
+ reference back()
+ {
+ return implementation_.intrusiveList.back();
+ }
+
+ /**
+ * \return const reference to last element on the list
+ */
+
+ const_reference back() const
+ {
+ return implementation_.intrusiveList.back();
+ }
+
+ /**
+ * \return iterator of first element on the list
+ */
+
+ iterator begin()
+ {
+ return implementation_.intrusiveList.begin();
+ }
+
+ /**
+ * \return const iterator of first element on the list
+ */
+
+ const_iterator begin() const
+ {
+ return implementation_.intrusiveList.begin();
+ }
+
+ /**
+ * \return const iterator of first element on the list
+ */
+
+ const_iterator cbegin() const
+ {
+ return implementation_.intrusiveList.cbegin();
+ }
+
+ /**
+ * \return const iterator of "one past the last" element on the list
+ */
+
+ const_iterator cend() const
+ {
+ return implementation_.intrusiveList.cend();
+ }
+
+ /**
+ * \brief Unlinks all elements from the list.
+ */
+
+ void clear()
+ {
+ implementation_.intrusiveList.clear();
+ }
+
+ /**
+ * \return true is the list is empty, false otherwise
+ */
+
+ bool empty() const
+ {
+ return implementation_.intrusiveList.empty();
+ }
+
+ /**
+ * \return iterator of "one past the last" element on the list
+ */
+
+ iterator end()
+ {
+ return implementation_.intrusiveList.end();
+ }
+
+ /**
+ * \return const iterator of "one past the last" element on the list
+ */
+
+ const_iterator end() const
+ {
+ return implementation_.intrusiveList.end();
+ }
+
+ /**
+ * \return reference to first element on the list
+ */
+
+ reference front()
+ {
+ return implementation_.intrusiveList.front();
+ }
+
+ /**
+ * \return const reference to first element on the list
+ */
+
+ const_reference front() const
+ {
+ return implementation_.intrusiveList.front();
+ }
+
+ /**
+ * \brief Links the element in the list, keeping it sorted.
+ *
+ * \param [in] newElement is a reference to the element that will be linked in the list
+ *
+ * \return iterator of \a newElement
+ */
+
+ iterator insert(reference newElement)
+ {
+ return UnsortedIntrusiveList::insert(implementation_.findInsertPosition(newElement), newElement);
+ }
+
+ /**
+ * \brief Unlinks the last element from the list.
+ */
+
+ void pop_back()
+ {
+ implementation_.intrusiveList.pop_back();
+ }
+
+ /**
+ * \brief Unlinks the first element from the list.
+ */
+
+ void pop_front()
+ {
+ implementation_.intrusiveList.pop_front();
+ }
+
+ /**
+ * \brief Transfers the element from another list to this one, keeping it sorted.
+ *
+ * \param [in] splicedElement is an iterator of the element that will be spliced from another list to this one
+ */
+
+ void splice(const iterator splicedElement)
+ {
+ UnsortedIntrusiveList::splice(implementation_.findInsertPosition(*splicedElement), splicedElement);
+ }
+
+ /**
+ * \brief Swaps contents with another list.
+ *
+ * \param [in] other is a reference to SortedIntrusiveList with which contents of this list will be swapped
+ */
+
+ void swap(SortedIntrusiveList& other)
+ {
+ implementation_.swap(other.implementation_);
+ }
+
+ /**
+ * \brief Unlinks the element at \a position from the list.
+ *
+ * \note No instance of the list is needed for this operation.
+ *
+ * \param [in] position is an iterator of the element that will be unlinked from the list
+ *
+ * \return iterator of the element that was following the element which was unlinked
+ */
+
+ static iterator erase(const iterator position)
+ {
+ return UnsortedIntrusiveList::erase(position);
+ }
+
+ SortedIntrusiveList(const SortedIntrusiveList&) = delete;
+ SortedIntrusiveList(SortedIntrusiveList&&) = default;
+ const SortedIntrusiveList& operator=(const SortedIntrusiveList&) = delete;
+ SortedIntrusiveList& operator=(SortedIntrusiveList&&) = delete;
+
+private:
+
+ /// Implementation struct is used primarily for "Empty Base Optimization" with \a Compare type
+ struct Implementation : public Compare
+ {
+ /**
+ * \brief Implementation's constructor
+ *
+ * \param [in] comparee is a reference to Compare object used to copy-construct internal comparison functor
+ */
+
+ constexpr Implementation(const Compare& comparee) :
+ Compare{comparee},
+ intrusiveList{}
+ {
+
+ }
+
+ /**
+ * \brief Finds insert position that satisfies sorting criteria.
+ *
+ * \param [in] newElement is a const reference to new element that is going to be inserted/spliced
+ *
+ * \return iterator for which Compare's function call operator of dereferenced value and \a newElement returns
+ * true.
+ */
+
+ iterator findInsertPosition(const_reference newElement)
+ {
+ return std::find_if(intrusiveList.begin(), intrusiveList.end(),
+ [this, &newElement](const_reference& element) -> bool
+ {
+ return this->Compare::operator()(element, newElement);
+ }
+ );
+ }
+
+ /**
+ * \brief Swaps contents with another instance.
+ *
+ * \param [in] other is a reference to Implementation with which contents of this instance will be swapped
+ */
+
+ void swap(Implementation& other)
+ {
+ intrusiveList.swap(other.intrusiveList);
+ using std::swap;
+ swap(static_cast<Compare&>(*this), static_cast<Compare&>(other));
+ }
+
+ Implementation(const Implementation&) = delete;
+ Implementation(Implementation&&) = default;
+ const Implementation& operator=(const Implementation&) = delete;
+ Implementation& operator=(Implementation&&) = delete;
+
+ /// internal unsorted IntrusiveList
+ UnsortedIntrusiveList intrusiveList;
+ };
+
+ /// internal Implementation object - unsorted IntrusiveList and Compare instance
+ Implementation implementation_;
+};
+
+/**
+ * \brief Swaps contents of two lists.
+ *
+ * \tparam Compare is a type of functor used for comparison, std::less results in descending order, std::greater - in
+ * ascending order
+ * \tparam T is the type that has the IntrusiveListNode variable
+ * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
+ * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
+ * convertible to \a T (so usually a type derived from \a T); default - \a T;
+ *
+ * \param [in] left is a reference to SortedIntrusiveList with which contents of \a right will be swapped
+ * \param [in] right is a reference to SortedIntrusiveList with which contents of \a left will be swapped
+ */
+
+template<typename Compare, typename T, IntrusiveListNode T::* NodePointer, typename U = T>
+inline void swap(SortedIntrusiveList<Compare, T, NodePointer, U>& left,
+ SortedIntrusiveList<Compare, T, NodePointer, U>& right)
+{
+ left.swap(right);
+}
+
+} // namespace estd
+
+#endif // ESTD_SORTEDINTRUSIVELIST_HPP_
diff --git a/include/estd/TypeErasedFunctor.hpp b/include/estd/TypeErasedFunctor.hpp
new file mode 100644
index 0000000..a19d59b
--- /dev/null
+++ b/include/estd/TypeErasedFunctor.hpp
@@ -0,0 +1,99 @@
+/**
+ * \file
+ * \brief TypeErasedFunctor template 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 ESTD_TYPEERASEDFUNCTOR_HPP_
+#define ESTD_TYPEERASEDFUNCTOR_HPP_
+
+namespace estd
+{
+
+template<typename Signature, bool NonConst = {}>
+class TypeErasedFunctor;
+
+/**
+ * \brief TypeErasedFunctor class is an interface for type-erased functors.
+ *
+ * Overload with const operator()().
+ *
+ * \tparam R is the type returned by <em>TypeErasedFunctor::operator()() const</em>
+ * \tparam Args are the types of arguments for <em>TypeErasedFunctor::operator()() const</em>
+ */
+
+template<typename R, typename... Args>
+class TypeErasedFunctor<R(Args...), false>
+{
+public:
+
+ /**
+ * \brief Function call operator of TypeErasedFunctor
+ *
+ * \param [in,out] args are arguments for derived function
+ *
+ * \return value returned by derived function
+ */
+
+ virtual R operator()(Args... args) const = 0;
+
+protected:
+
+ /**
+ * \brief TypeErasedFunctor's destructor
+ *
+ * \note Polymorphic objects of TypeErasedFunctor type must not be deleted via pointer/reference
+ */
+
+ ~TypeErasedFunctor()
+ {
+
+ }
+};
+
+/**
+ * \brief TypeErasedFunctor class is an interface for type-erased functors.
+ *
+ * Overload with non-const operator()().
+ *
+ * \tparam R is the type returned by <em>TypeErasedFunctor::operator()()</em>
+ * \tparam Args are the types of arguments for <em>TypeErasedFunctor::operator()()</em>
+ */
+
+template<typename R, typename... Args>
+class TypeErasedFunctor<R(Args...), true>
+{
+public:
+
+ /**
+ * \brief Function call operator of TypeErasedFunctor
+ *
+ * \param [in,out] args are arguments for derived function
+ *
+ * \return value returned by derived function
+ */
+
+ virtual R operator()(Args... args) = 0;
+
+protected:
+
+ /**
+ * \brief TypeErasedFunctor's destructor
+ *
+ * \note Polymorphic objects of TypeErasedFunctor type must not be deleted via pointer/reference
+ */
+
+ ~TypeErasedFunctor()
+ {
+
+ }
+};
+
+} // namespace estd
+
+#endif // ESTD_TYPEERASEDFUNCTOR_HPP_
diff --git a/include/estd/apply.hpp b/include/estd/apply.hpp
new file mode 100644
index 0000000..743cce6
--- /dev/null
+++ b/include/estd/apply.hpp
@@ -0,0 +1,73 @@
+/**
+ * \file
+ * \brief apply() 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 ESTD_APPLY_HPP_
+#define ESTD_APPLY_HPP_
+
+#include "estd/IntegerSequence.hpp"
+#include "estd/invoke.hpp"
+
+#include <tuple>
+
+namespace estd
+{
+
+namespace internal
+{
+
+/**
+ * \brief Implementation of apply()
+ *
+ * \tparam Function is the function object that will be invoked
+ * \tparam Tuple is the type of tuple of arguments
+ * \tparam Indexes is a sequence of std::size_t indexes for \a Tuple
+ *
+ * \param [in] function is the function object that will be executed
+ * \param [in] tuple is the tuple of arguments
+ *
+ * \return value returned by call to \a function with arguments from \a tuple
+ */
+
+template<typename Function, typename Tuple, std::size_t... Indexes>
+constexpr auto apply(Function&& function, Tuple&& tuple, estd::IndexSequence<Indexes...>) ->
+ decltype(estd::invoke(std::forward<Function>(function), std::get<Indexes>(std::forward<Tuple>(tuple))...))
+{
+ return estd::invoke(std::forward<Function>(function), std::get<Indexes>(std::forward<Tuple>(tuple))...);
+}
+
+} // namespace internal
+
+/**
+ * \brief Invokes callable object with a tuple of arguments.
+ *
+ * Implementation inspired by http://en.cppreference.com/w/cpp/experimental/apply
+ *
+ * \tparam Function is the function object that will be invoked
+ * \tparam Tuple is the type of tuple of arguments
+ *
+ * \param [in] function is the function object that will be executed
+ * \param [in] tuple is the tuple of arguments
+ *
+ * \return value returned by call to \a function with arguments from \a tuple
+ */
+
+template <typename Function, typename Tuple>
+constexpr auto apply(Function&& function, Tuple&& tuple) ->
+ decltype(internal::apply(std::forward<Function>(function), std::forward<Tuple>(tuple),
+ estd::MakeIndexSequence<std::tuple_size<typename std::decay<Tuple>::type>{}>{}))
+{
+ return internal::apply(std::forward<Function>(function), std::forward<Tuple>(tuple),
+ estd::MakeIndexSequence<std::tuple_size<typename std::decay<Tuple>::type>{}>{});
+}
+
+} // namespace estd
+
+#endif // ESTD_APPLY_HPP_
diff --git a/include/estd/invoke.hpp b/include/estd/invoke.hpp
new file mode 100644
index 0000000..bdac1a0
--- /dev/null
+++ b/include/estd/invoke.hpp
@@ -0,0 +1,147 @@
+/**
+ * \file
+ * \brief invoke() 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 ESTD_INVOKE_HPP_
+#define ESTD_INVOKE_HPP_
+
+#include <utility>
+
+namespace estd
+{
+
+namespace internal
+{
+
+/**
+ * \brief Implementation of invoke() for function objects
+ *
+ * \tparam Function is the function object that will be executed
+ * \tparam Args are the arguments for \a Function
+ *
+ * \param [in] function is the function object that will be executed
+ * \param [in] args are arguments for \a function
+ *
+ * \return value returned by call to \a function with \a args
+ */
+
+template<typename Function, typename... Args>
+inline auto invoke(Function&& function, Args&&... args) ->
+ decltype(std::forward<Function>(function)(std::forward<Args>(args)...))
+{
+ return std::forward<Function>(function)(std::forward<Args>(args)...);
+}
+
+/**
+ * \brief Implementation of invoke() for member functions
+ *
+ * \tparam T is the type returned by call to member function
+ * \tparam Base is the type of base class
+ * \tparam Derived is the type of derived class
+ * \tparam Args are the arguments for member function
+ *
+ * \param [in] memberFunction is a pointer to member function of \a object that will be executed
+ * \param [in] object is an object or a reference to object on which \a memberFunction will be executed
+ * \param [in] args are arguments for \a memberFunction
+ *
+ * \return value returned by call to \a memberFunction on \a object with \a args
+ */
+
+template<typename T, typename Base, typename Derived, typename... Args>
+inline auto invoke(T Base::* memberFunction, Derived&& object, Args&&... args) ->
+ decltype((std::forward<Derived>(object).*memberFunction)(std::forward<Args>(args)...))
+{
+ return (std::forward<Derived>(object).*memberFunction)(std::forward<Args>(args)...);
+}
+
+/**
+ * \brief Implementation of invoke() for member functions
+ *
+ * \tparam MemberFunction is the type or pointer to member function
+ * \tparam Pointer is the type of pointer to object
+ * \tparam Args are the arguments for member function
+ *
+ * \param [in] memberFunction is a pointer to member function of object that will be executed
+ * \param [in] pointer is a pointer to object on which \a memberFunction will be executed
+ * \param [in] args are arguments for \a memberFunction
+ *
+ * \return value returned by call to \a memberFunction on \a (*pointer) with \a args
+ */
+
+template<typename MemberFunction, typename Pointer, typename... Args>
+inline auto invoke(MemberFunction memberFunction, Pointer&& pointer, Args&&... args) ->
+ decltype(((*std::forward<Pointer>(pointer)).*memberFunction)(std::forward<Args>(args)...))
+{
+ return ((*std::forward<Pointer>(pointer)).*memberFunction)(std::forward<Args>(args)...);
+}
+
+/**
+ * \brief Implementation of invoke() for data members
+ *
+ * \tparam T is the type of data member
+ * \tparam Base is the type of base class
+ * \tparam Derived is the type of derived class
+ *
+ * \param [in] dataMember is a pointer to data member of \a object that will be accessed
+ * \param [in] object is an object or a reference to object in which \a dataMember will be accessed
+ *
+ * \return value returned by access to \a dataMember in \a object
+ */
+
+template<typename T, typename Base, typename Derived>
+inline auto invoke(T Base::* dataMember, Derived&& object) -> decltype(std::forward<Derived>(object).*dataMember)
+{
+ return std::forward<Derived>(object).*dataMember;
+}
+
+/**
+ * \brief Implementation of invoke() for data members
+ *
+ * \tparam DataMember is the type or pointer to data member
+ * \tparam Pointer is the type of pointer to object
+ *
+ * \param [in] dataMember is a pointer to data member of object that will be accessed
+ * \param [in] pointer is a pointer to object in which \a dataMember will be accessed
+ *
+ * \return value returned by access to \a dataMember in \a (*pointer)
+ */
+
+template<typename DataMember, typename Pointer>
+inline auto invoke(DataMember dataMember, Pointer&& pointer) -> decltype((*std::forward<Pointer>(pointer)).*dataMember)
+{
+ return (*std::forward<Pointer>(pointer)).*dataMember;
+}
+
+} // namespace internal
+
+/**
+ * \brief Invokes callable object in an appropriate way.
+ *
+ * Implementation inspired by http://en.cppreference.com/w/cpp/utility/functional/invoke
+ *
+ * \tparam Function is the function object that will be executed
+ * \tparam Args are the arguments for \a Function
+ *
+ * \param [in] function is the function object that will be executed
+ * \param [in] args are arguments for \a function
+ *
+ * \return value returned by call to \a function with \a args
+ */
+
+template<typename Function, typename... Args>
+auto invoke(Function&& function, Args&&... args) ->
+ decltype(internal::invoke(std::forward<Function>(function), std::forward<Args>(args)...))
+{
+ return internal::invoke(std::forward<Function>(function), std::forward<Args>(args)...);
+}
+
+} // namespace estd
+
+#endif // ESTD_INVOKE_HPP_
diff --git a/include/motor.h b/include/motor.h
deleted file mode 100644
index cf15088..0000000
--- a/include/motor.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef MOTOR_H_
-#define MOTOR_H_
-
-#include "ch.h"
-#include "hal.h"
-#include "vex.h"
-
-typedef enum {
- /* 1 */ mClawThingy = kVexMotor_1,
- /* 2 */ mLiftHighLeft,
- /* 3 */ mLiftLowLeft,
- /* 4 */ mLiftHighRight,
- /* 5 */ mLiftLowRight,
- /* 6 */ mDriveFrontLeft,
- /* 7 */ mDriveBackLeft,
- /* 8 */ mDriveBackRight,
- /* 9 */ mDriveFrontRight,
- /* 10 */ mPickupThingy,
-} motor_port_t;
-
-constexpr const tVexImeChannels iLiftLowLeft = kImeChannel_1;
-constexpr const tVexImeChannels iLiftHighLeft = kImeChannel_2;
-constexpr const tVexImeChannels iLiftLowRight = kImeChannel_3;
-constexpr const tVexImeChannels iLiftHighRight = kImeChannel_4;
-
-#define DIGI_CFG_DIGI_OUT(p) { kVexDigital_##p, kVexSensorDigitalOutput, kVexConfigOutput, 0 }
-#define DIGI_CFG_DIGI_IN(p) { kVexDigital_##p, kVexSensorDigitalInput, kVexConfigInput, 0 }
-
-#define MOTOR_CFG_MOT(p, t, r) (tVexMotor)p, kVexMotor##t, kVexMotor##r
-#define MOTOR_CFG_NOIME kVexSensorNone, 0
-#define MOTOR_CFG_IME(c) kVexSensorIME, c
-
-#endif // MOTOR_H_
diff --git a/include/sys/signal.h b/include/sys/signal.h
new file mode 100644
index 0000000..02509ac
--- /dev/null
+++ b/include/sys/signal.h
@@ -0,0 +1,41 @@
+/**
+ * \file
+ * \brief Override for newlib's sys/signal.h
+ *
+ * \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_SYS_SIGNAL_H_
+#define INCLUDE_SYS_SIGNAL_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* def __cplusplus */
+
+/*---------------------------------------------------------------------------------------------------------------------+
+| global types
++---------------------------------------------------------------------------------------------------------------------*/
+
+/** pointer to function taking an int argument (required by newlib's signal.h) */
+typedef void (* _sig_func_ptr)(int);
+
+/** standard sigval union - integer and void pointer */
+union sigval
+{
+ /** integer signal value */
+ int sival_int;
+
+ /** pointer signal value */
+ void* sival_ptr;
+};
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* def __cplusplus */
+
+#endif /* INCLUDE_SYS_SIGNAL_H_ */
diff --git a/libdistortos.a b/libdistortos.a
new file mode 100644
index 0000000..54a0aa1
--- /dev/null
+++ b/libdistortos.a
Binary files differ
diff --git a/main.cpp b/main.cpp
deleted file mode 100644
index 38b6a1b..0000000
--- a/main.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*-----------------------------------------------------------------------------*/
-/* */
-/* Copyright (c) James Pearman */
-/* 2013 */
-/* All Rights Reserved */
-/* */
-/*-----------------------------------------------------------------------------*/
-/* */
-/* Module: vexmain.c */
-/* Author: James Pearman */
-/* Created: 7 May 2013 */
-/* */
-/* Revisions: */
-/* V1.00 04 July 2013 - Initial release */
-/* */
-/*-----------------------------------------------------------------------------*/
-/* */
-/* The author is supplying this software for use with the VEX cortex */
-/* control system. This file can be freely distributed and teams are */
-/* authorized to freely use this program , however, it is requested that */
-/* improvements or additions be shared with the Vex community via the vex */
-/* forum. Please acknowledge the work of the authors when appropriate. */
-/* Thanks. */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
-/* See the License for the specific language governing permissions and */
-/* limitations under the License. */
-/* */
-/* The author can be contacted on the vex forums as jpearman */
-/* or electronic mail using jbpearman_at_mac_dot_com */
-/* Mentor for team 8888 RoboLancers, Pasadena CA. */
-/* */
-/*-----------------------------------------------------------------------------*/
-
-
-#include <string.h>
-
-#include "ch.h"
-#include "hal.h"
-#include "chprintf.h"
-#include "vex.h"
-
-/*-----------------------------------------------------------------------------*/
-/* Command line related. */
-/*-----------------------------------------------------------------------------*/
-
-#define SHELL_WA_SIZE THD_WA_SIZE(512)
-
-// Shell command
-static const ShellCommand commands[] = {
- {"adc", vexAdcDebug },
- {"spi", vexSpiDebug },
- {"motor", vexMotorDebug},
- {"lcd", vexLcdDebug},
- {"enc", vexEncoderDebug},
- {"son", vexSonarDebug},
- {"ime", vexIMEDebug},
- {"test", vexTestDebug},
- {NULL, NULL}
-};
-
-// configuration for the shell
-static const ShellConfig shell_cfg1 = {
- (vexStream *)SD_CONSOLE,
- commands
-};
-
-/*-----------------------------------------------------------------------------*/
-// Application entry point. */
-/*-----------------------------------------------------------------------------*/
-
-int main(void)
-{
- Thread *shelltp = NULL;
- short timeout = 0;
-
- // System initializations.
- // - HAL initialization, this also initializes the configured device drivers
- // and performs the board-specific initializations.
- // - Kernel initialization, the main() function becomes a thread and the
- // RTOS is active.
- halInit();
- chSysInit();
-
- // Init the serial port associated with the console
- vexConsoleInit();
-
- // init VEX
- vexCortexInit();
-
- // wait for good spi comms
- while( vexSpiGetOnlineStatus() == 0 )
- {
- // wait for a while
- chThdSleepMilliseconds(100);
- // dump after 5 seconds
- if(timeout++ == 50)
- break;
- }
-
- // Shell manager initialization.
- shellInit();
-
- // spin in loop monitoring the shell
- while (TRUE)
- {
- if (!shelltp)
- shelltp = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO);
- else
- if (chThdTerminated(shelltp))
- {
- chThdRelease(shelltp); /* Recovers memory of the previous shell. */
- shelltp = NULL; /* Triggers spawning of a new shell. */
- }
-
- chThdSleepMilliseconds(50);
- }
-}
diff --git a/mcuconf.h b/mcuconf.h
deleted file mode 100644
index 8095cb7..0000000
--- a/mcuconf.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-#define STM32F103_MCUCONF
-
-/*
- * STM32F1xx drivers configuration.
- * The following settings override the default settings present in
- * the various device driver implementation headers.
- * Note that the settings for each driver only have effect if the whole
- * driver is enabled in halconf.h.
- *
- * IRQ priorities:
- * 15...0 Lowest...Highest.
- *
- * DMA priorities:
- * 0...3 Lowest...Highest.
- */
-
-/*
- * HAL driver system settings.
- */
-#define STM32_NO_INIT FALSE
-#define STM32_HSI_ENABLED TRUE
-#define STM32_LSI_ENABLED FALSE
-#define STM32_HSE_ENABLED TRUE
-#define STM32_LSE_ENABLED FALSE
-#define STM32_SW STM32_SW_PLL
-#define STM32_PLLSRC STM32_PLLSRC_HSE
-#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
-#define STM32_PLLMUL_VALUE 9
-#define STM32_HPRE STM32_HPRE_DIV1
-#define STM32_PPRE1 STM32_PPRE1_DIV2
-#define STM32_PPRE2 STM32_PPRE2_DIV1
-#define STM32_ADCPRE STM32_ADCPRE_DIV8
-#define STM32_USB_CLOCK_REQUIRED TRUE
-#define STM32_USBPRE STM32_USBPRE_DIV1P5
-#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
-#define STM32_RTCSEL STM32_RTCSEL_HSEDIV
-#define STM32_PVD_ENABLE FALSE
-#define STM32_PLS STM32_PLS_LEV0
-
-/*
- * ADC driver system settings.
- */
-#define STM32_ADC_USE_ADC1 TRUE
-#define STM32_ADC_ADC1_DMA_PRIORITY 2
-#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-
-/*
- * CAN driver system settings.
- */
-#define STM32_CAN_USE_CAN1 TRUE
-#define STM32_CAN_CAN1_IRQ_PRIORITY 11
-
-/*
- * EXT driver system settings.
- */
-#define STM32_EXT_EXTI0_IRQ_PRIORITY 6
-#define STM32_EXT_EXTI1_IRQ_PRIORITY 6
-#define STM32_EXT_EXTI2_IRQ_PRIORITY 6
-#define STM32_EXT_EXTI3_IRQ_PRIORITY 6
-#define STM32_EXT_EXTI4_IRQ_PRIORITY 6
-#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
-#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6
-#define STM32_EXT_EXTI16_IRQ_PRIORITY 6
-#define STM32_EXT_EXTI17_IRQ_PRIORITY 6
-#define STM32_EXT_EXTI18_IRQ_PRIORITY 6
-#define STM32_EXT_EXTI19_IRQ_PRIORITY 6
-
-/*
- * GPT driver system settings.
- */
-#define STM32_GPT_USE_TIM1 TRUE
-#define STM32_GPT_USE_TIM2 TRUE
-#define STM32_GPT_USE_TIM3 FALSE
-#define STM32_GPT_USE_TIM4 FALSE
-#define STM32_GPT_USE_TIM5 TRUE
-#define STM32_GPT_USE_TIM8 FALSE
-#define STM32_GPT_TIM1_IRQ_PRIORITY 7
-#define STM32_GPT_TIM2_IRQ_PRIORITY 7
-#define STM32_GPT_TIM3_IRQ_PRIORITY 7
-#define STM32_GPT_TIM4_IRQ_PRIORITY 7
-#define STM32_GPT_TIM5_IRQ_PRIORITY 7
-#define STM32_GPT_TIM8_IRQ_PRIORITY 7
-
-/*
- * I2C driver system settings.
- */
-#define STM32_I2C_USE_I2C1 TRUE
-#define STM32_I2C_USE_I2C2 FALSE
-#define STM32_I2C_USE_I2C3 FALSE
-#define STM32_I2C_I2C1_IRQ_PRIORITY 10
-#define STM32_I2C_I2C2_IRQ_PRIORITY 10
-#define STM32_I2C_I2C3_IRQ_PRIORITY 10
-#define STM32_I2C_I2C1_DMA_PRIORITY 1
-#define STM32_I2C_I2C2_DMA_PRIORITY 1
-#define STM32_I2C_I2C3_DMA_PRIORITY 1
-#define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt()
-#define STM32_I2C_I2C3_DMA_ERROR_HOOK() chSysHalt()
-
-/*
- * ICU driver system settings.
- */
-#define STM32_ICU_USE_TIM1 FALSE
-#define STM32_ICU_USE_TIM2 FALSE
-#define STM32_ICU_USE_TIM3 FALSE
-#define STM32_ICU_USE_TIM4 FALSE
-#define STM32_ICU_USE_TIM5 FALSE
-#define STM32_ICU_USE_TIM8 FALSE
-#define STM32_ICU_TIM1_IRQ_PRIORITY 7
-#define STM32_ICU_TIM2_IRQ_PRIORITY 7
-#define STM32_ICU_TIM3_IRQ_PRIORITY 7
-#define STM32_ICU_TIM4_IRQ_PRIORITY 7
-#define STM32_ICU_TIM5_IRQ_PRIORITY 7
-#define STM32_ICU_TIM8_IRQ_PRIORITY 7
-
-/*
- * PWM driver system settings.
- */
-#define STM32_PWM_USE_ADVANCED FALSE
-#define STM32_PWM_USE_TIM1 FALSE
-#define STM32_PWM_USE_TIM2 FALSE
-#define STM32_PWM_USE_TIM3 FALSE
-#define STM32_PWM_USE_TIM4 FALSE
-#define STM32_PWM_USE_TIM5 FALSE
-#define STM32_PWM_USE_TIM8 FALSE
-#define STM32_PWM_TIM1_IRQ_PRIORITY 7
-#define STM32_PWM_TIM2_IRQ_PRIORITY 7
-#define STM32_PWM_TIM3_IRQ_PRIORITY 7
-#define STM32_PWM_TIM4_IRQ_PRIORITY 7
-#define STM32_PWM_TIM5_IRQ_PRIORITY 7
-#define STM32_PWM_TIM8_IRQ_PRIORITY 7
-
-/*
- * RTC driver system settings.
- */
-#define STM32_RTC_IRQ_PRIORITY 15
-
-/*
- * SERIAL driver system settings.
- */
-#define STM32_SERIAL_USE_USART1 TRUE
-#define STM32_SERIAL_USE_USART2 TRUE
-#define STM32_SERIAL_USE_USART3 TRUE
-#define STM32_SERIAL_USE_UART4 FALSE
-#define STM32_SERIAL_USE_UART5 FALSE
-#define STM32_SERIAL_USE_USART6 FALSE
-#define STM32_SERIAL_USART1_PRIORITY 12
-#define STM32_SERIAL_USART2_PRIORITY 12
-#define STM32_SERIAL_USART3_PRIORITY 12
-#define STM32_SERIAL_UART4_PRIORITY 12
-#define STM32_SERIAL_UART5_PRIORITY 12
-#define STM32_SERIAL_USART6_PRIORITY 12
-
-/*
- * SPI driver system settings.
- */
-#define STM32_SPI_USE_SPI1 TRUE
-#define STM32_SPI_USE_SPI2 FALSE
-#define STM32_SPI_USE_SPI3 FALSE
-#define STM32_SPI_SPI1_DMA_PRIORITY 1
-#define STM32_SPI_SPI2_DMA_PRIORITY 1
-#define STM32_SPI_SPI3_DMA_PRIORITY 1
-#define STM32_SPI_SPI1_IRQ_PRIORITY 10
-#define STM32_SPI_SPI2_IRQ_PRIORITY 10
-#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
-
-/*
- * UART driver system settings.
- */
-#define STM32_UART_USE_USART1 FALSE
-#define STM32_UART_USE_USART2 FALSE
-#define STM32_UART_USE_USART3 FALSE
-#define STM32_UART_USART1_IRQ_PRIORITY 12
-#define STM32_UART_USART2_IRQ_PRIORITY 12
-#define STM32_UART_USART3_IRQ_PRIORITY 12
-#define STM32_UART_USART1_DMA_PRIORITY 0
-#define STM32_UART_USART2_DMA_PRIORITY 0
-#define STM32_UART_USART3_DMA_PRIORITY 0
-#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
-
-/*
- * USB driver system settings.
- */
-#define STM32_USB_USE_USB1 FALSE
-#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
-#define STM32_USB_USB1_HP_IRQ_PRIORITY 6
-#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
diff --git a/setup.mk b/setup.mk
deleted file mode 100644
index 131405e..0000000
--- a/setup.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# uncomment these if running from default project location
-# Path to ChibiOS
-#CHIBIOS = ../ChibiOS_2.6.2
-# Path to convex
-#CONVEX = ../convex/cortex
-
-# uncomment to use the optional code like the smart motor library
-#CONVEX_OPT = yes
-
-# User C code files
-VEXUSERSRC = vexuser.cpp src/motor.cpp
-
-# Uncomment and add/modify user include files
-VEXUSERINC = include/
-
diff --git a/src/motor.cpp b/src/motor.cpp
deleted file mode 100644
index d9e7c4b..0000000
--- a/src/motor.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <motor.h>
-
-
diff --git a/vexuser.cpp b/vexuser.cpp
deleted file mode 100644
index 8bd3088..0000000
--- a/vexuser.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-#include <unistd.h>
-#include <array>
-
-#include "ch.h" // needs for all ChibiOS programs
-#include "hal.h" // hardware abstraction layer header
-#include "vex.h" // vex library header
-
-#include <motor.h>
-#include <control.h>
-
-//static WORKING_AREA(waVexIME, 512);
-//static msg_t vexIME(void *);
-
-// Digi IO configuration
-static vexDigiCfg dConfig[] = {
-};
-
-static vexMotorCfg mConfig[] = {
- { MOTOR_CFG_MOT(mClawThingy, 393T, Normal), MOTOR_CFG_NOIME },
- { MOTOR_CFG_MOT(mDriveFrontLeft, 393T, Normal), MOTOR_CFG_NOIME },
- { MOTOR_CFG_MOT(mDriveFrontRight, 393T, Reversed), MOTOR_CFG_NOIME },
- { MOTOR_CFG_MOT(mDriveBackLeft, 393T, Reversed), MOTOR_CFG_NOIME },
- { MOTOR_CFG_MOT(mDriveBackRight, 393T, Normal), MOTOR_CFG_NOIME },
- { MOTOR_CFG_MOT(mLiftLowRight, 393T, Normal), MOTOR_CFG_IME(iLiftLowRight) },
- { MOTOR_CFG_MOT(mLiftHighRight, 393T, Normal), MOTOR_CFG_IME(iLiftHighRight) },
- { MOTOR_CFG_MOT(mLiftLowLeft, 393T, Normal), MOTOR_CFG_IME(iLiftLowLeft) },
- { MOTOR_CFG_MOT(mLiftHighLeft, 393T, Normal), MOTOR_CFG_IME(iLiftHighLeft) },
- { MOTOR_CFG_MOT(mPickupThingy, 393T, Normal), MOTOR_CFG_NOIME }
-};
-
-void vexUserSetup(void)
-{
- vexDigitalConfigure(dConfig, DIG_CONFIG_SIZE(dConfig));
- vexMotorConfigure(mConfig, MOT_CONFIG_SIZE(mConfig));
-}
-
-void vexUserInit(void)
-{}
-
-#define AIRCR_ADDR 0xE000ED0C
-#define VECTKEY 0x05FA
-#define SYSRESETREQ (1<<2)
-#define VECTRESET (1<<0)
-
-void softwareReset(void){
- uint32_t AIRCR = *((uint32_t *)AIRCR_ADDR);
- AIRCR = (AIRCR & 0xFFFF) | (VECTKEY << 16) | SYSRESETREQ | VECTRESET;
- *((volatile uint32_t *)0xE000ED0C) = AIRCR;
- asm("DSB");
- while(1);
-}
-
-msg_t vexAutonomous(void* arg)
-{
- (void)arg;
-
- vexTaskRegister("auton");
-
- vexMotorSet(mClawThingy, -127);
- vexMotorSet(mPickupThingy, -64);
- vexSleep(300);
- vexMotorSet(mClawThingy, 0);
- vexMotorSet(mPickupThingy, 0);
-
- vexMotorSet(mDriveFrontLeft, -127);
- vexMotorSet(mDriveFrontRight, -127);
- vexMotorSet(mDriveBackLeft, -127);
- vexMotorSet(mDriveBackRight, -127);
- vexSleep(3000);
- vexMotorSet(mDriveFrontLeft, 30);
- vexMotorSet(mDriveFrontRight, 30);
- vexMotorSet(mDriveBackLeft, 30);
- vexMotorSet(mDriveBackRight, 30);
- vexSleep(1000);
- vexMotorSet(mDriveFrontLeft, 0);
- vexMotorSet(mDriveFrontRight, 0);
- vexMotorSet(mDriveBackLeft, 0);
- vexMotorSet(mDriveBackRight, 0);
-
- while(1)
- vexSleep(25);
-
- return (msg_t)0;
-}
-
-int doubleButton(int btnp, int btnn, int speed);
-
-msg_t vexOperator(void* arg)
-{
- Controller joyMain (1);
-
- (void)arg;
-
- vexTaskRegister("operator");
-
- //chThdCreateStatic(waVexIME, sizeof(waVexIME), NORMALPRIO - 1, vexIME, nullptr);
-
- while(!chThdShouldTerminate()) {
-
- // control update
- joyMain.update();
-
- // drive motors
- int dx = joyMain->Ch4, dy = -joyMain->Ch3;
- vexMotorSet(mDriveFrontLeft, dy - dx);
- vexMotorSet(mDriveFrontRight, dy + dx);
- vexMotorSet(mDriveBackLeft, dy - dx);
- vexMotorSet(mDriveBackRight, dy + dx);
-
- // lift motors
-#ifndef NEW_LIFT
- int ly = joyMain->Ch2;
- vexMotorSet(mLiftLowRight, ly);
- vexMotorSet(mLiftHighRight, ly);
- vexMotorSet(mLiftLowLeft, ly);
- vexMotorSet(mLiftHighLeft, ly);
-#else
- if (joyMain->Btn8U)
- motorCountInc();
- else if (joyMain->Btn7D)
- motorCountDec();
-#endif // NEW_LIFT
-
- // lift thingy
- vexMotorSet(mPickupThingy, doubleButton(joyMain->Btn5U, joyMain->Btn5D, 64));
-
- // claw thingy
- vexMotorSet(mClawThingy, doubleButton(joyMain->Btn6U, joyMain->Btn6D, 127));
-
- if (joyMain->Btn8R)
- softwareReset();
-
- vexSleep(25);
- }
-
- return (msg_t)0;
-}
-
-
-int doubleButton(int btnp, int btnn, int speed)
-{
- return (btnp ? speed : (btnn ? -speed : 0));
-}
-
-extern "C" {
- void _exit(int code) {
- (void)code;
-
- vexLcdPrintf(0, 0, "PANIC: exit(%d)", code);
- vexLcdPrintf(0, 1, "Halting...");
-
- while(1);
- }
- void _kill(pid_t pid) {
- (void)pid;
- // no way to kill here
- }
- pid_t _getpid(void) {
- // no pids here
- return 0;
- }
-}
-
-/*using CountTuple = std::tuple<tVexMotor, tVexImeChannels, int32_t>;
-
-static std::array<CountTuple, 4> MotorCounts = {
- std::make_tuple(mLiftLowLeft, iLiftLowLeft, 0),
- std::make_tuple(mLiftHighLeft, iLiftHighLeft, 0),
- std::make_tuple(mLiftLowRight, iLiftLowRight, 0),
- std::make_tuple(mLiftHighRight, iLiftHighRight, 0)
-};
-
-void
-motorCountInc(void)
-{
- for (auto &c : MotorCounts)
- std::get<2>(c) += 10;
-}
-
-void
-motorCountDec(void)
-{
- for (auto &c : MotorCounts)
- std::get<2>(c) -= 10;
-}
-
-static msg_t
-vexIME(void *arg)
-{
- (void)arg;
-
- vexTaskRegister("uime");
-
- while (1) {
- for (auto &c : MotorCounts) {
- auto count = vexImeGetPtr(std::get<1>(c))->count;
- auto comp = std::get<2>(c);
-
- if (count > comp)
- vexMotorSet(vexMotorGet(std::get<0>(c)) - 2);
- else if(count < comp)
- vexMotorSet(vexMotorGet(std::get<0>(c)) + 2);
- }
-
- vexSleep(100);
- }
-}*/