29#ifndef ETL_MESSAGE_TIMER_ATOMIC_INCLUDED
30#define ETL_MESSAGE_TIMER_ATOMIC_INCLUDED
34#include "message_types.h"
36#include "message_router.h"
37#include "message_bus.h"
38#include "static_assert.h"
52 template <
typename TSemaphore>
53 class imessage_timer_atomic
68 bool is_space = (registered_timers < MAX_TIMERS);
78 timer_data& timer = timer_array[
i];
80 if (timer.id == etl::timer::id::NO_TIMER)
102 if (
id_ != etl::timer::id::NO_TIMER)
104 timer_data& timer = timer_array[
id_];
106 if (timer.id != etl::timer::id::NO_TIMER)
108 if (timer.is_active())
111 active_list.remove(timer.id,
true);
116 new (&timer) timer_data();
137 bool is_running()
const
151 for (
int i = 0;
i < MAX_TIMERS; ++
i)
153 new (&timer_array[
i]) timer_data();
156 registered_timers = 0
U;
169 if (process_semaphore == 0
U)
176 while (
has_active && (count >= active_list.front().delta))
178 timer_data& timer = active_list.front();
180 count -= timer.delta;
182 active_list.remove(timer.id,
true);
184 if (timer.p_router != ETL_NULLPTR)
186 timer.p_router->receive(timer.destination_router_id, *(timer.p_message));
191 timer.delta = timer.period;
192 active_list.insert(timer.id);
201 active_list.front().delta -= count;
220 if (
id_ != etl::timer::id::NO_TIMER)
222 timer_data& timer = timer_array[
id_];
225 if (timer.id != etl::timer::id::NO_TIMER)
228 if (timer.period != etl::timer::state::Inactive)
231 if (timer.is_active())
233 active_list.remove(timer.id,
false);
237 active_list.insert(timer.id);
256 if (
id_ != etl::timer::id::NO_TIMER)
258 timer_data& timer = timer_array[
id_];
261 if (timer.id != etl::timer::id::NO_TIMER)
263 if (timer.is_active())
266 active_list.remove(timer.id,
false);
308 bool has_active_timer()
const
311 bool result = !active_list.empty();
323 uint32_t delta =
static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
326 if (!active_list.empty())
328 delta = active_list.front().delta;
343 : p_message(ETL_NULLPTR)
344 , p_router(ETL_NULLPTR)
346 , delta(
etl::timer::state::Inactive)
347 , destination_router_id(
etl::imessage_bus::ALL_MESSAGE_ROUTERS)
348 , id(
etl::timer::id::NO_TIMER)
349 , previous(
etl::timer::id::NO_TIMER)
350 , next(
etl::timer::id::NO_TIMER)
362 : p_message(&message_)
363 , p_router(&irouter_)
365 , delta(
etl::timer::state::Inactive)
366 , destination_router_id(destination_router_id_)
368 , previous(
etl::timer::id::NO_TIMER)
369 , next(
etl::timer::id::NO_TIMER)
370 , repeating(repeating_)
377 bool is_active()
const
379 return delta != etl::timer::state::Inactive;
387 delta = etl::timer::state::Inactive;
396 uint_least8_t previous;
403 timer_data(
const timer_data& other);
404 timer_data& operator =(
const timer_data& other);
414 , process_semaphore(0
U)
415 , registered_timers(0
U)
437 timer_list(timer_data* ptimers_)
438 : head(
etl::timer::id::NO_TIMER)
439 , tail(
etl::timer::id::NO_TIMER)
440 , current(
etl::timer::id::NO_TIMER)
448 return head == etl::timer::id::NO_TIMER;
456 timer_data& timer = ptimers[id_];
458 if (head == etl::timer::id::NO_TIMER)
463 timer.previous = etl::timer::id::NO_TIMER;
464 timer.next = etl::timer::id::NO_TIMER;
471 while (test_id != etl::timer::id::NO_TIMER)
473 timer_data& test = ptimers[test_id];
476 if (timer.delta <= test.delta)
484 timer.previous = test.previous;
485 test.previous = timer.id;
486 timer.next = test.id;
489 test.delta -= timer.delta;
491 if (timer.previous != etl::timer::id::NO_TIMER)
493 ptimers[timer.previous].next = timer.id;
499 timer.delta -= test.delta;
502 test_id = next(test_id);
506 if (test_id == etl::timer::id::NO_TIMER)
509 ptimers[tail].next = timer.id;
510 timer.previous = tail;
511 timer.next = etl::timer::id::NO_TIMER;
520 timer_data& timer = ptimers[id_];
528 ptimers[timer.previous].next = timer.next;
533 tail = timer.previous;
537 ptimers[timer.next].previous = timer.previous;
543 if (timer.next != etl::timer::id::NO_TIMER)
545 ptimers[timer.next].delta += timer.delta;
549 timer.previous = etl::timer::id::NO_TIMER;
550 timer.next = etl::timer::id::NO_TIMER;
551 timer.delta = etl::timer::state::Inactive;
557 return ptimers[head];
561 const timer_data& front()
const
563 return ptimers[head];
576 current = ptimers[last].previous;
583 current = ptimers[last].next;
592 while (
id != etl::timer::id::NO_TIMER)
594 timer_data& timer = ptimers[id];
596 timer.next = etl::timer::id::NO_TIMER;
599 head = etl::timer::id::NO_TIMER;
600 tail = etl::timer::id::NO_TIMER;
601 current = etl::timer::id::NO_TIMER;
610 timer_data*
const ptimers;
614 timer_data*
const timer_array;
617 timer_list active_list;
631 template <u
int_least8_t MAX_TIMERS_,
typename TSemaphore>
636 ETL_STATIC_ASSERT(
MAX_TIMERS_ <= 254,
"No more than 254 timers are allowed");
This is the base of all message routers.
Definition message_router_generator.h:123
ETL_CONSTEXPR14 TIterator remove(TIterator first, TIterator last, const T &value)
Definition algorithm.h:2180
bitset_ext
Definition absolute.h:38
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:962
pair holds two objects of arbitrary type
Definition utility.h:164
ETL_CONSTEXPR pair()
Default constructor.
Definition utility.h:176