RTOS Wrapper
API reference
Loading...
Searching...
No Matches
BaseThreadsManager.h
Go to the documentation of this file.
1
19#ifndef HF_UTILS_RTOS_WRAP_BASETHREADSMANAGER_H_
20#define HF_UTILS_RTOS_WRAP_BASETHREADSMANAGER_H_
21
22#include <algorithm>
23#include <map>
24#include <bitset>
25#include <functional>
26
27#include "OsAbstraction.h"
28
29#include "OsUtility.h"
30#include "Utility.h"
31#include "BaseThread.h"
32#include "Mutex.h"
33#include "MutexGuard.h"
34
35//==============================================================//
36// CLASS
37//==============================================================//
38template <typename EnumType, EnumType MaxCount> class BaseThreadsManager
39{
40 public:
41 BaseThreadsManager(const std::map<EnumType, BaseThread*>& threads, std::function<const char*(EnumType)> enumToStringFunc) ;
42
49
50
57
58 virtual ~BaseThreadsManager();
59
60 bool EnsureInitialized() noexcept;
61
62 bool ResumeAll() noexcept;
63
64 bool ResumeSelected(const std::vector<EnumType>& selectedEnums) noexcept;
65
66 bool StartAll() noexcept;
67
68 bool StartSelected(const std::vector<EnumType>& selectedEnums) noexcept;
69
70 bool StartAllExceptSelected(const std::vector<EnumType>& selectedEnums) noexcept;
71
72 bool StartAllAndWaitToVerify(uint32_t waitToVerifyTimeoutMsec) noexcept;
73
74 bool StartSelectedAndWaitToVerify(const std::vector<EnumType>& selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept;
75
76 bool StartAllExceptSelectedAndWaitToVerify(const std::vector<EnumType>& selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept;
77
78 bool StopAll() noexcept;
79
80 bool StopSelected(const std::vector<EnumType>& selectedEnums) noexcept;
81
82 bool StopAllExceptSelected(const std::vector<EnumType>& selectedEnums) noexcept;
83
84 bool StopAllAndWaitToVerify(uint32_t waitToVerifyTimeoutMsec) noexcept;
85
86 bool StopSelectedAndWaitToVerify(const std::vector<EnumType>& selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept;
87
88 bool StopAllExceptSelectedAndWaitToVerify(const std::vector<EnumType>& selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept;
89
90 virtual bool PreThreadInitializationActions() noexcept;
91
92 virtual bool PostThreadInitializationActions() noexcept;
93
94 private:
95
100 bool Initialize() noexcept;
101
102 //==============================================================//
103 // VERBOSE??
104 //==============================================================//
105 static constexpr bool verbose = false;
106 static constexpr bool timeBetweenChecksMsec = 10;
107
111 static const char mutexName[];
112
113 std::map<EnumType, BaseThread*> threadsManaged;
114 std::function<const char*(EnumType)> enumToString;
115
116 std::bitset<MaxCount> threadsInitializedTracker;
117 std::bitset<MaxCount> threadsStartedTracker;
118 std::bitset<MaxCount> threadsStoppedTracker;
119};
120
121
122template <typename EnumType, EnumType MaxCount>
123BaseThreadsManager<EnumType, MaxCount>::BaseThreadsManager(const std::map<EnumType, BaseThread*>& threads, std::function<const char*(EnumType)> enumToStringFunc) :
124 initialized(false),
126 threadsManaged(threads),
127 enumToString(enumToStringFunc),
131{
133}
134
135template <typename EnumType, EnumType MaxCount>
138
146template <typename EnumType, EnumType MaxCount>
148{
149 if (!initialized)
150 {
152 }
153 return initialized;
154}
155
156template <typename EnumType, EnumType MaxCount>
158{
159 if (EnsureInitialized() )
160 {
161 MutexGuard guard(mutex);
162
163
164 for(auto& threadMap : threadsManaged) {
165 threadMap.second->Resume();
166 }
167
168 return true;
169 }
170
171 return false;
172}
173template <typename EnumType, EnumType MaxCount>
174bool BaseThreadsManager<EnumType, MaxCount>::ResumeSelected(const std::vector<EnumType>& selectedEnums) noexcept
175{
176 bool resumed = false;
177 if (EnsureInitialized() )
178 {
179 MutexGuard guard(mutex);
180
181
182 for(const auto& enumValue : selectedEnums)
183 {
184 auto threadMap = threadsManaged.find(enumValue);
185 if(threadMap != threadsManaged.end())
186 {
187 resumed = threadMap->second->Resume();
188 }
189 }
190 }
191
192 return resumed;
193}
194
195template <typename EnumType, EnumType MaxCount>
197{
198 if (EnsureInitialized() )
199 {
200 MutexGuard guard(mutex);
201
202
203 for(auto& threadMap : threadsManaged) {
204 threadsStartedTracker[threadMap.first] = threadMap.second->Start();
205 }
206
207
208 return threadsStartedTracker.all();
209 }
210
211 return false;
212}
213
214
215template <typename EnumType, EnumType MaxCount>
216bool BaseThreadsManager<EnumType, MaxCount>::StartSelected(const std::vector<EnumType>& selectedEnums) noexcept
217{
218 if (EnsureInitialized() )
219 {
220 MutexGuard guard(mutex);
221
222
223 bool allSelectedStarted = true;
224 for(const auto& enumValue : selectedEnums) {
225 auto threadMap = threadsManaged.find(enumValue);
226 if(threadMap != threadsManaged.end()) {
227 bool started = threadMap->second->Start();
228 allSelectedStarted = allSelectedStarted && started;
229 threadsStartedTracker[threadMap->first] = started;
230 }
231 }
232
233
234 return allSelectedStarted;
235 }
236
237 return false;
238}
239
240template <typename EnumType, EnumType MaxCount>
241bool BaseThreadsManager<EnumType, MaxCount>::StartAllExceptSelected(const std::vector<EnumType>& selectedEnums) noexcept
242{
243 if (EnsureInitialized() )
244 {
245 MutexGuard guard(mutex);
246
247
248 bool allExceptSelectedStarted = true;
250 for(const auto& threadMap : threadsManaged) {
252 if(std::find(selectedEnums.begin(), selectedEnums.end(), threadMap.first) == selectedEnums.end()) {
254 bool started = threadMap.second->Start();
255 allExceptSelectedStarted = allExceptSelectedStarted && started;
256 threadsStartedTracker[threadMap.first] = started;
257 } else {
258 }
259 }
260
261
262 return allExceptSelectedStarted;
263 }
264
265 return false;
266}
267
268template <typename EnumType, EnumType MaxCount>
269bool BaseThreadsManager<EnumType, MaxCount>::StartAllAndWaitToVerify(uint32_t waitToVerifyTimeoutMsec) noexcept
270{
271 if (EnsureInitialized() )
272 {
273 MutexGuard guard(mutex);
274
275
276 for(auto& threadMap : threadsManaged) {
277 threadMap.second->Start();
278 }
279
280
282 std::function<bool()> CheckIfAllHalSubThreadsAreStarted = [this]() {
283 for(auto& threadMap : threadsManaged) {
284 threadsStartedTracker[threadMap.first] = threadMap.second->IsThreadRunning();
285 }
286 return threadsStartedTracker.all();
287 };
288
289 const uint32_t waitStartTimeMsec = os_get_elapsed_time_msec();
290
292 bool result = TestLogicWithTimeout(CheckIfAllHalSubThreadsAreStarted, true, waitToVerifyTimeoutMsec, timeBetweenChecksMsec);
293
294 const uint32_t elapsedStartTimeMsec = os_get_elapsed_time_msec() - waitStartTimeMsec;
295
297
298 if (result) {
299 }
300 else {
301 }
302
303 for(auto& threadMap : threadsManaged) {
304 }
305
306 return result;
307 }
308
309 return false;
310}
311
312template <typename EnumType, EnumType MaxCount>
313bool BaseThreadsManager<EnumType, MaxCount>::StartSelectedAndWaitToVerify(const std::vector<EnumType>& selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept
314{
315 if (EnsureInitialized() )
316 {
317 MutexGuard guard(mutex);
318
319
320
321 for(const auto& enumValue : selectedEnums) {
322 auto threadMap = threadsManaged.find(enumValue);
323 if(threadMap != threadsManaged.end()) {
324 threadMap->second->Start();
325 }
326 }
327
328
329
331 std::function<bool()> CheckIfAllSelectedThreadsAreStarted = [this, selectedEnums] {
333 for(const auto& enumValue : selectedEnums) {
334 threadsStartedTracker[enumValue] = threadsManaged[enumValue]->IsThreadRunning();
335 }
337 for(const auto& enumValue : selectedEnums) {
338 if(!threadsStartedTracker[enumValue]) {
339 return false;
340 }
341 }
342 return true;
343 };
344
345 const uint32_t waitStartTimeMsec = os_get_elapsed_time_msec();
346
348 bool result = TestLogicWithTimeout(CheckIfAllSelectedThreadsAreStarted, true, waitToVerifyTimeoutMsec, timeBetweenChecksMsec);
349
350 const uint32_t elapsedStartTimeMsec = os_get_elapsed_time_msec() - waitStartTimeMsec;
351
353
354 if (result) {
355 }
356 else {
357 }
358
359 for(const auto& enumValue : selectedEnums) {
360 }
361
362 return result;
363 }
364
365 return false;
366}
367
368template <typename EnumType, EnumType MaxCount>
369bool BaseThreadsManager<EnumType, MaxCount>::StartAllExceptSelectedAndWaitToVerify(const std::vector<EnumType>& selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept
370{
371 if (EnsureInitialized() )
372 {
373 MutexGuard guard(mutex);
374
375
376
378 for(const auto& threadMap : threadsManaged) {
380 if(std::find(selectedEnums.begin(), selectedEnums.end(), threadMap.first) == selectedEnums.end()) {
382 threadMap.second->Start();
383 }
384 }
385
386
388 std::function<bool()> CheckIfAllExceptSelectedThreadsAreStarted = [this, selectedEnums] {
390 for(const auto& threadMap : threadsManaged) {
391 if(std::find(selectedEnums.begin(), selectedEnums.end(), threadMap.first) == selectedEnums.end()) {
392 threadsStartedTracker[threadMap.first] = threadMap.second->IsThreadRunning();
393 }
394 }
396 for(const auto& threadMap : threadsManaged) {
397 if(std::find(selectedEnums.begin(), selectedEnums.end(), threadMap.first) == selectedEnums.end()) {
398 if(!threadsStartedTracker[threadMap.first]) {
399 return false;
400 }
401 }
402 }
403 return true;
404 };
405
406 const uint32_t waitStartTimeMsec = os_get_elapsed_time_msec();
407
409 bool result = TestLogicWithTimeout(CheckIfAllExceptSelectedThreadsAreStarted, true, waitToVerifyTimeoutMsec, timeBetweenChecksMsec);
410
411 const uint32_t elapsedStartTimeMsec = os_get_elapsed_time_msec() - waitStartTimeMsec;
412
414
415 if (result) {
416 }
417 else {
418 }
419
420 for(const auto& threadMap : threadsManaged) {
421 if(std::find(selectedEnums.begin(), selectedEnums.end(), threadMap.first) == selectedEnums.end()) {
422 }
423 }
424
425 return result;
426 }
427
428 return false;
429}
430
431template <typename EnumType, EnumType MaxCount>
433{
434 if (EnsureInitialized() )
435 {
436 MutexGuard guard(mutex);
437
438
439
440 for(auto& threadMap : threadsManaged) {
441 threadsStoppedTracker[threadMap.first] = threadMap.second->Stop();
442 }
443
444
445 return threadsStoppedTracker.all();
446 }
447
448 return false;
449}
450template <typename EnumType, EnumType MaxCount>
451bool BaseThreadsManager<EnumType, MaxCount>::StopSelected(const std::vector<EnumType>& selectedEnums) noexcept
452{
453 if (EnsureInitialized() )
454 {
455 MutexGuard guard(mutex);
456
457
458
459 bool allSelectedStopped = true;
460 for(const auto& enumValue : selectedEnums) {
461 auto threadMap = threadsManaged.find(enumValue);
462 if(threadMap != threadsManaged.end()) {
463 bool stopped = threadMap->second->Stop();
464 allSelectedStopped = allSelectedStopped && stopped;
465 threadsStoppedTracker[threadMap->first] = stopped;
466 }
467 }
468
469
470 return allSelectedStopped;
471 }
472
473 return false;
474}
475
476template <typename EnumType, EnumType MaxCount>
477bool BaseThreadsManager<EnumType, MaxCount>::StopAllExceptSelected(const std::vector<EnumType>& selectedEnums) noexcept
478{
479 if (EnsureInitialized() )
480 {
481 MutexGuard guard(mutex);
482
483
484
485 bool allExceptSelectedStopped = true;
486 for(const auto& threadMap : threadsManaged) {
487 if(std::find(selectedEnums.begin(), selectedEnums.end(), threadMap.first) == selectedEnums.end()) {
488 bool stopped = threadMap.second->Stop();
489 allExceptSelectedStopped = allExceptSelectedStopped && stopped;
490 threadsStoppedTracker[threadMap.first] = stopped;
491 } else {
492 }
493 }
494
495
496 return allExceptSelectedStopped;
497 }
498
499 return false;
500}
501template <typename EnumType, EnumType MaxCount>
502bool BaseThreadsManager<EnumType, MaxCount>::StopAllAndWaitToVerify(uint32_t waitToVerifyTimeoutMsec) noexcept
503{
504 if (EnsureInitialized() )
505 {
506 MutexGuard guard(mutex);
507
508
509 for(auto& threadMap : threadsManaged) {
510 threadsStoppedTracker[threadMap.first] = threadMap.second->Stop();
511 }
512
513
515 std::function<bool()> CheckIfAllHalSubThreadsAreStopped = [this]() {
516 for(auto& threadMap : threadsManaged) {
517 threadsStoppedTracker[threadMap.first] = threadMap.second->IsThreadStopped();
518 }
519 return threadsStoppedTracker.all();
520 };
521
523 const bool result = TestLogicWithTimeout(
524 CheckIfAllHalSubThreadsAreStopped, true, waitToVerifyTimeoutMsec, timeBetweenChecksMsec);
525 return result;
526 }
527
528 return false;
529}
530
531template <typename EnumType, EnumType MaxCount>
532bool BaseThreadsManager<EnumType, MaxCount>::StopSelectedAndWaitToVerify(const std::vector<EnumType>& selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept
533{
534 if (EnsureInitialized() )
535 {
536 MutexGuard guard(mutex);
537;
538
539
540 for(const auto& enumValue : selectedEnums) {
541 auto threadMap = threadsManaged.find(enumValue);
542 if(threadMap != threadsManaged.end()) {
543 threadsStoppedTracker[threadMap->first] = threadMap->second->Stop();
544 }
545 }
546
547
549 std::function<bool()> CheckIfAllSelectedThreadsAreStopped = [this, selectedEnums] {
550 for(const auto& enumValue : selectedEnums) {
551 threadsStoppedTracker[enumValue] = threadsManaged[enumValue]->IsThreadStopped();
552 }
553 for(const auto& enumValue : selectedEnums) {
554 if(!threadsStoppedTracker[enumValue]) {
555 return false;
556 }
557 }
558 return true;
559 };
560
562 const bool result = TestLogicWithTimeout(
563 CheckIfAllSelectedThreadsAreStopped, true, waitToVerifyTimeoutMsec, timeBetweenChecksMsec);
564 return result;
565 }
566
567 return false;
568}
569
570
571template <typename EnumType, EnumType MaxCount>
572bool BaseThreadsManager<EnumType, MaxCount>::StopAllExceptSelectedAndWaitToVerify(const std::vector<EnumType>& selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept
573{
574 if (EnsureInitialized() )
575 {
576 MutexGuard guard(mutex);
577
578
580 for(const auto& threadMap : threadsManaged) {
582 if(std::find(selectedEnums.begin(), selectedEnums.end(), threadMap.first) == selectedEnums.end()) {
584 threadMap.second->Stop();
585 } else {
586 }
587 }
588
589
591 std::function<bool()> CheckIfAllExceptSelectedThreadsAreStopped = [this, selectedEnums] {
593 for(const auto& threadMap : threadsManaged) {
594 if(std::find(selectedEnums.begin(), selectedEnums.end(), threadMap.first) == selectedEnums.end()) {
595 threadsStoppedTracker[threadMap.first] = threadMap.second->IsThreadStopped();
596 }
597 }
599 for(const auto& threadMap : threadsManaged) {
600 if(std::find(selectedEnums.begin(), selectedEnums.end(), threadMap.first) == selectedEnums.end()) {
601 if(!threadsStoppedTracker[threadMap.first]) {
602 return false;
603 }
604 }
605 }
606 return true;
607 };
608
609 const uint32_t waitStopTimeMsec = os_get_elapsed_time_msec();
610
612 bool result = TestLogicWithTimeout(CheckIfAllExceptSelectedThreadsAreStopped, true, waitToVerifyTimeoutMsec, timeBetweenChecksMsec);
613
614 const uint32_t elapsedStopTimeMsec = os_get_elapsed_time_msec() - waitStopTimeMsec;
615
617
618 if (result) {
619 }
620 else {
621 }
622
623 for(const auto& threadMap : threadsManaged) {
624 if(std::find(selectedEnums.begin(), selectedEnums.end(), threadMap.first) == selectedEnums.end()) {
625 }
626 }
627
628 return result;
629 }
630
631 return false;
632}
633
634template <typename EnumType, EnumType MaxCount>
638
639template <typename EnumType, EnumType MaxCount>
643
649template <typename EnumType, EnumType MaxCount>
651{
652 bool success = false;
653 MutexGuard guard(mutex, &success);
654
655 if( success )
656 {
658 if( !PreThreadInitializationActions() ) { return false; }
659
660 for(auto& threadMap : threadsManaged) {
661 bool threadInitialized = threadMap.second->EnsureInitialized();
662 threadsInitializedTracker[threadMap.first] = threadInitialized;
663
664 if(threadInitialized) {
665 }
666 else {
667 os_delay_msec( 5 );
668 }
669 }
670
672 if( !PostThreadInitializationActions() ) { return false; }
673
675 }
676 return success && threadsInitializedTracker.all();
677}
678
679
680
681template <typename EnumType, EnumType MaxCount>
682const char BaseThreadsManager<EnumType, MaxCount>::mutexName[] = "BaseThreadManager-Mutex";
683
684#endif /* HF_UTILS_RTOS_WRAP_BASETHREADSMANAGER_H_ */
Abstract base class for long running worker threads.
Named-mutex wrapper used by BaseThread infrastructure.
MutexGuard class definition.
Generic RTOS abstraction — public header.
C-facing helper functions for delays, cycle counters, and creation of RTOS handles (queues,...
uint32_t os_get_elapsed_time_msec()
Retrieves the elapsed time in milliseconds.
Definition OsUtility.cpp:65
void os_delay_msec(uint16_t msec)
Delays execution for the specified number of milliseconds.
Definition OsUtility.cpp:28
Miscellaneous utility helpers for the RTOS wrapper.
static bool TestLogicWithTimeout(Func func, T expected, uint32_t timeoutMsec, uint32_t checkIntervalMs)
Helper to repeatedly check a condition until timeout.
Definition Utility.h:26
Abstract class to assist in designing thread-based execution sequences.
Definition BaseThread.h:32
Definition BaseThreadsManager.h:39
bool StartSelected(const std::vector< EnumType > &selectedEnums) noexcept
Definition BaseThreadsManager.h:216
static constexpr bool timeBetweenChecksMsec
Definition BaseThreadsManager.h:106
bool StopAllAndWaitToVerify(uint32_t waitToVerifyTimeoutMsec) noexcept
Definition BaseThreadsManager.h:502
BaseThreadsManager(const BaseThreadsManager &)=delete
The Copy constructor is deleted to avoid copying instances.
bool StartAll() noexcept
Definition BaseThreadsManager.h:196
bool EnsureInitialized() noexcept
Ensures that the BaseThreadsManager is initialized.
Definition BaseThreadsManager.h:147
bool ResumeSelected(const std::vector< EnumType > &selectedEnums) noexcept
Definition BaseThreadsManager.h:174
virtual bool PreThreadInitializationActions() noexcept
Definition BaseThreadsManager.h:635
std::function< const char *(EnumType)> enumToString
Definition BaseThreadsManager.h:114
std::bitset< MaxCount > threadsStartedTracker
Definition BaseThreadsManager.h:117
bool StopSelectedAndWaitToVerify(const std::vector< EnumType > &selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept
Definition BaseThreadsManager.h:532
bool StopAll() noexcept
Definition BaseThreadsManager.h:432
bool StartSelectedAndWaitToVerify(const std::vector< EnumType > &selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept
Definition BaseThreadsManager.h:313
bool StopAllExceptSelectedAndWaitToVerify(const std::vector< EnumType > &selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept
Definition BaseThreadsManager.h:572
bool StartAllExceptSelectedAndWaitToVerify(const std::vector< EnumType > &selectedEnums, uint32_t waitToVerifyTimeoutMsec) noexcept
Definition BaseThreadsManager.h:369
virtual bool PostThreadInitializationActions() noexcept
Definition BaseThreadsManager.h:640
std::bitset< MaxCount > threadsStoppedTracker
Definition BaseThreadsManager.h:118
BaseThreadsManager & operator=(const BaseThreadsManager &)=delete
The assignment operator constructor is deleted to avoid copying instances.
bool StartAllExceptSelected(const std::vector< EnumType > &selectedEnums) noexcept
Definition BaseThreadsManager.h:241
std::bitset< MaxCount > threadsInitializedTracker
Definition BaseThreadsManager.h:116
Mutex mutex
Definition BaseThreadsManager.h:110
bool StopAllExceptSelected(const std::vector< EnumType > &selectedEnums) noexcept
Definition BaseThreadsManager.h:477
bool StopSelected(const std::vector< EnumType > &selectedEnums) noexcept
Definition BaseThreadsManager.h:451
bool initialized
Definition BaseThreadsManager.h:108
bool Initialize() noexcept
Initializes the BaseThreadsManager.
Definition BaseThreadsManager.h:650
static const char mutexName[]
Definition BaseThreadsManager.h:111
bool ResumeAll() noexcept
Definition BaseThreadsManager.h:157
bool StartAllAndWaitToVerify(uint32_t waitToVerifyTimeoutMsec) noexcept
Definition BaseThreadsManager.h:269
static constexpr bool verbose
Definition BaseThreadsManager.h:105
virtual ~BaseThreadsManager()
Definition BaseThreadsManager.h:136
std::map< EnumType, BaseThread * > threadsManaged
Definition BaseThreadsManager.h:113
Definition MutexGuard.h:29
Definition Mutex.h:29