From 2aa0c4edb3bbdfa9f28de6e42f8e208fa7389f0f Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 26 Oct 2026 15:50:35 +0000 Subject: [PATCH] Fixed remove for timer_active_list Moved time to nex notifications to inside the lock regions Finished unit tests --- include/etl/intrusive_timer.h | 124 ++-- include/etl/private/timer_lists.h | 10 +- include/etl/timer.h | 17 +- include/etl/timer_node.h | 64 +- test/test_intrusive_timer.cpp | 957 +++++++++++++++--------------- test/test_timer_lists.cpp | 26 +- test/test_timer_node.cpp | 16 +- 7 files changed, 605 insertions(+), 609 deletions(-) diff --git a/include/etl/intrusive_timer.h b/include/etl/intrusive_timer.h index 4b0284e5..5bd26aa8 100644 --- a/include/etl/intrusive_timer.h +++ b/include/etl/intrusive_timer.h @@ -131,17 +131,10 @@ namespace etl result = true; } - // Get the next timer that is due to expire. - etl::timer_node* next_timer = active_list.first(); + notify_about_timer_change(notify, active_list.first()); lock_policy.unlock(); - if (notify) - { - // The next timer has changed, so notify the user. - time_to_next_notification.call_if(next_timer->get_delta()); - } - return result; } @@ -214,7 +207,7 @@ namespace etl if (timer->get_mode() == etl::timer::mode::Repeating) { // Reinsert the timer. - timer->delta = timer->get_period(); + timer->delta = timer->get_interval(); active_list.insert(timer); } @@ -224,7 +217,7 @@ namespace etl has_active = !active_list.empty(); - notify = has_active; + notify = true; } if (has_active) @@ -233,19 +226,12 @@ namespace etl active_list.first()->delta -= count; } } - } - // Get the next timer that is due to expire. - etl::timer_node* next_timer = active_list.first(); + notify_about_timer_change(notify, active_list.first()); - lock_policy.unlock(); + was_processed = true; - was_processed = true; - - if (notify) - { - // The next timer has changed, so notify the user. - time_to_next_notification.call_if(next_timer->get_delta()); + lock_policy.unlock(); } // Invoke all of the expired timers. @@ -266,8 +252,9 @@ namespace etl if (timer_.is_registered_with(this)) { - // Must not be active and must have a valid period. - if (!timer_.is_active() && (timer_.get_period() != etl::timer::interval::No_Active_Interval)) + // Must not be active, must have a valid interval, and must have a valid mode. + if (!timer_.is_active() && (timer_.get_interval() != etl::timer::interval::No_Active_Interval) + && (timer_.get_mode() != etl::timer::mode::No_Mode_Set)) { active_list.insert(timer_); is_started = true; @@ -285,11 +272,7 @@ namespace etl timer_.invoke(); } - if (notify) - { - // The next timer has changed, so notify the user. - time_to_next_notification.call_if(timer_.get_delta()); - } + notify_about_timer_change(notify, &timer_); return is_started; } @@ -300,34 +283,27 @@ namespace etl bool stop(etl::timer_node& timer_) ETL_NOEXCEPT { bool is_stopped = false; - bool notify = false; lock_policy.lock(); if (timer_.is_active()) { - notify = (active_list.first() == &timer_); stop_timer(timer_); is_stopped = true; } - // Get the next timer that is due to expire. - etl::timer_node* next_timer = active_list.first(); - - notify = true; + // The next timer has changed, so notify the user. + time_to_next_notification.call_if(active_list.first()->get_delta()); lock_policy.unlock(); - // The next timer has changed, so notify the user. - time_to_next_notification.call_if(next_timer->get_delta()); - return is_stopped; } //******************************************* - /// Sets a timer's period. + /// Sets a timer's interval. //******************************************* - bool set_period(etl::timer_node& timer_, uint32_t period_) ETL_NOEXCEPT + bool set_interval(etl::timer_node& timer_, uint32_t interval_) ETL_NOEXCEPT { bool result = false; @@ -343,21 +319,14 @@ namespace etl stop_timer(timer_); } - timer_.set_period(period_); + timer_.set_interval(interval_); result = true; } - // Get the next timer that is due to expire. - etl::timer_node* next_timer = active_list.first(); + notify_about_timer_change(notify, active_list.first()); lock_policy.unlock(); - if (notify) - { - // The next timer has changed, so notify the user. - time_to_next_notification.call_if(next_timer->get_delta()); - } - return result; } @@ -383,17 +352,40 @@ namespace etl result = true; } - // Get the next timer that is due to expire. - etl::timer_node* next_timer = active_list.first(); + notify_about_timer_change(notify, active_list.first()); lock_policy.unlock(); - if (notify) + return result; + } + + //******************************************* + /// Sets a timer's interval. + //******************************************* + bool set_config(etl::timer_node& timer_, const etl::timer_config& config_) ETL_NOEXCEPT + { + bool result = false; + + lock_policy.lock(); + + bool notify = false; + + if (timer_.is_registered_with(this)) { - // The next timer has changed, so notify the user. - time_to_next_notification.call_if(next_timer->get_delta()); + if (timer_.is_active()) + { + notify = (active_list.first() == &timer_); + stop_timer(timer_); + } + + timer_.set_config(config_); + result = true; } + notify_about_timer_change(notify, active_list.first()); + + lock_policy.unlock(); + return result; } @@ -475,8 +467,21 @@ namespace etl private: + //******************************************* + /// Notifies the user of the next timer that is due to expire. + //******************************************* + void notify_about_timer_change(bool notify_, etl::timer_node* timer_) ETL_NOEXCEPT + { + if (notify_ && time_to_next_notification.is_valid()) + { + // The next timer has changed, so notify the user. + time_to_next_notification(timer_->get_delta()); + } + } + //******************************************* /// Gets the next available timer id. + /// Searches the list of registered timers for the next available id. //******************************************* etl::timer::id::type get_next_id() ETL_NOEXCEPT { @@ -484,23 +489,12 @@ namespace etl etl::timer_node* timer = register_list.first(); - while (timer != register_list.end()) + while ((timer != register_list.end()) && (timer->get_id() == next_id)) { - if (timer->get_id() == next_id) - { - // Already in use, so increment next_id and continue checking. - ++next_id; - } - else if (timer->get_id() > next_id) - { - // Found a gap in the IDs, so return the next_id. - return next_id; - } - + ++next_id; timer = register_list.next(timer); } - // We never found a gap, so return the next available ID. return next_id; } diff --git a/include/etl/private/timer_lists.h b/include/etl/private/timer_lists.h index d1cf6651..9c7773ce 100644 --- a/include/etl/private/timer_lists.h +++ b/include/etl/private/timer_lists.h @@ -162,7 +162,7 @@ namespace etl // Clear the id and next pointer of the removed timer. current->set_id(etl::timer::id::No_Timer); - current->registered_next = end(); + current->registered_next = etl::timer_node::unlinked(); // We are no longer the owner of this timer_node. current->set_owner(ETL_NULLPTR); @@ -214,9 +214,9 @@ namespace etl while (head != end()) { - head = timer->registered_next; - timer->registered_next = etl::timer_node::unlinked(); - timer = head; + head = timer->registered_next; + timer->clear(); + timer = head; } tail = end(); @@ -377,7 +377,7 @@ namespace etl } // Clear the next pointer of the removed timer. - current->active_next = end(); + timer_->active_next = etl::timer_node::unlinked(); return next; } diff --git a/include/etl/timer.h b/include/etl/timer.h index 791a1ef1..1fd95bda 100644 --- a/include/etl/timer.h +++ b/include/etl/timer.h @@ -58,14 +58,15 @@ namespace etl { enum { - SINGLE_SHOT = false, - REPEATING = true, + SINGLE_SHOT = 0, // Deprecated + REPEATING = 1, // Deprecated - Single_Shot = false, - Repeating = true + Single_Shot = 0, + Repeating = 1, + No_Mode_Set = 2 }; - typedef bool type; + typedef uint_least8_t type; }; // Timer start status. @@ -115,6 +116,12 @@ namespace etl typedef uint32_t type; }; + + // Timer owner. + struct owner + { + static ETL_CONSTANT void* No_Owner = ETL_NULLPTR; + }; }; } // namespace etl diff --git a/include/etl/timer_node.h b/include/etl/timer_node.h index 30948913..c165eb27 100644 --- a/include/etl/timer_node.h +++ b/include/etl/timer_node.h @@ -77,19 +77,19 @@ namespace etl //******************************************* /// Constructor. //******************************************* - ETL_CONSTEXPR timer_config(uint32_t period_, etl::timer::mode::type repeating_) ETL_NOEXCEPT - : period(period_) + ETL_CONSTEXPR timer_config(uint32_t interval_, etl::timer::mode::type repeating_) ETL_NOEXCEPT + : interval(interval_) , mode(repeating_) , id(etl::timer::id::No_Timer) { } //******************************************* - /// Returns the period of the timer. + /// Returns the interval of the timer. //******************************************* - ETL_CONSTEXPR uint32_t get_period() const ETL_NOEXCEPT + ETL_CONSTEXPR uint32_t get_interval() const ETL_NOEXCEPT { - return period; + return interval; } //******************************************* @@ -113,16 +113,16 @@ namespace etl //******************************************* ETL_CONSTEXPR14 void clear() ETL_NOEXCEPT { - period = etl::timer::state::Inactive; - mode = etl::timer::mode::Repeating; - id = etl::timer::id::No_Timer; + interval = etl::timer::interval::No_Active_Interval; + mode = etl::timer::mode::No_Mode_Set; + id = etl::timer::id::No_Timer; } private: - uint32_t period; ///< The period of the timer. - etl::timer::mode::type mode; ///< Whether the timer is repeating or single-shot. - etl::timer::id::type id; ///< The id of the timer. + uint32_t interval; ///< The interval of the timer. + etl::timer::mode::type mode; ///< Whether the timer is repeating or single-shot. + etl::timer::id::type id; ///< The id of the timer. }; class sentinal_node; @@ -165,9 +165,9 @@ namespace etl : registered_next(unlinked()) , active_next(unlinked()) , expired_next(unlinked()) - , owner(ETL_NULLPTR) + , owner(etl::timer::owner::No_Owner) , config(config_) - , delta(config_.get_period()) + , delta(config_.get_interval()) { } @@ -178,9 +178,9 @@ namespace etl : registered_next(unlinked()) , active_next(unlinked()) , expired_next(unlinked()) - , owner(ETL_NULLPTR) + , owner(etl::timer::owner::No_Owner) , config(node_.config) - , delta(node_.config.get_period()) + , delta(node_.config.get_interval()) { } @@ -201,11 +201,11 @@ namespace etl } //******************************************* - /// Returns the period of the timer. + /// Returns the interval of the timer. //******************************************* - ETL_CONSTEXPR uint32_t get_period() const ETL_NOEXCEPT + ETL_CONSTEXPR uint32_t get_interval() const ETL_NOEXCEPT { - return config.get_period(); + return config.get_interval(); } //******************************************* @@ -242,11 +242,20 @@ namespace etl private: //******************************************* - /// Sets the period of the timer. + /// Returns the configuration of the timer. //******************************************* - void set_period(uint32_t period_) ETL_NOEXCEPT + void set_config(const timer_config& config_) ETL_NOEXCEPT { - config.period = period_; + set_interval(config_.get_interval()); + set_mode(config_.get_mode()); + } + + //******************************************* + /// Sets the interval of the timer. + //******************************************* + void set_interval(uint32_t interval_) ETL_NOEXCEPT + { + config.interval = interval_; } //******************************************* @@ -282,20 +291,20 @@ namespace etl } //******************************************* - /// Clear the next pointers. + /// Clear the node. //******************************************* void clear() ETL_NOEXCEPT { + config.clear(); registered_next = unlinked(); active_next = unlinked(); expired_next = unlinked(); - owner = ETL_NULLPTR; - delta = config.get_period(); + owner = etl::timer::owner::No_Owner; + delta = config.get_interval(); } //******************************************* - /// Returns true if the timer is registered to this owner. - /// A timer cannot be registered to more than one owner. + /// Returns true if the timer is registered to the specified owner. //******************************************* bool is_registered_with(void* owner_) const ETL_NOEXCEPT { @@ -303,8 +312,7 @@ namespace etl } //******************************************* - /// Returns true if the timer is registered to this owner. - /// A timer cannot be registered to more than one owner. + /// Returns true if the timer is registered to an owner. //******************************************* bool is_registered() const ETL_NOEXCEPT { diff --git a/test/test_intrusive_timer.cpp b/test/test_intrusive_timer.cpp index 51396f40..cb49774f 100644 --- a/test/test_intrusive_timer.cpp +++ b/test/test_intrusive_timer.cpp @@ -33,6 +33,7 @@ SOFTWARE. #include "etl/timer.h" #include "etl/timer_node.h" +#include #include #include #include @@ -48,39 +49,6 @@ namespace { uint64_t ticks = 0ULL; - class TimerInsertRemoveTest - { - public: - - uint32_t inserted; - uint32_t removed; - TimerInsertRemoveTest() - : inserted(0) - , removed(0) - { - } - - void insert_handler(etl::timer::id::type id_) - { - (void)id_; - inserted++; - } - - void remove_handler(etl::timer::id::type id_) - { - (void)id_; - removed++; - } - - void clear(void) - { - inserted = 0; - removed = 0; - } - }; - - TimerInsertRemoveTest timerInsertRemoveTest; - //*************************************************************************** /// A lock policy that counts the number of times it is locked and unlocked. /// The lock count should always be 0 or 1. @@ -291,7 +259,7 @@ namespace } //************************************************************************* - TEST(test_intrusive_timer_double_register_timers) + TEST(test_intrusive_timer_register_timers_more_than_once) { LockPolicy lock_policy; @@ -315,6 +283,72 @@ namespace CHECK_EQUAL(0U, timer_controller2.number_of_timers()); } + //************************************************************************* + TEST(test_intrusive_timer_register_timers_to_one_then_unregister_then_register_with_another) + { + LockPolicy lock_policy; + + etl::intrusive_timer timer_controller1(lock_policy); + etl::intrusive_timer timer_controller2(lock_policy); + + etl::timer_node node1(etl::timer_config(100, etl::timer::mode::Single_Shot)); + + bool success = false; + + // Register the timer with the first controller. + success = timer_controller1.register_timer(node1); + CHECK_TRUE(success); + + // Unregister the timer from the first controller. + success = timer_controller1.unregister_timer(node1); + CHECK_TRUE(success); + + // Register the same timer with the second controller. + success = timer_controller2.register_timer(node1); + CHECK_TRUE(success); + } + + //************************************************************************* + TEST(test_intrusive_timer_start_stop_timers) + { + LockPolicy lock_policy; + + etl::intrusive_timer timer_controller(lock_policy); + + etl::timer_node node1(etl::timer_config(100, etl::timer::mode::Single_Shot)); + + // Start without registering. + CHECK_FALSE(timer_controller.start(node1)); + CHECK_FALSE(timer_controller.has_active_timer()); + + // Stop without registering. + CHECK_FALSE(timer_controller.stop(node1)); + CHECK_FALSE(timer_controller.has_active_timer()); + + // Register node1. + CHECK_TRUE(timer_controller.register_timer(node1)); + + // Start. + CHECK_TRUE(timer_controller.start(node1)); + CHECK_TRUE(timer_controller.has_active_timer()); + + // Stop. + CHECK_TRUE(timer_controller.stop(node1)); + CHECK_FALSE(timer_controller.has_active_timer()); + + // Start twice. + CHECK_TRUE(timer_controller.start(node1)); + CHECK_TRUE(timer_controller.has_active_timer()); + CHECK_FALSE(timer_controller.start(node1)); + CHECK_TRUE(timer_controller.has_active_timer()); + + // Stop twice. + CHECK_TRUE(timer_controller.stop(node1)); + CHECK_FALSE(timer_controller.has_active_timer()); + CHECK_FALSE(timer_controller.stop(node1)); + CHECK_FALSE(timer_controller.has_active_timer()); + } + //************************************************************************* TEST(test_intrusive_timer_find_timers) { @@ -371,7 +405,7 @@ namespace } //************************************************************************* - TEST(test_intrusive_timer_register_timers_then_modify_them) + TEST(test_intrusive_timer_register_timers_then_modify_them_individually) { LockPolicy lock_policy; @@ -385,19 +419,19 @@ namespace timer_controller.register_timer(node2); timer_controller.register_timer(node3); - // Modify the timer periods. - timer_controller.set_period(node1, 150U); - timer_controller.set_period(node2, 250U); - timer_controller.set_period(node3, 350U); + // Modify the timer intervals. + timer_controller.set_interval(node1, 150U); + timer_controller.set_interval(node2, 250U); + timer_controller.set_interval(node3, 350U); // Modify the timer modes. timer_controller.set_mode(node1, etl::timer::mode::Repeating); timer_controller.set_mode(node2, etl::timer::mode::Single_Shot); timer_controller.set_mode(node3, etl::timer::mode::Single_Shot); - CHECK_EQUAL(150U, node1.get_period()); - CHECK_EQUAL(250U, node2.get_period()); - CHECK_EQUAL(350U, node3.get_period()); + CHECK_EQUAL(150U, node1.get_interval()); + CHECK_EQUAL(250U, node2.get_interval()); + CHECK_EQUAL(350U, node3.get_interval()); CHECK_EQUAL(etl::timer::mode::Repeating, node1.get_mode()); CHECK_EQUAL(etl::timer::mode::Single_Shot, node2.get_mode()); @@ -407,7 +441,42 @@ namespace } //************************************************************************* - TEST(test_intrusive_timer_one_shot) + TEST(test_intrusive_timer_register_timers_then_modify_them_with_config) + { + LockPolicy lock_policy; + + etl::intrusive_timer timer_controller(lock_policy); + + etl::timer_node node1(etl::timer_config(100, etl::timer::mode::Single_Shot)); + etl::timer_node node2(etl::timer_config(200, etl::timer::mode::Repeating)); + etl::timer_node node3(etl::timer_config(300, etl::timer::mode::Repeating)); + + timer_controller.register_timer(node1); + timer_controller.register_timer(node2); + timer_controller.register_timer(node3); + + // Modify the timer configs. + etl::timer_config config1(150, etl::timer::mode::Repeating); + etl::timer_config config2(250, etl::timer::mode::Single_Shot); + etl::timer_config config3(350, etl::timer::mode::Single_Shot); + + timer_controller.set_config(node1, config1); + timer_controller.set_config(node2, config2); + timer_controller.set_config(node3, config3); + + CHECK_EQUAL(150U, node1.get_interval()); + CHECK_EQUAL(250U, node2.get_interval()); + CHECK_EQUAL(350U, node3.get_interval()); + + CHECK_EQUAL(etl::timer::mode::Repeating, node1.get_mode()); + CHECK_EQUAL(etl::timer::mode::Single_Shot, node2.get_mode()); + CHECK_EQUAL(etl::timer::mode::Single_Shot, node3.get_mode()); + + CHECK_EQUAL(0U, lock_policy.get_count()); + } + + //************************************************************************* + TEST(test_intrusive_timer_single_shot) { LockPolicy lock_policy; @@ -462,8 +531,10 @@ namespace CHECK_EQUAL(1, message_processor.message_call_count); // Check the notifications. - CHECK_EQUAL(12, time_to_next[0]); // 23, the next after 11 expired. - CHECK_EQUAL(14, time_to_next[1]); // 37, the next after 23 expired. + CHECK_EQUAL(3, time_to_next.size()); + CHECK_EQUAL(12, time_to_next[0]); // 23, the next after 11 expired. + CHECK_EQUAL(14, time_to_next[1]); // 37, the next after 23 expired. + CHECK_EQUAL(etl::timer::interval::No_Active_Interval, time_to_next[2]); // No more timers due. time_to_next.clear(); } @@ -500,6 +571,7 @@ namespace timer_controller.start(callback_timer2); // 23, the third timer started is now second due to expire.37 is third. // Check the notifications. + CHECK_EQUAL(2, time_to_next.size()); CHECK_EQUAL(37, time_to_next[0]); // 37, the first timer started is the first due to expire. CHECK_EQUAL(11, time_to_next[1]); // 11, the second timer started is now first due to expire. @@ -528,6 +600,7 @@ namespace CHECK_EQUAL(9, message_processor.message_call_count); // Check the notifications. + CHECK_EQUAL(15, time_to_next.size()); CHECK_EQUAL(11, time_to_next[0]); CHECK_EQUAL(1, time_to_next[1]); CHECK_EQUAL(10, time_to_next[2]); @@ -579,6 +652,7 @@ namespace timer_controller.start(callback_timer2); // 23, the third timer started is now second due to expire.37 is third. // Check the notifications. + CHECK_EQUAL(2, time_to_next.size()); CHECK_EQUAL(37, time_to_next[0]); // 37, the first timer started is the first due to expire. CHECK_EQUAL(11, time_to_next[1]); // 11, the second timer started is now first due to expire. @@ -607,6 +681,7 @@ namespace CHECK_EQUAL(9, message_processor.message_call_count); // Check the notifications. + CHECK_EQUAL(14, time_to_next.size()); CHECK_EQUAL(10, time_to_next[0]); CHECK_EQUAL(9, time_to_next[1]); CHECK_EQUAL(4, time_to_next[2]); @@ -685,6 +760,7 @@ namespace CHECK_EQUAL(9, message_processor.message_call_count); // Check the notifications. + CHECK_EQUAL(12, time_to_next.size()); CHECK_EQUAL(11, time_to_next[0]); // Start to timer3 CHECK_EQUAL(11, time_to_next[1]); // to timer3 CHECK_EQUAL(1, time_to_next[2]); // to timer2 @@ -701,445 +777,356 @@ namespace time_to_next.clear(); } - // //************************************************************************* - // TEST(test_intrusive_timer_repeating_clear) - // { - // etl::intrusive_timer<3> timer_controller; - // - // etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::Repeating); - // etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Repeating); - // etl::timer::id::type id3 = timer_controller.register_timer(free_callback2, 11, etl::timer::mode::Repeating); - // - // object.tick_list.clear(); - // free_tick_list1.clear(); - // free_tick_list2.clear(); - // - // timer_controller.start(id1); - // timer_controller.start(id3); - // timer_controller.start(id2); - // - // timer_controller.enable(true); - // - // ticks = 0; - // - // const uint32_t step = 1U; - // - // while (ticks <= 100U) - // { - // ticks += step; - // - // if (ticks == 40) - // { - // timer_controller.clear(); - // } - // - // timer_controller.tick(step); - // } - // - // std::vector compare1 = {37}; - // std::vector compare2 = {23}; - // std::vector compare3 = {11, 22, 33}; - // - // CHECK(object.tick_list.size() != 0); - // CHECK(free_tick_list1.size() != 0); - // CHECK(free_tick_list2.size() != 0); - // - // CHECK_ARRAY_EQUAL(compare1.data(), object.tick_list.data(), compare1.size()); - // CHECK_ARRAY_EQUAL(compare2.data(), free_tick_list1.data(), compare2.size()); - // CHECK_ARRAY_EQUAL(compare3.data(), free_tick_list2.data(), compare3.size()); - // } - // - // //************************************************************************* - // TEST(test_intrusive_timer_delayed_immediate) - // { - // etl::intrusive_timer<3> timer_controller; - // - // etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::Repeating); - // etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Repeating); - // etl::timer::id::type id3 = timer_controller.register_timer(free_callback2, 11, etl::timer::mode::Repeating); - // - // object.tick_list.clear(); - // free_tick_list1.clear(); - // free_tick_list2.clear(); - // - // timer_controller.enable(true); - // - // ticks = 5; - // timer_controller.tick(uint32_t(ticks)); - // - // timer_controller.start(id1, etl::timer::start::Immediate); - // timer_controller.start(id2, etl::timer::start::Immediate); - // timer_controller.start(id3, etl::timer::start::Delayed); - // - // const uint32_t step = 1U; - // - // while (ticks <= 100U) - // { - // ticks += step; - // timer_controller.tick(step); - // } - // - // std::vector compare1 = {6, 42, 79}; - // std::vector compare2 = {6, 28, 51, 74, 97}; - // std::vector compare3 = {16, 27, 38, 49, 60, 71, 82, 93}; - // - // CHECK(object.tick_list.size() != 0); - // CHECK(free_tick_list1.size() != 0); - // CHECK(free_tick_list2.size() != 0); - // - // CHECK_ARRAY_EQUAL(compare1.data(), object.tick_list.data(), compare1.size()); - // CHECK_ARRAY_EQUAL(compare2.data(), free_tick_list1.data(), compare2.size()); - // CHECK_ARRAY_EQUAL(compare3.data(), free_tick_list2.data(), compare3.size()); - // } - // - // //************************************************************************* - // TEST(test_intrusive_timer_one_shot_big_step_short_delay_insert) - // { - // etl::intrusive_timer<3> timer_controller; - // - // etl::timer::id::type id1 = timer_controller.register_timer(free_callback1, 15, etl::timer::mode::Single_Shot); - // etl::timer::id::type id2 = timer_controller.register_timer(free_callback2, 5, etl::timer::mode::Repeating); - // - // free_tick_list1.clear(); - // free_tick_list2.clear(); - // - // timer_controller.start(id1); - // timer_controller.start(id2); - // - // timer_controller.enable(true); - // - // ticks = 0; - // - // const uint32_t step = 11U; - // - // ticks += step; - // timer_controller.tick(step); - // - // ticks += step; - // timer_controller.tick(step); - // - // std::vector compare1 = {22}; - // std::vector compare2 = {11, 11, 22, 22}; - // - // CHECK(free_tick_list1.size() != 0); - // CHECK(free_tick_list2.size() != 0); - // - // CHECK_ARRAY_EQUAL(compare1.data(), free_tick_list1.data(), compare1.size()); - // CHECK_ARRAY_EQUAL(compare2.data(), free_tick_list2.data(), compare2.size()); - // } - // - // //************************************************************************* - // TEST(test_intrusive_timer_one_shot_empty_list_huge_tick_before_insert) - // { - // etl::intrusive_timer<3> timer_controller; - // - // etl::timer::id::type id1 = timer_controller.register_timer(free_callback1, 5, etl::timer::mode::Single_Shot); - // - // free_tick_list1.clear(); - // - // timer_controller.start(id1); - // - // timer_controller.enable(true); - // - // ticks = 0; - // - // const uint32_t step = 5U; - // - // for (uint32_t i = 0U; i < step; ++i) - // { - // ++ticks; - // timer_controller.tick(1); - // } - // - // // Huge tick count. - // timer_controller.tick(UINT32_MAX - step + 1); - // - // timer_controller.start(id1); - // - // for (uint32_t i = 0U; i < step; ++i) - // { - // ++ticks; - // timer_controller.tick(1); - // } - // std::vector compare1 = {5, 10}; - // - // CHECK(free_tick_list1.size() != 0); - // - // CHECK_ARRAY_EQUAL(compare1.data(), free_tick_list1.data(), compare1.size()); - // } - // - // //************************************************************************* - // TEST(message_timer_time_to_next_repeating) - // { - // etl::intrusive_timer<3> timer_controller; - // - // etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::Repeating); - // etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Repeating); - // etl::timer::id::type id3 = timer_controller.register_timer(free_callback2, 11, etl::timer::mode::Repeating); - // - // timer_controller.start(id1); - // timer_controller.start(id3); - // timer_controller.start(id2); - // - // timer_controller.enable(true); - // - // CHECK_EQUAL(11, timer_controller.time_to_next()); - // - // timer_controller.tick(7); - // CHECK_EQUAL(4, timer_controller.time_to_next()); - // - // timer_controller.tick(7); - // CHECK_EQUAL(8, timer_controller.time_to_next()); - // - // timer_controller.tick(7); - // CHECK_EQUAL(1, timer_controller.time_to_next()); - // - // timer_controller.tick(7); - // CHECK_EQUAL(5, timer_controller.time_to_next()); - // - // timer_controller.tick(7); - // CHECK_EQUAL(2, timer_controller.time_to_next()); - // - // timer_controller.tick(7); - // CHECK_EQUAL(2, timer_controller.time_to_next()); - // - // timer_controller.tick(7); - // CHECK_EQUAL(6, timer_controller.time_to_next()); - // - // timer_controller.tick(7); - // CHECK_EQUAL(10, timer_controller.time_to_next()); - // - // timer_controller.tick(7); - // CHECK_EQUAL(3, timer_controller.time_to_next()); - // - // timer_controller.tick(7); - // CHECK_EQUAL(4, timer_controller.time_to_next()); - // } - // - // //************************************************************************* - // TEST(message_timer_time_to_next_with_has_active_timer) - // { - // etl::intrusive_timer<3> timer_controller; - // - // etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::Single_Shot); - // etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Single_Shot); - // etl::timer::id::type id3 = timer_controller.register_timer(free_callback2, 11, etl::timer::mode::Single_Shot); - // - // timer_controller.start(id1); - // timer_controller.start(id3); - // timer_controller.start(id2); - // - // timer_controller.enable(true); - // - // timer_controller.tick(11); - // CHECK_EQUAL(12, timer_controller.time_to_next()); - // CHECK_TRUE(timer_controller.has_active_timer()); - // - // timer_controller.tick(23); - // CHECK_EQUAL(3, timer_controller.time_to_next()); - // CHECK_TRUE(timer_controller.has_active_timer()); - // - // timer_controller.tick(2); - // CHECK_EQUAL(1, timer_controller.time_to_next()); - // CHECK_TRUE(timer_controller.has_active_timer()); - // - // timer_controller.tick(1); - // CHECK_EQUAL(static_cast(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next()); - // CHECK_FALSE(timer_controller.has_active_timer()); - // } - // - // //************************************************************************* - // class test_object - // { - // public: - // - // void call() - // { - // ++called; - // } - // - // size_t called = 0UL; - // }; - // - // using callback_type = etl::iintrusive_timer::callback_type; - // - // TEST(test_intrusive_timer_call_etl_delegate) - // { - // test_object test_obj; - // callback_type delegate_callback = callback_type::create(test_obj); - // etl::intrusive_timer<1> timer_controller; - // - // timer_controller.enable(true); - // - // etl::timer::id::type id = timer_controller.register_timer(delegate_callback, 5, etl::timer::mode::Single_Shot); - // timer_controller.start(id); - // - // timer_controller.tick(4); - // CHECK(test_obj.called == 0); - // - // timer_controller.tick(2); - // CHECK(test_obj.called == 1); - // } - // - // //************************************************************************* - // TEST(test_intrusive_timer_is_active) - // { - // timerInsertRemoveTest.clear(); - // etl::intrusive_timer<4> timer_controller; - // - // etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::Single_Shot); - // etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Single_Shot); - // etl::timer::id::type id3 = timer_controller.register_timer(free_callback2, 11, etl::timer::mode::Single_Shot); - // - // timer_controller.set_insert_callback( - // event_callback_type::create()); - // timer_controller.set_remove_callback( - // event_callback_type::create()); - // - // timer_controller.start(id1); - // timer_controller.start(id3); - // timer_controller.start(id2); - // - // CHECK_EQUAL(3, timerInsertRemoveTest.inserted); - // CHECK_EQUAL(0, timerInsertRemoveTest.removed); - // - // timer_controller.enable(true); - // - // CHECK_TRUE(timer_controller.is_active(id1)); - // CHECK_TRUE(timer_controller.is_active(id2)); - // CHECK_TRUE(timer_controller.is_active(id3)); - // - // CHECK_EQUAL(3, timerInsertRemoveTest.inserted); - // CHECK_EQUAL(0, timerInsertRemoveTest.removed); - // - // timer_controller.tick(11); - // CHECK_TRUE(timer_controller.is_active(id1)); - // CHECK_TRUE(timer_controller.is_active(id2)); - // CHECK_FALSE(timer_controller.is_active(id3)); - // - // CHECK_EQUAL(3, timerInsertRemoveTest.inserted); - // CHECK_EQUAL(1, timerInsertRemoveTest.removed); - // - // timer_controller.tick(23 - 11); - // CHECK_TRUE(timer_controller.is_active(id1)); - // CHECK_FALSE(timer_controller.is_active(id2)); - // CHECK_FALSE(timer_controller.is_active(id3)); - // - // CHECK_EQUAL(3, timerInsertRemoveTest.inserted); - // CHECK_EQUAL(2, timerInsertRemoveTest.removed); - // - // timer_controller.tick(37 - 23); - // CHECK_FALSE(timer_controller.is_active(id1)); - // CHECK_FALSE(timer_controller.is_active(id2)); - // CHECK_FALSE(timer_controller.is_active(id3)); - // - // CHECK_EQUAL(3, timerInsertRemoveTest.inserted); - // CHECK_EQUAL(3, timerInsertRemoveTest.removed); - // } - // - // //************************************************************************* - // #if REALTIME_TEST - // - // #if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently - // // supported - // #define RAISE_THREAD_PRIORITY SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST) - // #define FIX_PROCESSOR_AFFINITY SetThreadAffinityMask(GetCurrentThread(), 1); - // #else - // #define RAISE_THREAD_PRIORITY - // #define FIX_PROCESSOR_AFFINITY - // #endif - // - // etl::intrusive_timer<3> controller; - // - // void timer_event() - // { - // const uint32_t TICK = 1U; - // uint32_t tick = TICK; - // ticks = 1U; - // - // RAISE_THREAD_PRIORITY; - // FIX_PROCESSOR_AFFINITY; - // - // while (ticks <= 1000U) - // { - // std::this_thread::sleep_for(std::chrono::milliseconds(1)); - // - // if (controller.tick(tick)) - // { - // tick = TICK; - // } - // else - // { - // tick += TICK; - // } - // - // ++ticks; - // } - // } - // - // TEST(test_intrusive_timer_threads) - // { - // FIX_PROCESSOR_AFFINITY; - // - // etl::timer::id::type id1 = controller.register_timer(member_callback, 400, etl::timer::mode::Single_Shot); - // etl::timer::id::type id2 = controller.register_timer(free_function_callback, 100, etl::timer::mode::Repeating); - // etl::timer::id::type id3 = controller.register_timer(free_callback2, 10, etl::timer::mode::Repeating); - // - // object.tick_list.clear(); - // free_tick_list1.clear(); - // free_tick_list2.clear(); - // - // controller.start(id1); - // controller.start(id2); - // // controller.start(id3); - // - // controller.enable(true); - // - // std::thread t1(timer_event); - // - // bool restart_1 = true; - // - // while (ticks <= 1000U) - // { - // if ((ticks > 200U) && (ticks < 500U)) - // { - // controller.stop(id3); - // } - // - // if ((ticks > 600U) && (ticks < 800U)) - // { - // controller.start(id3); - // } - // - // if ((ticks > 500U) && restart_1) - // { - // controller.start(id1); - // restart_1 = false; - // } - // - // std::this_thread::sleep_for(std::chrono::milliseconds(1)); - // } - // - // // Join the thread with the main thread - // t1.join(); - // - // CHECK_EQUAL(2U, object.tick_list.size()); - // CHECK_EQUAL(10U, free_tick_list1.size()); - // CHECK(free_tick_list2.size() < 65U); - // - // // std::vector compare1 = { 400, 900 }; - // // std::vector compare2 = { 100, 200, 300, 400, 500, 600, 700, - // // 800, 900, 1000 }; - // - // CHECK(object.tick_list.size() != 0); - // CHECK(free_tick_list1.size() != 0); - // CHECK(free_tick_list2.size() != 0); - // - // // CHECK_ARRAY_EQUAL(compare1.data(), object.tick_list.data(), - // // min(compare1.size(), object.tick_list.size())); - // // CHECK_ARRAY_EQUAL(compare2.data(), free_tick_list1.data(), - // // min(compare2.size(), free_tick_list1.size())); - // } - // #endif + //************************************************************************* + TEST(test_intrusive_timer_repeating_clear) + { + LockPolicy lock_policy; + + etl::intrusive_timer timer_controller(lock_policy); + timer_controller.set_next_timer_notification(notification_delegate); + time_to_next.clear(); + + global_callback_clear(); + etl::timer_config config1(37, etl::timer::mode::Repeating); + CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback); + CallbackTimer callback_timer1(config1, callback_delegate1); + + object.clear(); + etl::timer_config config2(23, etl::timer::mode::Repeating); + CallbackDelegate callback_delegate2 = CallbackDelegate::create(); + CallbackTimer callback_timer2(config2, callback_delegate2); + + message_processor.clear(); + etl::timer_config config3(11, etl::timer::mode::Repeating); + MessageTimer callback_timer3(config3, message_processor, callback_message); + + timer_controller.register_timer(callback_timer1); + timer_controller.register_timer(callback_timer2); + timer_controller.register_timer(callback_timer3); + + timer_controller.start(callback_timer1); // 37, the first timer started is the first due to expire. + timer_controller.start(callback_timer3); // 11, the second timer started is now first due to expire, 37 is second. + timer_controller.start(callback_timer2); // 23, the third timer started is now second due to expire.37 is third. + + time_to_next.clear(); + + timer_controller.enable(true); + + ticks = 0; + + const uint32_t step = 1UL; + + while (ticks <= 100U) + { + ticks += step; + + if (ticks == 40) + { + timer_controller.clear(); + } + + timer_controller.tick(step); + } + + // Check that the timers have been cleared. + CHECK_EQUAL(3, timer_controller.number_of_timers()); + CHECK_TRUE(callback_timer1.get_id() == etl::timer::id::No_Timer); + CHECK_TRUE(callback_timer2.get_id() == etl::timer::id::No_Timer); + CHECK_TRUE(callback_timer3.get_id() == etl::timer::id::No_Timer); + CHECK_TRUE(callback_timer1.get_interval() == etl::timer::interval::No_Active_Interval); + CHECK_TRUE(callback_timer2.get_interval() == etl::timer::interval::No_Active_Interval); + CHECK_TRUE(callback_timer3.get_interval() == etl::timer::interval::No_Active_Interval); + CHECK_TRUE(callback_timer1.get_mode() == etl::timer::mode::No_Mode_Set); + CHECK_TRUE(callback_timer2.get_mode() == etl::timer::mode::No_Mode_Set); + CHECK_TRUE(callback_timer3.get_mode() == etl::timer::mode::No_Mode_Set); + + // Check the callback counts. + CHECK_TRUE(global_callback_called); + CHECK_EQUAL(1, global_call_count); + + CHECK_TRUE(object.member_callback_called); + CHECK_EQUAL(1, object.member_call_count); + + CHECK_TRUE(message_processor.message_callback_called); + CHECK_EQUAL(3, message_processor.message_call_count); + + // Check the notifications. + CHECK_EQUAL(5, time_to_next.size()); + CHECK_EQUAL(11, time_to_next[0]); + CHECK_EQUAL(1, time_to_next[1]); + CHECK_EQUAL(10, time_to_next[2]); + CHECK_EQUAL(4, time_to_next[3]); + CHECK_EQUAL(7, time_to_next[4]); + + time_to_next.clear(); + } + + //************************************************************************* + TEST(test_intrusive_timer_delayed_immediate) + { + LockPolicy lock_policy; + + etl::intrusive_timer timer_controller(lock_policy); + timer_controller.set_next_timer_notification(notification_delegate); + time_to_next.clear(); + + global_callback_clear(); + etl::timer_config config1(37, etl::timer::mode::Repeating); + CallbackDelegate callback_delegate1 = CallbackDelegate::create(global_callback); + CallbackTimer callback_timer1(config1, callback_delegate1); + + object.clear(); + etl::timer_config config2(23, etl::timer::mode::Repeating); + CallbackDelegate callback_delegate2 = CallbackDelegate::create(); + CallbackTimer callback_timer2(config2, callback_delegate2); + + message_processor.clear(); + etl::timer_config config3(11, etl::timer::mode::Repeating); + MessageTimer callback_timer3(config3, message_processor, callback_message); + + timer_controller.register_timer(callback_timer1); + timer_controller.register_timer(callback_timer2); + timer_controller.register_timer(callback_timer3); + + time_to_next.clear(); + + timer_controller.enable(true); + + ticks = 0; + timer_controller.tick(uint32_t(ticks)); + + timer_controller.start(callback_timer1, etl::timer::start::Immediate); + timer_controller.start(callback_timer2, etl::timer::start::Immediate); + timer_controller.start(callback_timer3, etl::timer::start::Delayed); + + const uint32_t step = 1U; + + while (ticks <= 100U) + { + ticks += step; + timer_controller.tick(step); + } + + // Check the callback counts. + CHECK_TRUE(global_callback_called); + CHECK_EQUAL(3, global_call_count); + + CHECK_TRUE(object.member_callback_called); + CHECK_EQUAL(5, object.member_call_count); + + CHECK_TRUE(message_processor.message_callback_called); + CHECK_EQUAL(9, message_processor.message_call_count); + + // Check the notifications. + CHECK_EQUAL(18, time_to_next.size()); + CHECK_EQUAL(37, time_to_next[0]); + CHECK_EQUAL(23, time_to_next[1]); + CHECK_EQUAL(11, time_to_next[2]); + CHECK_EQUAL(11, time_to_next[3]); + CHECK_EQUAL(1, time_to_next[4]); + CHECK_EQUAL(10, time_to_next[5]); + CHECK_EQUAL(4, time_to_next[6]); + CHECK_EQUAL(7, time_to_next[7]); + CHECK_EQUAL(2, time_to_next[8]); + CHECK_EQUAL(9, time_to_next[9]); + CHECK_EQUAL(11, time_to_next[10]); + CHECK_EQUAL(3, time_to_next[11]); + CHECK_EQUAL(5, time_to_next[12]); + CHECK_EQUAL(3, time_to_next[13]); + CHECK_EQUAL(11, time_to_next[14]); + CHECK_EQUAL(4, time_to_next[15]); + CHECK_EQUAL(7, time_to_next[16]); + CHECK_EQUAL(11, time_to_next[17]); + + time_to_next.clear(); + } + + //************************************************************************* +#if REALTIME_TEST + + #if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently + // supported + #define RAISE_THREAD_PRIORITY SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST) + #define FIX_PROCESSOR_AFFINITY SetThreadAffinityMask(GetCurrentThread(), 1); + #else + #define RAISE_THREAD_PRIORITY + #define FIX_PROCESSOR_AFFINITY + #endif + + //************************************************************************* + class semaphore_lock_policy : public etl::timer_lock_policy + { + public: + + //******************************************* + semaphore_lock_policy() + : semaphore(0) + { + } + + //******************************************* + void lock() ETL_NOEXCEPT override + { + ++semaphore; + + // Add a small delay to cause the locks to more likely contend. + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + //******************************************* + void unlock() ETL_NOEXCEPT override + { + --semaphore; + } + + //******************************************* + bool is_locked() ETL_NOEXCEPT override + { + return (semaphore > 0); + } + + std::atomic semaphore; + }; + + semaphore_lock_policy real_time_lock_policy; + etl::intrusive_timer timer_controller(real_time_lock_policy); + + std::atomic real_time_ticks(0U); + + static void real_time_callback1(); + static void real_time_callback2(); + static void real_time_callback3(); + + etl::timer_config config1(10, etl::timer::mode::Repeating); + CallbackDelegate callback_delegate1 = CallbackDelegate::create(real_time_callback1); + CallbackTimer callback_timer1(config1, callback_delegate1); + + etl::timer_config config2(10, etl::timer::mode::Repeating); + CallbackDelegate callback_delegate2 = CallbackDelegate::create(real_time_callback2); + CallbackTimer callback_timer2(config2, callback_delegate2); + + etl::timer_config config3(10, etl::timer::mode::Repeating); + CallbackDelegate callback_delegate3 = CallbackDelegate::create(real_time_callback3); + CallbackTimer callback_timer3(config3, callback_delegate3); + + int real_time_callback_count1 = 0; + int real_time_callback_count2 = 0; + int real_time_callback_count3 = 0; + + //********************************* + static void real_time_callback1() + { + ++real_time_callback_count1; + } + + static void real_time_callback2() + { + ++real_time_callback_count2; + } + + static void real_time_callback3() + { + ++real_time_callback_count3; + } + + //********************************* + void timer_event() + { + uint32_t delta = 1; + + RAISE_THREAD_PRIORITY; + FIX_PROCESSOR_AFFINITY; + + while (real_time_ticks.load() <= 1000U) + { + if (timer_controller.tick(delta)) + { + delta = 1; + } + else + { + // Enable the assert to check that the tick can sometimes fail to process due to contending locks. + // This is expected behaviour. + // assert(false); + ++delta; + } + + ++real_time_ticks; + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + } + + //********************************* + TEST(test_intrusive_timer_threads) + { + FIX_PROCESSOR_AFFINITY; + + timer_controller.register_timer(callback_timer1); + timer_controller.register_timer(callback_timer2); + timer_controller.register_timer(callback_timer3); + + timer_controller.start(callback_timer1); + timer_controller.start(callback_timer2); + timer_controller.start(callback_timer3); + + timer_controller.enable(true); + + std::thread t1(timer_event); + + int count1 = 0; + int count2 = 0; + int count3 = 0; + + while (real_time_ticks.load() <= 1000U) + { + if (count1 == 50) + { + timer_controller.stop(callback_timer1); + } + + if (count1 == 100) + { + timer_controller.start(callback_timer1); + count1 = 0; + } + + if (count2 == 60) + { + timer_controller.stop(callback_timer2); + } + + if (count2 == 110) + { + timer_controller.start(callback_timer2); + count2 = 0; + } + + if (count3 == 70) + { + timer_controller.stop(callback_timer3); + } + + if (count3 == 120) + { + timer_controller.start(callback_timer3); + count3 = 0; + } + + ++count1; + ++count2; + ++count3; + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + // Join the thread with the main thread + t1.join(); + + CHECK_TRUE(real_time_callback_count1 > 30); + CHECK_TRUE(real_time_callback_count2 > 30); + CHECK_TRUE(real_time_callback_count3 > 30); + } +#endif } } // namespace diff --git a/test/test_timer_lists.cpp b/test/test_timer_lists.cpp index 44593cbf..debb2a1e 100644 --- a/test/test_timer_lists.cpp +++ b/test/test_timer_lists.cpp @@ -194,7 +194,7 @@ namespace etl::timer_node* timer = active_list.first(); - // The timers should be in the order of their periods. + // The timers should be in the order of their intervals. CHECK_EQUAL(&timer2, timer); timer = active_list.next(timer); CHECK_EQUAL(&timer3, timer); @@ -208,23 +208,23 @@ namespace CHECK_EQUAL(active_list.end(), timer); // Check the deltas are correct. - // The period order of the timers in the list is timer2, timer3, timer5, timer1, timer4. - // timer 5 has the same period as timer 3, so it should be after timer 3 in the list. - CHECK_EQUAL(timer2.get_period(), timer2.get_delta()); - CHECK_EQUAL(timer3.get_period() - timer2.get_period(), timer3.get_delta()); - CHECK_EQUAL(timer1.get_period() - timer3.get_period(), timer1.get_delta()); - CHECK_EQUAL(timer4.get_period() - timer1.get_period(), timer4.get_delta()); - CHECK_EQUAL(timer5.get_period() - timer3.get_period(), timer5.get_delta()); + // The interval order of the timers in the list is timer2, timer3, timer5, timer1, timer4. + // timer 5 has the same interval as timer 3, so it should be after timer 3 in the list. + CHECK_EQUAL(timer2.get_interval(), timer2.get_delta()); + CHECK_EQUAL(timer3.get_interval() - timer2.get_interval(), timer3.get_delta()); + CHECK_EQUAL(timer1.get_interval() - timer3.get_interval(), timer1.get_delta()); + CHECK_EQUAL(timer4.get_interval() - timer1.get_interval(), timer4.get_delta()); + CHECK_EQUAL(timer5.get_interval() - timer3.get_interval(), timer5.get_delta()); // Remove timer3 from the list. active_list.remove(&timer3); // Check the deltas are still correct. - // The period order of the timers in the list is now timer2, timer5, timer1, timer4. - CHECK_EQUAL(timer2.get_period(), timer2.get_delta()); - CHECK_EQUAL(timer5.get_period() - timer2.get_period(), timer5.get_delta()); - CHECK_EQUAL(timer1.get_period() - timer5.get_period(), timer1.get_delta()); - CHECK_EQUAL(timer4.get_period() - timer1.get_period(), timer4.get_delta()); + // The interval order of the timers in the list is now timer2, timer5, timer1, timer4. + CHECK_EQUAL(timer2.get_interval(), timer2.get_delta()); + CHECK_EQUAL(timer5.get_interval() - timer2.get_interval(), timer5.get_delta()); + CHECK_EQUAL(timer1.get_interval() - timer5.get_interval(), timer1.get_delta()); + CHECK_EQUAL(timer4.get_interval() - timer1.get_interval(), timer4.get_delta()); // Search the list to ensure the other timers are still present. bool timer1_found = false; diff --git a/test/test_timer_node.cpp b/test/test_timer_node.cpp index 75237df0..0d1a8d51 100644 --- a/test/test_timer_node.cpp +++ b/test/test_timer_node.cpp @@ -38,24 +38,24 @@ namespace TEST(test_timer_config) { constexpr etl::timer_config config1(100U, etl::timer::mode::Repeating); - CHECK_EQUAL(100U, config1.get_period()); + CHECK_EQUAL(100U, config1.get_interval()); CHECK_EQUAL(etl::timer::mode::Repeating, config1.get_mode()); etl::timer_config config2(200U, etl::timer::mode::Single_Shot); - CHECK_EQUAL(200U, config2.get_period()); + CHECK_EQUAL(200U, config2.get_interval()); CHECK_EQUAL(etl::timer::mode::Single_Shot, config2.get_mode()); etl::timer_config config3(config2); - CHECK_EQUAL(config2.get_period(), config3.get_period()); + CHECK_EQUAL(config2.get_interval(), config3.get_interval()); CHECK_EQUAL(etl::timer::mode::Single_Shot, config2.get_mode()); etl::timer_config config4 = etl::timer_config(500U, etl::timer::mode::Repeating); - CHECK_EQUAL(500U, config4.get_period()); + CHECK_EQUAL(500U, config4.get_interval()); CHECK_EQUAL(etl::timer::mode::Repeating, config4.get_mode()); config2.clear(); - CHECK_EQUAL(etl::timer::state::Inactive, config2.get_period()); - CHECK_EQUAL(etl::timer::mode::Repeating, config2.get_mode()); + CHECK_EQUAL(etl::timer::interval::No_Active_Interval, config2.get_interval()); + CHECK_EQUAL(etl::timer::mode::No_Mode_Set, config2.get_mode()); } //************************************************************************* @@ -68,10 +68,10 @@ namespace const etl::timer_config& config1_ref = node1.get_config(); - CHECK_EQUAL(config1.get_period(), node1.get_config().get_period()); + CHECK_EQUAL(config1.get_interval(), node1.get_config().get_interval()); CHECK_EQUAL(config1.get_mode(), node1.get_config().get_mode()); - CHECK_EQUAL(node1.get_config().get_period(), node2.get_config().get_period()); + CHECK_EQUAL(node1.get_config().get_interval(), node2.get_config().get_interval()); CHECK_EQUAL(node1.get_config().get_mode(), node2.get_config().get_mode()); } }