distortos  v0.5.0
object-oriented C++ RTOS for microcontrollers
DynamicThreadBase.hpp
Go to the documentation of this file.
1 
12 #ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_
13 #define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_
14 
18 
20 
21 #include <functional>
22 
23 namespace distortos
24 {
25 
26 #if CONFIG_THREAD_DETACH_ENABLE == 1
27 
28 class DynamicThread;
29 
30 #endif // CONFIG_THREAD_DETACH_ENABLE == 1
31 
32 namespace internal
33 {
34 
45 {
46 public:
47 
48 #if CONFIG_THREAD_DETACH_ENABLE == 1
49 
70  template<typename Function, typename... Args>
71  DynamicThreadBase(size_t stackSize, bool canReceiveSignals, size_t queuedSignals, size_t signalActions,
72  uint8_t priority, SchedulingPolicy schedulingPolicy, DynamicThread& owner, Function&& function,
73  Args&&... args);
74 
75 #else // CONFIG_THREAD_DETACH_ENABLE != 1
76 
96  template<typename Function, typename... Args>
97  DynamicThreadBase(size_t stackSize, bool canReceiveSignals, size_t queuedSignals, size_t signalActions,
98  uint8_t priority, SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args);
99 
111  template<typename Function, typename... Args>
112  DynamicThreadBase(const DynamicThreadParameters parameters, Function&& function, Args&&... args) :
113  DynamicThreadBase{parameters.stackSize, parameters.canReceiveSignals, parameters.queuedSignals,
114  parameters.signalActions, parameters.priority, parameters.schedulingPolicy,
115  std::forward<Function>(function), std::forward<Args>(args)...}
116  {
117 
118  }
119 
120 #endif // CONFIG_THREAD_DETACH_ENABLE != 1
121 
122 #if CONFIG_THREAD_DETACH_ENABLE == 1
123 
137  int detach() override;
138 
139 #endif // CONFIG_THREAD_DETACH_ENABLE == 1
140 
150  int start()
151  {
152 #if CONFIG_THREAD_DETACH_ENABLE == 1
154 #else // CONFIG_THREAD_DETACH_ENABLE != 1
156 #endif // CONFIG_THREAD_DETACH_ENABLE != 1
157  }
158 
159  DynamicThreadBase(const DynamicThreadBase&) = delete;
160  DynamicThreadBase(DynamicThreadBase&&) = default;
161  const DynamicThreadBase& operator=(const DynamicThreadBase&) = delete;
162  DynamicThreadBase& operator=(DynamicThreadBase&&) = delete;
163 
164 protected:
165 
166 #if CONFIG_THREAD_DETACH_ENABLE == 1
167 
176  static void preTerminationHook(Thread& thread);
177 
186  static void terminationHook(Thread& thread);
187 
188 #endif // CONFIG_THREAD_DETACH_ENABLE == 1
189 
190 private:
191 
202  static Stack makeStack(const size_t stackSize)
203  {
204  static_assert(alignof(max_align_t) >= CONFIG_ARCHITECTURE_STACK_ALIGNMENT,
205  "Alignment of dynamically allocated memory is too low!");
206 
207  const auto adjustedStackSize = (stackSize + CONFIG_ARCHITECTURE_STACK_ALIGNMENT - 1) /
208  CONFIG_ARCHITECTURE_STACK_ALIGNMENT * CONFIG_ARCHITECTURE_STACK_ALIGNMENT;
209  return {{new uint8_t[adjustedStackSize + stackGuardSize], storageDeleter<uint8_t>},
210  adjustedStackSize + stackGuardSize};
211  }
212 
221  static void run(Thread& thread);
222 
223 #if CONFIG_SIGNALS_ENABLE == 1
224 
227 
228 #endif // CONFIG_SIGNALS_ENABLE == 1
229 
231  std::function<void()> boundFunction_;
232 
233 #if CONFIG_THREAD_DETACH_ENABLE == 1
234 
237 
238 #endif // CONFIG_THREAD_DETACH_ENABLE == 1
239 };
240 
241 #if CONFIG_SIGNALS_ENABLE == 1 && CONFIG_THREAD_DETACH_ENABLE == 1
242 
243 template<typename Function, typename... Args>
244 DynamicThreadBase::DynamicThreadBase(const size_t stackSize, const bool canReceiveSignals, const size_t queuedSignals,
245  const size_t signalActions, const uint8_t priority, const SchedulingPolicy schedulingPolicy,
246  DynamicThread& owner, Function&& function, Args&&... args) :
247  ThreadCommon{makeStack(stackSize), priority, schedulingPolicy, nullptr,
248  canReceiveSignals == true ? &dynamicSignalsReceiver_ : nullptr},
249  dynamicSignalsReceiver_{canReceiveSignals == true ? queuedSignals : 0,
250  canReceiveSignals == true ? signalActions : 0},
251  boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)},
252  owner_{&owner}
253 {
254 
255 }
256 
257 #elif CONFIG_SIGNALS_ENABLE == 1 && CONFIG_THREAD_DETACH_ENABLE != 1
258 
259 template<typename Function, typename... Args>
260 DynamicThreadBase::DynamicThreadBase(const size_t stackSize, const bool canReceiveSignals, const size_t queuedSignals,
261  const size_t signalActions, const uint8_t priority, const SchedulingPolicy schedulingPolicy,
262  Function&& function, Args&&... args) :
263  ThreadCommon{makeStack(stackSize), priority, schedulingPolicy, nullptr,
264  canReceiveSignals == true ? &dynamicSignalsReceiver_ : nullptr},
265  dynamicSignalsReceiver_{canReceiveSignals == true ? queuedSignals : 0,
266  canReceiveSignals == true ? signalActions : 0},
267  boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)}
268 {
269 
270 }
271 
272 #elif CONFIG_SIGNALS_ENABLE != 1 && CONFIG_THREAD_DETACH_ENABLE == 1
273 
274 template<typename Function, typename... Args>
275 DynamicThreadBase::DynamicThreadBase(const size_t stackSize, bool, size_t, size_t, const uint8_t priority,
276  const SchedulingPolicy schedulingPolicy, DynamicThread& owner, Function&& function, Args&&... args) :
277  ThreadCommon{makeStack(stackSize), priority, schedulingPolicy, nullptr, nullptr},
278  boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)},
279  owner_{&owner}
280 {
281 
282 }
283 
284 #else // CONFIG_SIGNALS_ENABLE != 1 && CONFIG_THREAD_DETACH_ENABLE != 1
285 
286 template<typename Function, typename... Args>
287 DynamicThreadBase::DynamicThreadBase(const size_t stackSize, bool, size_t, size_t, const uint8_t priority,
288  const SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args) :
289  ThreadCommon{makeStack(stackSize), priority, schedulingPolicy, nullptr, nullptr},
290  boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)}
291 {
292 
293 }
294 
295 #endif // CONFIG_SIGNALS_ENABLE != 1 && CONFIG_THREAD_DETACH_ENABLE != 1
296 
297 } // namespace internal
298 
299 } // namespace distortos
300 
301 #endif // INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_
DynamicSignalsReceiver class header.
size_t queuedSignals
Definition: DynamicThreadParameters.hpp:78
int start()
Starts the thread.
Definition: DynamicThreadBase.hpp:150
DynamicThreadBase class is a type-erased interface for thread that has dynamic storage for bound func...
Definition: DynamicThreadBase.hpp:44
DynamicThreadParameters class header.
SchedulingPolicy schedulingPolicy
scheduling policy of the thread
Definition: DynamicThreadParameters.hpp:94
size_t stackSize
size of stack, bytes
Definition: DynamicThreadParameters.hpp:85
static void terminationHook(Thread &thread)
Termination hook function of thread.
Definition: DynamicThreadBase.cpp:68
SchedulingPolicy
scheduling policy of the thread
Definition: SchedulingPolicy.hpp:26
static Stack makeStack(const size_t stackSize)
Helper function to make stack with size adjusted to alignment requirements.
Definition: DynamicThreadBase.hpp:202
uint8_t priority
thread&#39;s priority, 0 - lowest, UINT8_MAX - highest
Definition: DynamicThreadParameters.hpp:91
static void run(Thread &thread)
Thread&#39;s "run" function.
Definition: DynamicThreadBase.cpp:84
DynamicThreadBase(size_t stackSize, bool canReceiveSignals, size_t queuedSignals, size_t signalActions, uint8_t priority, SchedulingPolicy schedulingPolicy, DynamicThread &owner, Function &&function, Args &&... args)
DynamicThreadBase&#39;s constructor.
Definition: DynamicThreadBase.hpp:244
bool canReceiveSignals
selects whether reception of signals is enabled (true) or disabled (false) for this thread ...
Definition: DynamicThreadParameters.hpp:88
DynamicSignalsReceiver class is a templated interface for SignalsReceiver that has dynamic storage fo...
Definition: DynamicSignalsReceiver.hpp:31
storageDeleter() definition
DynamicSignalsReceiver dynamicSignalsReceiver_
internal DynamicSignalsReceiver object
Definition: DynamicThreadBase.hpp:226
Top-level namespace of distortos project.
ThreadCommon class implements common functionality of threads.
Definition: ThreadCommon.hpp:29
void thread(uint32_t value, bool &sharedResult)
Test thread.
Definition: ARMv7-M-FpuThreadTestCase.cpp:68
DynamicThreadParameters struct is a helper with parameters for DynamicThread&#39;s constructor.
Definition: DynamicThreadParameters.hpp:32
Stack class is an abstraction of architecture&#39;s stack.
Definition: Stack.hpp:32
ThreadCommon class header.
static void preTerminationHook(Thread &thread)
Pre-termination hook function of thread.
Definition: DynamicThreadBase.cpp:60
constexpr size_t stackGuardSize
size of "stack guard", bytes
Definition: stackGuardSize.hpp:26
size_t signalActions
Definition: DynamicThreadParameters.hpp:82
std::function< void()> boundFunction_
bound function object
Definition: DynamicThreadBase.hpp:231
int detach() override
Detaches the thread.
Definition: DynamicThreadBase.cpp:38
int startInternal(void(&runFunction)(Thread &), void(*preTerminationHookFunction)(Thread &), void(&terminationHookFunction)(Thread &))
Starts the thread.
Definition: ThreadCommon.cpp:144
DynamicThread * owner_
pointer to owner DynamicThread object, nullptr if thread is detached
Definition: DynamicThreadBase.hpp:236
DynamicThread class is a type-erased interface for thread that has dynamic storage for bound function...
Definition: DynamicThread.hpp:32
Thread class is a pure abstract interface for threads.
Definition: Thread.hpp:32