SuperTinyKernel™ RTOS 1.05.3
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
test_eventflags.cpp
Go to the documentation of this file.
1/*
2 * SuperTinyKernel™ (STK): Lightweight High-Performance Deterministic C++ RTOS for Embedded Systems.
3 *
4 * Source: https://github.com/SuperTinyKernel-RTOS
5 *
6 * Copyright (c) 2022-2026 Neutron Code Limited <stk@neutroncode.com>. All Rights Reserved.
7 * License: MIT License, see LICENSE for a full text.
8 */
9
10#include <stk_config.h>
11#include <stk.h>
13#include <assert.h>
14#include <string.h>
15
16#include "stktest_context.h"
17
18using namespace stk;
19using namespace stk::test;
20
22
23#define _STK_EF_TEST_TASKS_MAX 5
24#define _STK_EF_TEST_TIMEOUT 300
25#define _STK_EF_TEST_SHORT_SLEEP 10
26#define _STK_EF_TEST_LONG_SLEEP 100
27#ifdef __ARM_ARCH_6M__
28#define _STK_EF_STACK_SIZE 128 // ARM Cortex-M0
29#define STK_TASK
30#else
31#define _STK_EF_STACK_SIZE 256
32#define STK_TASK static
33#endif
34
35#ifndef _NEW
36inline void *operator new(std::size_t, void *ptr) noexcept { return ptr; }
37inline void operator delete(void *, void *) noexcept { /* nothing for placement delete */ }
38#endif
39
40// Shared flag bit definitions used across all tests
41static const uint32_t FLAG_A = (1U << 0);
42static const uint32_t FLAG_B = (1U << 1);
43static const uint32_t FLAG_C = (1U << 2);
44static const uint32_t FLAG_D = (1U << 3);
45
46namespace stk {
47namespace test {
48
52namespace eventflags {
53
54// Test results storage
55static volatile int32_t g_TestResult = 0;
56static volatile int32_t g_SharedCounter = 0;
57static volatile bool g_TestComplete = false;
58
59// Kernel
61
62// Test object (re-constructed per test via ResetTestState)
64
65// ---------------------------------------------------------------------------
66
74template <EAccessMode _AccessMode>
75class SetWaitAnyTask : public Task<_STK_EF_STACK_SIZE, _AccessMode>
76{
77 uint8_t m_task_id;
78 int32_t m_iterations;
79
80public:
81 SetWaitAnyTask(uint8_t task_id, int32_t iterations) : m_task_id(task_id), m_iterations(iterations)
82 {}
83
84private:
85 void Run()
86 {
87 if (m_task_id == 0)
88 {
89 // Producer: alternate between two flags so consumers see different bits
90 stk::Sleep(_STK_EF_TEST_SHORT_SLEEP); // let consumers block first
91
92 for (int32_t i = 0; i < m_iterations; ++i)
93 {
94 uint32_t flag = (i % 2 == 0) ? FLAG_A : FLAG_B;
95 g_Flags.Set(flag);
96 stk::Delay(1); // pace so a consumer can unblock between signals
97 }
98
100
101 printf("set-wait-any: counter=%d (expected %d)\n",
102 (int)g_SharedCounter, (int)m_iterations);
103
105 g_TestResult = 1;
106 }
107 else
108 {
109 // Consumers: wait for any of the four flags, count each successful wake
110 for (int32_t i = 0; i < m_iterations; ++i)
111 {
112 uint32_t result = g_Flags.Wait(FLAG_A | FLAG_B | FLAG_C | FLAG_D,
115 if (!sync::EventFlags::IsError(result))
117 }
118 }
119 }
120};
121
122// ---------------------------------------------------------------------------
123
130template <EAccessMode _AccessMode>
131class SetWaitAllTask : public Task<_STK_EF_STACK_SIZE, _AccessMode>
132{
133 uint8_t m_task_id;
134
135public:
136 SetWaitAllTask(uint8_t task_id, int32_t) : m_task_id(task_id)
137 {}
138
139private:
140 void Run()
141 {
142 if (m_task_id == 0)
143 {
144 stk::Sleep(_STK_EF_TEST_SHORT_SLEEP); // let task 1 block first
145
146 // Set flags one at a time with gaps; consumer must hold until all three arrive
147 g_Flags.Set(FLAG_A);
149 g_Flags.Set(FLAG_B);
151 g_Flags.Set(FLAG_C); // this final Set() should unblock task 1
152
154
155 printf("set-wait-all: counter=%d (expected 1)\n", (int)g_SharedCounter);
156
157 if (g_SharedCounter == 1)
158 g_TestResult = 1;
159 }
160 else
161 if (m_task_id == 1)
162 {
163 // Must block until all three flags are simultaneously present
164 uint32_t result = g_Flags.Wait(FLAG_A | FLAG_B | FLAG_C,
167
168 // Return value must equal the full requested mask with no extra bits
169 if (!sync::EventFlags::IsError(result) && (result == (FLAG_A | FLAG_B | FLAG_C)))
171 }
172 }
173};
174
175// ---------------------------------------------------------------------------
176
182template <EAccessMode _AccessMode>
183class ClearTask : public Task<_STK_EF_STACK_SIZE, _AccessMode>
184{
185 uint8_t m_task_id;
186
187public:
188 ClearTask(uint8_t task_id, int32_t) : m_task_id(task_id)
189 {}
190
191private:
192 void Run()
193 {
194 if (m_task_id == 0)
195 {
196 // Set FLAG_A and FLAG_B, clear FLAG_A, verify only FLAG_B remains
197 g_Flags.Set(FLAG_A | FLAG_B);
198 uint32_t pre_clear = g_Flags.Clear(FLAG_A); // returns value before clear
199
200 // pre_clear must have had both bits; FLAG_A must now be absent
201 bool pre_ok = ((pre_clear & (FLAG_A | FLAG_B)) == (FLAG_A | FLAG_B));
202 bool post_ok = ((g_Flags.Get() & FLAG_A) == 0U);
203 bool flag_b_ok = ((g_Flags.Get() & FLAG_B) != 0U);
204
206
207 printf("clear: pre_ok=%d (expected 1), post_ok=%d (expected 1), "
208 "flag_b_ok=%d (expected 1), counter=%d (expected 1)\n",
209 (int)pre_ok, (int)post_ok, (int)flag_b_ok, (int)g_SharedCounter);
210
211 if (pre_ok && post_ok && flag_b_ok && (g_SharedCounter == 1))
212 g_TestResult = 1;
213 }
214 else
215 if (m_task_id == 1)
216 {
217 // Wait for FLAG_B: must succeed because Clear() only removed FLAG_A
219
220 if (!sync::EventFlags::IsError(result))
222 }
223 else
224 if (m_task_id == 2)
225 {
226 // Wait for FLAG_A after it was cleared: must time out
228
229 // A timeout is the expected outcome here; a non-error result is a failure
230 if (sync::EventFlags::IsError(result))
231 ; // expected — do not count
232 else
233 ++g_SharedCounter; // unexpected wake: failure
234 }
235 }
236};
237
238// ---------------------------------------------------------------------------
239
246template <EAccessMode _AccessMode>
247class NoClearTask : public Task<_STK_EF_STACK_SIZE, _AccessMode>
248{
249 uint8_t m_task_id;
250
251public:
252 NoClearTask(uint8_t task_id, int32_t) : m_task_id(task_id)
253 {}
254
255private:
256 void Run()
257 {
258 if (m_task_id == 0)
259 {
260 stk::Sleep(_STK_EF_TEST_SHORT_SLEEP); // let tasks 1 and 2 reach their Wait() calls
261
262 g_Flags.Set(FLAG_A);
263
265
266 printf("no-clear: counter=%d (expected 2)\n", (int)g_SharedCounter);
267
268 if (g_SharedCounter == 2)
269 g_TestResult = 1;
270 }
271 else
272 if (m_task_id == 1)
273 {
274 // Wait with NO_CLEAR; flags must remain set after return
275 uint32_t result = g_Flags.Wait(FLAG_A,
278
279 if (!sync::EventFlags::IsError(result))
281 }
282 else
283 if (m_task_id == 2)
284 {
285 // Stagger slightly so task 1 wins first; then verify flags still present
286 stk::Sleep(1);
287
288 uint32_t result = g_Flags.Wait(FLAG_A,
291
292 if (!sync::EventFlags::IsError(result))
294 }
295 }
296};
297
298// ---------------------------------------------------------------------------
299
306template <EAccessMode _AccessMode>
307class TimeoutTask : public Task<_STK_EF_STACK_SIZE, _AccessMode>
308{
309 uint8_t m_task_id;
310
311public:
312 TimeoutTask(uint8_t task_id, int32_t) : m_task_id(task_id)
313 {}
314
315private:
316 void Run()
317 {
318 if (m_task_id == 0)
319 {
320 // Set FLAG_A well past the timeout window used by task 1
321 stk::Sleep(200);
322 g_Flags.Set(FLAG_A);
323 }
324 else
325 if (m_task_id == 1)
326 {
328
329 // Wait with a 50-tick timeout; must expire before task 0 fires Set()
330 int64_t start = GetTimeNowMs();
331 uint32_t result = g_Flags.Wait(FLAG_A, sync::EventFlags::OPT_WAIT_ANY, 50);
332 int64_t elapsed = GetTimeNowMs() - start;
333
334 if ((result == sync::EventFlags::ERROR_TIMEOUT) && (elapsed >= 45) && (elapsed <= 60))
336 }
337 else
338 if (m_task_id == 2)
339 {
340 // Wait with generous timeout after task 0 fires Set(); must succeed
341 stk::Sleep(210);
342
343 uint32_t result = g_Flags.Wait(FLAG_A, sync::EventFlags::OPT_WAIT_ANY, 100);
344
345 if (!sync::EventFlags::IsError(result))
347 }
348
349 if (m_task_id == 2)
350 {
352
353 printf("timeout: counter=%d (expected 2)\n", (int)g_SharedCounter);
354
355 if (g_SharedCounter == 2)
356 g_TestResult = 1;
357 }
358 }
359};
360
361// ---------------------------------------------------------------------------
362
369template <EAccessMode _AccessMode>
370class TryWaitTask : public Task<_STK_EF_STACK_SIZE, _AccessMode>
371{
372 uint8_t m_task_id;
373
374public:
375 TryWaitTask(uint8_t task_id, int32_t) : m_task_id(task_id)
376 {}
377
378private:
379 void Run()
380 {
381 if (m_task_id == 1)
382 {
383 // TryWait on a non-set flag must return immediately with an error
384 int64_t start = GetTimeNowMs();
385 uint32_t result = g_Flags.TryWait(FLAG_A);
386 int64_t elapsed = GetTimeNowMs() - start;
387
388 if (sync::EventFlags::IsError(result) && (elapsed < _STK_EF_TEST_SHORT_SLEEP))
390 }
391 else
392 if (m_task_id == 2)
393 {
394 // Set FLAG_A then TryWait; must succeed and auto-clear
395 g_Flags.Set(FLAG_A);
396
397 int64_t start = GetTimeNowMs();
398 uint32_t result = g_Flags.TryWait(FLAG_A);
399 int64_t elapsed = GetTimeNowMs() - start;
400
401 if (!sync::EventFlags::IsError(result) && (elapsed < _STK_EF_TEST_SHORT_SLEEP))
403
404 // Verify auto-clear: second TryWait must return an error
407 }
408
409 if (m_task_id == 0)
410 {
412
413 printf("try-wait: counter=%d (expected 3)\n", (int)g_SharedCounter);
414
415 if (g_SharedCounter == 3)
416 g_TestResult = 1;
417 }
418 }
419};
420
421// ---------------------------------------------------------------------------
422
428template <EAccessMode _AccessMode>
429class GetTask : public Task<_STK_EF_STACK_SIZE, _AccessMode>
430{
431 uint8_t m_task_id;
432
433public:
434 GetTask(uint8_t task_id, int32_t) : m_task_id(task_id)
435 {}
436
437private:
438 void Run()
439 {
440 if (m_task_id == 0)
441 {
442 // Get() on empty flags word must be zero
443 bool empty_ok = (g_Flags.Get() == 0U);
444
445 g_Flags.Set(FLAG_A | FLAG_C);
446
447 // Get() must reflect the two set bits
448 bool set_ok = ((g_Flags.Get() & (FLAG_A | FLAG_C)) == (FLAG_A | FLAG_C));
449
450 g_Flags.Clear(FLAG_C);
451
452 // Get() must now show only FLAG_A
453 bool clear_ok = ((g_Flags.Get() == FLAG_A));
454
456
457 printf("get: empty_ok=%d (expected 1), set_ok=%d (expected 1), "
458 "clear_ok=%d (expected 1), counter=%d (expected 1)\n",
459 (int)empty_ok, (int)set_ok, (int)clear_ok, (int)g_SharedCounter);
460
461 if (empty_ok && set_ok && clear_ok && (g_SharedCounter == 1))
462 g_TestResult = 1;
463 }
464 else
465 if (m_task_id == 1)
466 {
467 stk::Sleep(_STK_EF_TEST_SHORT_SLEEP); // let task 0 set flags first
468
469 // Get() must not consume the flag; a subsequent Wait() must still succeed
470 uint32_t snapshot = g_Flags.Get();
472
473 if (((snapshot & FLAG_A) != 0U) && !sync::EventFlags::IsError(result))
475 }
476 }
477};
478
479// ---------------------------------------------------------------------------
480
487template <EAccessMode _AccessMode>
488class MultiWaiterAnyTask : public Task<_STK_EF_STACK_SIZE, _AccessMode>
489{
490 uint8_t m_task_id;
491
492public:
493 MultiWaiterAnyTask(uint8_t task_id, int32_t) : m_task_id(task_id)
494 {}
495
496private:
497 void Run()
498 {
499 if (m_task_id == 0)
500 {
501 // Let all four consumers block, then release all at once
503
504 g_Flags.Set(FLAG_A | FLAG_B | FLAG_C | FLAG_D); // wakes all four consumers
505
507
508 printf("multi-waiter-any: counter=%d (expected %d)\n",
509 (int)g_SharedCounter, (int)(_STK_EF_TEST_TASKS_MAX - 1));
510
512 g_TestResult = 1;
513 }
514 else
515 {
516 // Each consumer watches a unique flag bit
517 static const uint32_t k_flags[4] = { FLAG_A, FLAG_B, FLAG_C, FLAG_D };
518 uint32_t my_flag = k_flags[m_task_id - 1];
519
520 uint32_t result = g_Flags.Wait(my_flag, sync::EventFlags::OPT_WAIT_ANY, _STK_EF_TEST_TIMEOUT);
521
522 // Return value must contain the consumer's own flag
523 if (!sync::EventFlags::IsError(result) && ((result & my_flag) != 0U))
525 }
526 }
527};
528
529// ---------------------------------------------------------------------------
530
538template <EAccessMode _AccessMode>
539class MultiWaiterAllTask : public Task<_STK_EF_STACK_SIZE, _AccessMode>
540{
541 uint8_t m_task_id;
542 int32_t m_consumers;
543
544public:
545 MultiWaiterAllTask(uint8_t task_id, int32_t consumers) : m_task_id(task_id), m_consumers(consumers)
546 {}
547
548private:
549 void Run()
550 {
551 if (m_task_id == 0)
552 {
553 stk::Sleep(_STK_EF_TEST_SHORT_SLEEP); // let consumers block
554
555 // Re-set flags for each consumer in turn (they clear on wakeup)
556 for (int32_t i = 0; i < m_consumers; ++i)
557 {
558 g_Flags.Set(FLAG_A | FLAG_B);
559 stk::Delay(1);
560 }
561
563
564 printf("multi-waiter-all: counter=%d (expected %d)\n",
565 (int)g_SharedCounter, (int)m_consumers);
566
568 g_TestResult = 1;
569 }
570 else
571 {
572 // Each consumer waits for both FLAG_A and FLAG_B together
573 uint32_t result = g_Flags.Wait(FLAG_A | FLAG_B,
576
577 if (!sync::EventFlags::IsError(result) && (result == (FLAG_A | FLAG_B)))
579 }
580 }
581};
582
583// ---------------------------------------------------------------------------
584
591template <EAccessMode _AccessMode>
592class InitialFlagsTask : public Task<_STK_EF_STACK_SIZE, _AccessMode>
593{
594 uint8_t m_task_id;
595
596public:
597 InitialFlagsTask(uint8_t task_id, int32_t) : m_task_id(task_id)
598 {}
599
600private:
601 void Run()
602 {
603 if (m_task_id == 1)
604 {
605 // First Wait() must succeed immediately (initial_flags had FLAG_A set)
607
608 if (!sync::EventFlags::IsError(first))
610
611 // Second Wait() must time out: FLAG_A was consumed by the first Wait()
613
616 }
617
618 if (m_task_id == 0)
619 {
621
622 printf("initial-flags: counter=%d (expected 2)\n", (int)g_SharedCounter);
623
624 if (g_SharedCounter == 2)
625 g_TestResult = 1;
626 }
627 }
628};
629
630// ---------------------------------------------------------------------------
631// Helper: reset test state and re-construct the EventFlags object in-place
632// ---------------------------------------------------------------------------
633
634static void ResetTestState(uint32_t initial_flags = 0U)
635{
636 g_TestResult = 0;
637 g_SharedCounter = 0;
638 g_TestComplete = false;
639
640 // Re-construct the EventFlags object in-place with the requested initial value
641 g_Flags.~EventFlags();
642 new (&g_Flags) sync::EventFlags(initial_flags);
643}
644
645} // namespace eventflags
646} // namespace test
647} // namespace stk
648
649// ---------------------------------------------------------------------------
650// RunTest helper
651// ---------------------------------------------------------------------------
652
653static bool NeedsExtendedTasks(const char *test_name)
654{
655 return (strcmp(test_name, "SetWaitAll") != 0) &&
656 (strcmp(test_name, "Clear") != 0) &&
657 (strcmp(test_name, "NoClear") != 0) &&
658 (strcmp(test_name, "Timeout") != 0) &&
659 (strcmp(test_name, "TryWait") != 0) &&
660 (strcmp(test_name, "Get") != 0) &&
661 (strcmp(test_name, "InitialFlags") != 0);
662}
663
667template <class TaskType>
668static int32_t RunTest(const char *test_name, int32_t param = 0, uint32_t initial_flags = 0U)
669{
670 using namespace stk;
671 using namespace stk::test;
672 using namespace stk::test::eventflags;
673
674 printf("Test: %s\n", test_name);
675
676 ResetTestState(initial_flags);
677
678 STK_TASK TaskType task0(0, param);
679 STK_TASK TaskType task1(1, param);
680 STK_TASK TaskType task2(2, param);
681 TaskType task3(3, param);
682 TaskType task4(4, param);
683
684 g_Kernel.AddTask(&task0);
685 g_Kernel.AddTask(&task1);
686 g_Kernel.AddTask(&task2);
687
688 if (NeedsExtendedTasks(test_name))
689 {
690 g_Kernel.AddTask(&task3);
691 g_Kernel.AddTask(&task4);
692 }
693
694 g_Kernel.Start();
695
697
698 printf("Result: %s\n", result == TestContext::SUCCESS_EXIT_CODE ? "PASS" : "FAIL");
699 printf("--------------\n");
700
701 return result;
702}
703
704// ---------------------------------------------------------------------------
705// main
706// ---------------------------------------------------------------------------
707
711int main(int argc, char **argv)
712{
713 (void)argc;
714 (void)argv;
715
716 using namespace stk::test::eventflags;
717
719
720 int total_failures = 0, total_success = 0;
721
722 printf("--------------\n");
723
724 g_Kernel.Initialize();
725
726 // Test 1: WAIT_ANY — one Set() unblocks exactly one consumer per call
728 total_failures++;
729 else
730 total_success++;
731
732#ifndef __ARM_ARCH_6M__
733
734 // Test 2: WAIT_ALL — Wait() blocks until all requested bits are simultaneously set
736 total_failures++;
737 else
738 total_success++;
739
740 // Test 3: Clear() returns pre-clear value; cleared bits block subsequent waiters
742 total_failures++;
743 else
744 total_success++;
745
746 // Test 4: NO_CLEAR option — matched flags are not consumed; next Wait() still succeeds
748 total_failures++;
749 else
750 total_success++;
751
752 // Test 5: Wait() returns ERROR_TIMEOUT within the expected window when flags are never set
754 total_failures++;
755 else
756 total_success++;
757
758 // Test 6: TryWait() returns immediately; auto-clears on success; fails when flags absent
760 total_failures++;
761 else
762 total_success++;
763
764 // Test 7: Get() is non-destructive; reflects Set() and Clear() without consuming flags
766 total_failures++;
767 else
768 total_success++;
769
770 // Test 8: Multiple concurrent WAIT_ANY waiters, each with a unique flag bit
772 total_failures++;
773 else
774 total_success++;
775
776 // Test 9: Multiple concurrent WAIT_ALL waiters — all must eventually receive the full mask
778 total_failures++;
779 else
780 total_success++;
781
782 // Test 10: Constructor initial_flags — fast-path Wait() succeeds; cleared flag then times out
784 total_failures++;
785 else
786 total_success++;
787
788#endif // __ARM_ARCH_6M__
789
790 int32_t final_result = (total_failures == 0 ? TestContext::SUCCESS_EXIT_CODE : TestContext::DEFAULT_FAILURE_EXIT_CODE);
791
792 printf("##############\n");
793 printf("Total tests: %d\n", total_failures + total_success);
794 printf("Failures: %d\n", total_failures);
795
797 return final_result;
798}
Top-level STK include. Provides the Kernel class template and all built-in task-switching strategies.
Implementation of synchronization primitive: stk::sync::EventFlags.
static int32_t RunTest(const char *test_name, int32_t param=0)
#define STK_TASK
static const uint32_t FLAG_B
static const uint32_t FLAG_C
int main(int argc, char **argv)
#define _STK_EF_TEST_TIMEOUT
#define _STK_EF_TEST_LONG_SLEEP
#define _STK_EF_TEST_TASKS_MAX
static int32_t RunTest(const char *test_name, int32_t param=0, uint32_t initial_flags=0U)
static const uint32_t FLAG_A
#define _STK_EF_TEST_SHORT_SLEEP
static const uint32_t FLAG_D
static bool NeedsExtendedTasks(const char *test_name)
#define STK_TEST_DECL_ASSERT
Declare assertion redirector in the source file.
Namespace of STK package.
static int64_t GetTimeNowMs()
Get current time in milliseconds since kernel start.
Definition stk_helper.h:281
void Sleep(uint32_t ticks)
Put calling process into a sleep state.
Definition stk_helper.h:298
void Delay(uint32_t ticks)
Delay calling process by busy-waiting until the deadline expires.
Definition stk_helper.h:342
Namespace of the test inventory.
Namespace of EventFlags test.
static sync::EventFlags g_Flags
static volatile int32_t g_TestResult
static volatile bool g_TestComplete
static Kernel< KERNEL_DYNAMIC|KERNEL_SYNC, 5, SwitchStrategyRR, PlatformDefault > g_Kernel
static volatile int32_t g_SharedCounter
static void ResetTestState(uint32_t initial_flags=0U)
Concrete implementation of IKernel.
Definition stk.h:83
Task(const Task &)=delete
32-bit event flags group for multi-flag synchronization between tasks.
static const uint32_t ERROR_TIMEOUT
Return sentinel: wait timed out before the flags condition was met.
static bool IsError(uint32_t result)
Checks if a return value from Set(), Clear(), or Wait() is an error.
static const uint32_t OPT_NO_CLEAR
Do not clear matched flags after a successful wait.
static const uint32_t OPT_WAIT_ALL
Wait for ALL of the specified flags to be set simultaneously (AND semantics).
static const uint32_t OPT_WAIT_ANY
Wait for ANY of the specified flags to be set (OR semantics, default).
Tests WAIT_ANY (OR) semantics: a single flag unblocks a waiting task.
SetWaitAnyTask(uint8_t task_id, int32_t iterations)
void Run()
Entry point of the user task.
Tests WAIT_ALL (AND) semantics: all requested flags must be set before unblocking.
void Run()
Entry point of the user task.
SetWaitAllTask(uint8_t task_id, int32_t)
Tests Clear() return value and effect on subsequent Wait() calls.
ClearTask(uint8_t task_id, int32_t)
void Run()
Entry point of the user task.
Tests NO_CLEAR option: matched flags are not consumed after a successful Wait().
NoClearTask(uint8_t task_id, int32_t)
void Run()
Entry point of the user task.
Tests Wait() timeout when the required flags are never set.
void Run()
Entry point of the user task.
TimeoutTask(uint8_t task_id, int32_t)
Tests TryWait() non-blocking poll.
TryWaitTask(uint8_t task_id, int32_t)
void Run()
Entry point of the user task.
Tests Get() returns a non-destructive snapshot of the flags word.
GetTask(uint8_t task_id, int32_t)
void Run()
Entry point of the user task.
Tests WAIT_ANY with multiple concurrent waiters watching different flag subsets.
void Run()
Entry point of the user task.
Tests WAIT_ALL with multiple concurrent waiters, each requiring the full flag set.
void Run()
Entry point of the user task.
MultiWaiterAllTask(uint8_t task_id, int32_t consumers)
Tests EventFlags constructed with a non-zero initial flags word.
void Run()
Entry point of the user task.
static void ShowTestSuitePrologue()
Show text string as prologue before tests start.
@ DEFAULT_FAILURE_EXIT_CODE
default exit code for exit() to denote failure of the test
@ SUCCESS_EXIT_CODE
exit code for exit() to denote the success of the test
static void ShowTestSuiteEpilogue(int32_t result)
Show text string as epilogue after tests end.