distortos  v0.7.0
object-oriented C++ RTOS for microcontrollers
StaticThread.hpp
Go to the documentation of this file.
1 
12 #ifndef INCLUDE_DISTORTOS_STATICTHREAD_HPP_
13 #define INCLUDE_DISTORTOS_STATICTHREAD_HPP_
14 
16 
17 #include "distortos/assert.h"
20 
21 #include <functional>
22 
23 namespace distortos
24 {
25 
26 namespace internal
27 {
28 
37 template<size_t StackSize, typename Function, typename... Args>
39 {
40 public:
41 
44 
56  StaticThreadBase(const uint8_t priority, const SchedulingPolicy schedulingPolicy,
57  SignalsReceiver* const signalsReceiver, Function&& function, Args&&... args) :
58  Base{{{&stack_, internal::dummyDeleter<decltype(stack_)>}, sizeof(stack_)}, priority,
59  schedulingPolicy, nullptr, signalsReceiver},
60  boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)}
61  {
62 
63  }
64 
65  StaticThreadBase(const StaticThreadBase&) = delete;
67  const StaticThreadBase& operator=(const StaticThreadBase&) = delete;
68  StaticThreadBase& operator=(StaticThreadBase&&) = delete;
69 
79  int start()
80  {
82  }
83 
84 protected:
85 
92  void run() override
93  {
95  }
96 
97 private:
98 
100  constexpr static size_t adjustedStackSize {(StackSize + DISTORTOS_ARCHITECTURE_STACK_ALIGNMENT - 1) /
101  DISTORTOS_ARCHITECTURE_STACK_ALIGNMENT * DISTORTOS_ARCHITECTURE_STACK_ALIGNMENT};
102 
104  alignas(DISTORTOS_ARCHITECTURE_STACK_ALIGNMENT)
105  typename std::aligned_storage<adjustedStackSize + internal::stackGuardSize>::type stack_;
106 
107  static_assert(sizeof(stack_) % DISTORTOS_ARCHITECTURE_STACK_ALIGNMENT == 0, "Stack size is not aligned!");
108 
110  decltype(std::bind(std::declval<Function>(), std::declval<Args>()...)) boundFunction_;
111 };
112 
113 } // namespace internal
114 
117 
131 template<size_t StackSize, bool CanReceiveSignals, size_t QueuedSignals, size_t SignalActions, typename Function,
132  typename... Args>
133 class StaticThread : public internal::StaticThreadBase<StackSize, Function, Args...>
134 {
135 public:
136 
138  using Base = internal::StaticThreadBase<StackSize, Function, Args...>;
139 
149  StaticThread(uint8_t priority, SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args);
150 
159  StaticThread(const uint8_t priority, Function&& function, Args&&... args) :
160  StaticThread{priority, SchedulingPolicy::roundRobin, std::forward<Function>(function),
161  std::forward<Args>(args)...}
162  {
163 
164  }
165 
166  StaticThread(const StaticThread&) = delete;
167  StaticThread(StaticThread&&) = default;
168  const StaticThread& operator=(const StaticThread&) = delete;
169  StaticThread& operator=(StaticThread&&) = delete;
170 };
171 
172 #if DISTORTOS_SIGNALS_ENABLE == 1
173 
189 template<size_t StackSize, size_t QueuedSignals, size_t SignalActions, typename Function, typename... Args>
190 class StaticThread<StackSize, true, QueuedSignals, SignalActions, Function, Args...> :
191  public internal::StaticThreadBase<StackSize, Function, Args...>
192 {
193 public:
194 
196  using Base = internal::StaticThreadBase<StackSize, Function, Args...>;
197 
207  StaticThread(uint8_t priority, SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args);
208 
217  StaticThread(const uint8_t priority, Function&& function, Args&&... args) :
218  StaticThread{priority, SchedulingPolicy::roundRobin, std::forward<Function>(function),
219  std::forward<Args>(args)...}
220  {
221 
222  }
223 
224  StaticThread(const StaticThread&) = delete;
225  StaticThread(StaticThread&&) = default;
226  const StaticThread& operator=(const StaticThread&) = delete;
227  StaticThread& operator=(StaticThread&&) = delete;
228 
229 private:
230 
233 };
234 
235 #endif // DISTORTOS_SIGNALS_ENABLE == 1
236 
257 template<size_t StackSize, bool CanReceiveSignals = {}, size_t QueuedSignals = {}, size_t SignalActions = {},
258  typename Function, typename... Args>
259 StaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions, Function, Args...>
260 makeStaticThread(const uint8_t priority, const SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args)
261 {
262  return {priority, schedulingPolicy, std::forward<Function>(function), std::forward<Args>(args)...};
263 }
264 
284 template<size_t StackSize, bool CanReceiveSignals = {}, size_t QueuedSignals = {}, size_t SignalActions = {},
285  typename Function, typename... Args>
286 StaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions, Function, Args...>
287 makeStaticThread(const uint8_t priority, Function&& function, Args&&... args)
288 {
289  return {priority, std::forward<Function>(function), std::forward<Args>(args)...};
290 }
291 
312 template<size_t StackSize, bool CanReceiveSignals = {}, size_t QueuedSignals = {}, size_t SignalActions = {},
313  typename Function, typename... Args>
314 StaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions, Function, Args...>
315 makeAndStartStaticThread(const uint8_t priority, const SchedulingPolicy schedulingPolicy, Function&& function,
316  Args&&... args)
317 {
318  auto thread = makeStaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions>(priority,
319  schedulingPolicy, std::forward<Function>(function), std::forward<Args>(args)...);
320  {
321  const auto ret = thread.start();
322  assert(ret == 0 && "Could not start thread!");
323  }
324  return thread;
325 }
326 
346 template<size_t StackSize, bool CanReceiveSignals = {}, size_t QueuedSignals = {}, size_t SignalActions = {},
347  typename Function, typename... Args>
348 StaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions, Function, Args...>
349 makeAndStartStaticThread(const uint8_t priority, Function&& function, Args&&... args)
350 {
351  auto thread = makeStaticThread<StackSize, CanReceiveSignals, QueuedSignals, SignalActions>(priority,
352  std::forward<Function>(function), std::forward<Args>(args)...);
353  {
354  const auto ret = thread.start();
355  assert(ret == 0 && "Could not start thread!");
356  }
357  return thread;
358 }
359 
361 
362 template<size_t StackSize, bool CanReceiveSignals, size_t QueuedSignals, size_t SignalActions, typename Function,
363  typename... Args>
365 StaticThread(const uint8_t priority, const SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args) :
366  Base{priority, schedulingPolicy, nullptr, std::forward<Function>(function), std::forward<Args>(args)...}
367 {
368 
369 }
370 
371 #if DISTORTOS_SIGNALS_ENABLE == 1
372 
373 template<size_t StackSize, size_t QueuedSignals, size_t SignalActions, typename Function, typename... Args>
375  const SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args) :
376  Base{priority, schedulingPolicy, &static_cast<SignalsReceiver&>(staticSignalsReceiver_),
377  std::forward<Function>(function), std::forward<Args>(args)...},
378  staticSignalsReceiver_{}
379 {
380 
381 }
382 
383 #endif // DISTORTOS_SIGNALS_ENABLE == 1
384 
385 } // namespace distortos
386 
387 #endif // INCLUDE_DISTORTOS_STATICTHREAD_HPP_
StaticThread(const uint8_t priority, Function &&function, Args &&... args)
StaticThread's constructor.
Definition: StaticThread.hpp:217
static constexpr size_t adjustedStackSize
size of stack adjusted to alignment requirements, bytes
Definition: StaticThread.hpp:100
UndetachableThread class is a ThreadCommon that cannot be detached.
Definition: UndetachableThread.hpp:28
StaticSignalsReceiver< QueuedSignals, SignalActions > staticSignalsReceiver_
internal StaticSignalsReceiver object
Definition: StaticThread.hpp:232
UndetachableThread class header.
StaticThread(const uint8_t priority, Function &&function, Args &&... args)
StaticThread's constructor.
Definition: StaticThread.hpp:159
StaticThreadBase class is a templated common base for StaticThread.
Definition: StaticThread.hpp:38
StaticThread< StackSize, CanReceiveSignals, QueuedSignals, SignalActions, Function, Args... > makeAndStartStaticThread(const uint8_t priority, const SchedulingPolicy schedulingPolicy, Function &&function, Args &&... args)
Helper factory function to make and start StaticThread object with partially deduced template argumen...
Definition: StaticThread.hpp:315
decltype(std::bind(std::declval< Function >(), std::declval< Args >()...)) boundFunction_
bound function object
Definition: StaticThread.hpp:107
int start()
Starts the thread.
Definition: StaticThread.hpp:79
SignalsReceiver class is a container for internal::SignalsReceiverControlBlock.
Definition: SignalsReceiver.hpp:32
SchedulingPolicy
scheduling policy of the thread
Definition: SchedulingPolicy.hpp:26
StaticThread< StackSize, CanReceiveSignals, QueuedSignals, SignalActions, Function, Args... > makeStaticThread(const uint8_t priority, const SchedulingPolicy schedulingPolicy, Function &&function, Args &&... args)
Helper factory function to make StaticThread object with partially deduced template arguments.
Definition: StaticThread.hpp:260
assert() macro
std::aligned_storage< adjustedStackSize+internal::stackGuardSize >::type stack_
stack buffer
Definition: StaticThread.hpp:105
StaticSignalsReceiver class header.
Top-level namespace of distortos project.
Definition: buttons.hpp:33
StaticThread(uint8_t priority, SchedulingPolicy schedulingPolicy, Function &&function, Args &&... args)
StaticThread's constructor.
Definition: StaticThread.hpp:365
void run() override
Thread's "run" function.
Definition: StaticThread.hpp:92
int startInternal()
Starts the thread.
Definition: ThreadCommon.cpp:164
void dummyDeleter(U *)
A "no-op" dummy deleter that can be used with std::unique_ptr and automatic storage that is trivially...
Definition: dummyDeleter.hpp:38
StaticThreadBase(const uint8_t priority, const SchedulingPolicy schedulingPolicy, SignalsReceiver *const signalsReceiver, Function &&function, Args &&... args)
StaticThreadBase's constructor.
Definition: StaticThread.hpp:56
StaticThread class is a templated interface for thread that has automatic storage for stack.
Definition: StaticThread.hpp:133
StaticSignalsReceiver class is a templated interface for SignalsReceiver that has automatic storage f...
Definition: StaticSignalsReceiver.hpp:38
round-robin scheduling policy
dummyDeleter() declaration