mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Modified atomic timer.
Experimentally added timer id to callback.
This commit is contained in:
parent
8a7647cb3a
commit
c73d96b5bc
@ -86,7 +86,7 @@ namespace etl
|
||||
|
||||
typedef etl::delegate<void(void)> callback_type;
|
||||
|
||||
typedef etl::delegate<void(uint32_t)> event_callback_type;
|
||||
typedef etl::delegate<void(etl::timer::id::type, uint32_t)> event_callback_type;
|
||||
|
||||
//*******************************************
|
||||
/// Register a timer.
|
||||
@ -197,7 +197,7 @@ namespace etl
|
||||
{
|
||||
ETL_DISABLE_TIMER_UPDATES;
|
||||
active_list.remove(timer.id, false);
|
||||
time_to_next_callback.call_if(time_to_next());
|
||||
time_to_next_callback.call_if(next_timer(), time_to_next());
|
||||
ETL_ENABLE_TIMER_UPDATES;
|
||||
}
|
||||
|
||||
@ -296,7 +296,7 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
time_to_next_callback.call_if(time_to_next());
|
||||
time_to_next_callback.call_if(next_timer(), time_to_next());
|
||||
|
||||
has_active = !active_list.empty();
|
||||
}
|
||||
@ -341,7 +341,7 @@ namespace etl
|
||||
|
||||
timer.delta = immediate_ ? 0 : timer.period;
|
||||
active_list.insert(timer.id);
|
||||
time_to_next_callback.call_if(time_to_next());
|
||||
time_to_next_callback.call_if(next_timer(), time_to_next());
|
||||
ETL_ENABLE_TIMER_UPDATES;
|
||||
|
||||
result = true;
|
||||
@ -371,7 +371,7 @@ namespace etl
|
||||
{
|
||||
ETL_DISABLE_TIMER_UPDATES;
|
||||
active_list.remove(timer.id, false);
|
||||
time_to_next_callback.call_if(time_to_next());
|
||||
time_to_next_callback.call_if(next_timer(), time_to_next());
|
||||
ETL_ENABLE_TIMER_UPDATES;
|
||||
}
|
||||
|
||||
@ -435,6 +435,23 @@ namespace etl
|
||||
return delta;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Get the ID of the next timer event.
|
||||
/// Returns etl::timer::id::No_Timer if there is no active
|
||||
/// timer.
|
||||
//*******************************************
|
||||
uint32_t next_timer() const
|
||||
{
|
||||
etl::timer::id::type id = etl::timer::id::No_Timer;
|
||||
|
||||
if (has_active_timer())
|
||||
{
|
||||
id = active_list.front().id;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Checks if a timer is currently active.
|
||||
/// Returns <b>true</b> if the timer is active, otherwise <b>false</b>.
|
||||
|
||||
@ -51,7 +51,7 @@ namespace etl
|
||||
|
||||
typedef etl::delegate<void(void)> callback_type;
|
||||
|
||||
typedef etl::delegate<void(etl::timer::id::type)> event_callback_type;
|
||||
typedef etl::delegate<void(uint32_t)> event_callback_type;
|
||||
|
||||
//*******************************************
|
||||
/// Register a timer.
|
||||
@ -100,7 +100,7 @@ namespace etl
|
||||
{
|
||||
++process_semaphore;
|
||||
active_list.remove(timer.id, false);
|
||||
remove_callback.call_if(timer.id);
|
||||
time_to_next_callback.call_if(time_to_next());
|
||||
--process_semaphore;
|
||||
}
|
||||
|
||||
@ -172,7 +172,6 @@ namespace etl
|
||||
count -= timer.delta;
|
||||
|
||||
active_list.remove(timer.id, true);
|
||||
remove_callback.call_if(timer.id);
|
||||
|
||||
if (timer.callback.is_valid())
|
||||
{
|
||||
@ -185,9 +184,10 @@ namespace etl
|
||||
// Reinsert the timer.
|
||||
timer.delta = timer.period;
|
||||
active_list.insert(timer.id);
|
||||
insert_callback.call_if(timer.id);
|
||||
}
|
||||
|
||||
time_to_next_callback.call_if(time_to_next());
|
||||
|
||||
has_active = !active_list.empty();
|
||||
}
|
||||
|
||||
@ -227,12 +227,11 @@ namespace etl
|
||||
if (timer.is_active())
|
||||
{
|
||||
active_list.remove(timer.id, false);
|
||||
remove_callback.call_if(timer.id);
|
||||
}
|
||||
|
||||
timer.delta = immediate_ ? 0U : timer.period;
|
||||
active_list.insert(timer.id);
|
||||
insert_callback.call_if(timer.id);
|
||||
time_to_next_callback.call_if(time_to_next());
|
||||
--process_semaphore;
|
||||
|
||||
result = true;
|
||||
@ -262,7 +261,7 @@ namespace etl
|
||||
{
|
||||
++process_semaphore;
|
||||
active_list.remove(timer.id, false);
|
||||
remove_callback.call_if(timer.id);
|
||||
time_to_next_callback.call_if(time_to_next());
|
||||
--process_semaphore;
|
||||
}
|
||||
|
||||
@ -360,32 +359,18 @@ namespace etl
|
||||
return result;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Set a callback when a timer is inserted on list
|
||||
//*******************************************
|
||||
void set_insert_callback(event_callback_type insert_)
|
||||
{
|
||||
insert_callback = insert_;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Set a callback when a timer is removed from list
|
||||
//*******************************************
|
||||
void set_remove_callback(event_callback_type remove_)
|
||||
void set_time_to_next_callback(event_callback_type time_to_next_)
|
||||
{
|
||||
remove_callback = remove_;
|
||||
time_to_next_callback = time_to_next_;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
void clear_insert_callback()
|
||||
void clear_time_next_callback()
|
||||
{
|
||||
insert_callback.clear();
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
void clear_remove_callback()
|
||||
{
|
||||
remove_callback.clear();
|
||||
time_to_next_callback.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -656,8 +641,7 @@ namespace etl
|
||||
mutable TSemaphore process_semaphore;
|
||||
uint_least8_t number_of_registered_timers;
|
||||
|
||||
event_callback_type insert_callback;
|
||||
event_callback_type remove_callback;
|
||||
event_callback_type time_to_next_callback;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@ -93,20 +93,24 @@ namespace
|
||||
public:
|
||||
|
||||
uint32_t time_to_next;
|
||||
etl::timer::id::type next_timer_id;
|
||||
|
||||
TimerTimeToNextTest()
|
||||
: time_to_next(0)
|
||||
, next_timer_id(etl::timer::id::NO_TIMER)
|
||||
{
|
||||
}
|
||||
|
||||
void time_to_next_handler(uint32_t time_to_next_)
|
||||
void time_to_next_handler(etl::timer::id::type next_timer_id_, uint32_t time_to_next_)
|
||||
{
|
||||
time_to_next = time_to_next_;
|
||||
time_to_next = time_to_next_;
|
||||
next_timer_id = next_timer_id_;
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
time_to_next = 0;
|
||||
time_to_next = 0;
|
||||
next_timer_id = etl::timer::id::NO_TIMER;
|
||||
}
|
||||
};
|
||||
|
||||
@ -843,15 +847,21 @@ namespace
|
||||
timer_controller.start(id3);
|
||||
timer_controller.start(id2);
|
||||
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next); // The time to next should be the interval for id3.
|
||||
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next); // The time to next should be the interval for id3.
|
||||
CHECK_EQUAL(int(id3), int(timerTimeToNextTest.next_timer_id)); // The next timer should be id3.
|
||||
timer_controller.enable(true);
|
||||
|
||||
CHECK_EQUAL(int(id3), int(timerTimeToNextTest.next_timer_id)); // The next timer should be id3.
|
||||
CHECK_EQUAL(int(id3), int(timerTimeToNextTest.next_timer_id)); // The next timer should be id3.
|
||||
|
||||
CHECK_TRUE(timer_controller.is_active(id1));
|
||||
CHECK_TRUE(timer_controller.is_active(id2));
|
||||
CHECK_TRUE(timer_controller.is_active(id3));
|
||||
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next); // The time to next should be the interval for id3.
|
||||
// The time to next should be the interval for id3.
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next);
|
||||
// The next timer should be id3.
|
||||
CHECK_EQUAL(int(id3), int(timerTimeToNextTest.next_timer_id));
|
||||
|
||||
// Tick the time for id3 to expire.
|
||||
timer_controller.tick(9);
|
||||
@ -859,15 +869,23 @@ namespace
|
||||
CHECK_TRUE(timer_controller.is_active(id2));
|
||||
CHECK_TRUE(timer_controller.is_active(id3));
|
||||
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next); // The time to next should be the what's left of the interval for id3.
|
||||
// The time to next should be the what's left of the interval for id3.
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next);
|
||||
// The next timer should be id3.
|
||||
CHECK_EQUAL(int(id3), int(timerTimeToNextTest.next_timer_id));
|
||||
|
||||
// Stop the timer and check that the time to next is updated to that of id2.
|
||||
timer_controller.stop(id3);
|
||||
CHECK_EQUAL(14, timerTimeToNextTest.time_to_next); // The time to next should be the what's left of the interval for id2.
|
||||
// The time to next should be the what's left of the interval for id2.
|
||||
CHECK_EQUAL(14, timerTimeToNextTest.time_to_next);
|
||||
// The next timer should be id2.
|
||||
CHECK_EQUAL(int(id2), int(timerTimeToNextTest.next_timer_id));
|
||||
|
||||
// Start the timer again and check that the time to next is updated to the interval for id3.
|
||||
timer_controller.start(id3);
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next);
|
||||
// The next timer should be id3.
|
||||
CHECK_EQUAL(int(id3), int(timerTimeToNextTest.next_timer_id));
|
||||
|
||||
// Tick the time for id3 to expire.
|
||||
timer_controller.tick(9);
|
||||
@ -877,6 +895,8 @@ namespace
|
||||
|
||||
// The time to next should be the what's left of the interval for id2.
|
||||
CHECK_EQUAL(5, timerTimeToNextTest.time_to_next);
|
||||
// The next timer should be id2.
|
||||
CHECK_EQUAL(int(id2), int(timerTimeToNextTest.next_timer_id));
|
||||
|
||||
// Tick the remaining time for id2 to expire.
|
||||
timer_controller.tick(5);
|
||||
@ -886,6 +906,8 @@ namespace
|
||||
|
||||
// The time to next should be the what's left of the interval for id3.
|
||||
CHECK_EQUAL(4, timerTimeToNextTest.time_to_next);
|
||||
// The next timer should be id3.
|
||||
CHECK_EQUAL(int(id3), int(timerTimeToNextTest.next_timer_id));
|
||||
|
||||
// Tick the remaining time for id3 to expire.
|
||||
timer_controller.tick(4);
|
||||
@ -895,6 +917,8 @@ namespace
|
||||
|
||||
// The time to next should be the what's left of the interval for id3.
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next);
|
||||
// The next timer should be id3.
|
||||
CHECK_EQUAL(int(id3), int(timerTimeToNextTest.next_timer_id));
|
||||
|
||||
// Tick the remaining time for id3 to expire.
|
||||
timer_controller.tick(9);
|
||||
@ -904,6 +928,8 @@ namespace
|
||||
|
||||
// The time to next should be the what's left of the interval for id1.
|
||||
CHECK_EQUAL(1, timerTimeToNextTest.time_to_next);
|
||||
// The next timer should be id1.
|
||||
CHECK_EQUAL(int(id1), int(timerTimeToNextTest.next_timer_id));
|
||||
|
||||
// Stop timer id3 so that id1 is the last timeout.
|
||||
timer_controller.stop(id3);
|
||||
@ -916,6 +942,8 @@ namespace
|
||||
|
||||
// There are no active timers so the time to next should be No_Active_Interval.
|
||||
CHECK_EQUAL(etl::timer::interval::No_Active_Interval, timerTimeToNextTest.time_to_next);
|
||||
// The next timer should be NO_TIMER.
|
||||
CHECK_EQUAL(int(etl::timer::id::NO_TIMER), int(timerTimeToNextTest.next_timer_id));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
@ -92,38 +92,29 @@ namespace
|
||||
callback_type member_callback1 = callback_type::create<Object, object, &Object::callback1>();
|
||||
callback_type member_callback2 = callback_type::create<Object, object, &Object::callback2>();
|
||||
|
||||
class TimerInsertRemoveTest
|
||||
class TimerTimeToNextTest
|
||||
{
|
||||
public:
|
||||
|
||||
uint32_t inserted;
|
||||
uint32_t removed;
|
||||
TimerInsertRemoveTest()
|
||||
: inserted(0)
|
||||
, removed(0)
|
||||
uint32_t time_to_next;
|
||||
|
||||
TimerTimeToNextTest()
|
||||
: time_to_next(0)
|
||||
{
|
||||
}
|
||||
|
||||
void insert_handler(etl::timer::id::type id_)
|
||||
void time_to_next_handler(uint32_t time_to_next_)
|
||||
{
|
||||
(void)id_;
|
||||
inserted++;
|
||||
}
|
||||
|
||||
void remove_handler(etl::timer::id::type id_)
|
||||
{
|
||||
(void)id_;
|
||||
removed++;
|
||||
time_to_next = time_to_next_;
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
inserted = 0;
|
||||
removed = 0;
|
||||
time_to_next = 0;
|
||||
}
|
||||
};
|
||||
|
||||
TimerInsertRemoveTest timerInsertRemoveTest;
|
||||
TimerTimeToNextTest timerTimeToNextTest;
|
||||
|
||||
//***************************************************************************
|
||||
// Free function callback via etl::function
|
||||
@ -800,26 +791,63 @@ namespace
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(callback_timer_is_active)
|
||||
// Tick ID1 ID2 ID3
|
||||
// 0 . . .
|
||||
// 1 . . .
|
||||
// 2 . . .
|
||||
// 3 . . .
|
||||
// 4 . . .
|
||||
// 5 . . .
|
||||
// 6 . . .
|
||||
// 7 . . .
|
||||
// 8 . . .
|
||||
// 9 . . O
|
||||
// 10 . . .
|
||||
// 11 . . .
|
||||
// 12 . . .
|
||||
// 13 . . .
|
||||
// 14 . . .
|
||||
// 15 . . .
|
||||
// 16 . . .
|
||||
// 17 . . .
|
||||
// 18 . . O
|
||||
// 19 . . .
|
||||
// 20 . . .
|
||||
// 21 . . .
|
||||
// 22 . . .
|
||||
// 23 . O .
|
||||
// 24 . . .
|
||||
// 25 . . .
|
||||
// 26 . . .
|
||||
// 27 . . O
|
||||
// 28 . . .
|
||||
// 29 . . .
|
||||
// 30 . . .
|
||||
// 31 . . .
|
||||
// 32 . . .
|
||||
// 33 . . .
|
||||
// 34 . . .
|
||||
// 35 . . .
|
||||
// 36 . . O
|
||||
// 37 O . .
|
||||
//
|
||||
TEST(callback_timer_is_active_and_time_to_next)
|
||||
{
|
||||
timerInsertRemoveTest.clear();
|
||||
timerTimeToNextTest.clear();
|
||||
etl::callback_timer_atomic<3, std::atomic_uint32_t> timer_controller;
|
||||
|
||||
etl::timer::id::type id1 = timer_controller.register_timer(member_callback1, 37, etl::timer::mode::Single_Shot);
|
||||
etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback1, 23, etl::timer::mode::Single_Shot);
|
||||
etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::Single_Shot);
|
||||
etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 9, etl::timer::mode::Repeating);
|
||||
|
||||
timer_controller.set_insert_callback(
|
||||
event_callback_type::create<TimerInsertRemoveTest, timerInsertRemoveTest, &TimerInsertRemoveTest::insert_handler>());
|
||||
timer_controller.set_remove_callback(
|
||||
event_callback_type::create<TimerInsertRemoveTest, timerInsertRemoveTest, &TimerInsertRemoveTest::remove_handler>());
|
||||
timer_controller.set_time_to_next_callback(
|
||||
event_callback_type::create<TimerTimeToNextTest, timerTimeToNextTest, &TimerTimeToNextTest::time_to_next_handler>());
|
||||
|
||||
timer_controller.start(id1);
|
||||
timer_controller.start(id3);
|
||||
timer_controller.start(id2);
|
||||
|
||||
CHECK_EQUAL(3, timerInsertRemoveTest.inserted);
|
||||
CHECK_EQUAL(0, timerInsertRemoveTest.removed);
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next); // The time to next should be the interval for id3.
|
||||
|
||||
timer_controller.enable(true);
|
||||
|
||||
@ -827,32 +855,71 @@ namespace
|
||||
CHECK_TRUE(timer_controller.is_active(id2));
|
||||
CHECK_TRUE(timer_controller.is_active(id3));
|
||||
|
||||
CHECK_EQUAL(3, timerInsertRemoveTest.inserted);
|
||||
CHECK_EQUAL(0, timerInsertRemoveTest.removed);
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next); // The time to next should be the interval for id3.
|
||||
|
||||
timer_controller.tick(11);
|
||||
// Tick the time for id3 to expire.
|
||||
timer_controller.tick(9);
|
||||
CHECK_TRUE(timer_controller.is_active(id1));
|
||||
CHECK_TRUE(timer_controller.is_active(id2));
|
||||
CHECK_FALSE(timer_controller.is_active(id3));
|
||||
CHECK_TRUE(timer_controller.is_active(id3));
|
||||
|
||||
CHECK_EQUAL(3, timerInsertRemoveTest.inserted);
|
||||
CHECK_EQUAL(1, timerInsertRemoveTest.removed);
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next); // The time to next should be the what's left of the interval for id3.
|
||||
|
||||
timer_controller.tick(23 - 11);
|
||||
// Stop the timer and check that the time to next is updated to that of id2.
|
||||
timer_controller.stop(id3);
|
||||
CHECK_EQUAL(14, timerTimeToNextTest.time_to_next); // The time to next should be the what's left of the interval for id2.
|
||||
|
||||
// Start the timer again and check that the time to next is updated to the interval for id3.
|
||||
timer_controller.start(id3);
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next);
|
||||
|
||||
// Tick the time for id3 to expire.
|
||||
timer_controller.tick(9);
|
||||
CHECK_TRUE(timer_controller.is_active(id1));
|
||||
CHECK_TRUE(timer_controller.is_active(id2));
|
||||
CHECK_TRUE(timer_controller.is_active(id3));
|
||||
|
||||
// The time to next should be the what's left of the interval for id2.
|
||||
CHECK_EQUAL(5, timerTimeToNextTest.time_to_next);
|
||||
|
||||
// Tick the remaining time for id2 to expire.
|
||||
timer_controller.tick(5);
|
||||
CHECK_TRUE(timer_controller.is_active(id1));
|
||||
CHECK_FALSE(timer_controller.is_active(id2));
|
||||
CHECK_FALSE(timer_controller.is_active(id3));
|
||||
CHECK_TRUE(timer_controller.is_active(id3));
|
||||
|
||||
CHECK_EQUAL(3, timerInsertRemoveTest.inserted);
|
||||
CHECK_EQUAL(2, timerInsertRemoveTest.removed);
|
||||
// The time to next should be the what's left of the interval for id3.
|
||||
CHECK_EQUAL(4, timerTimeToNextTest.time_to_next);
|
||||
|
||||
timer_controller.tick(37 - 23);
|
||||
// Tick the remaining time for id3 to expire.
|
||||
timer_controller.tick(4);
|
||||
CHECK_TRUE(timer_controller.is_active(id1));
|
||||
CHECK_FALSE(timer_controller.is_active(id2));
|
||||
CHECK_TRUE(timer_controller.is_active(id3));
|
||||
|
||||
// The time to next should be the what's left of the interval for id3.
|
||||
CHECK_EQUAL(9, timerTimeToNextTest.time_to_next);
|
||||
|
||||
// Tick the remaining time for id3 to expire.
|
||||
timer_controller.tick(9);
|
||||
CHECK_TRUE(timer_controller.is_active(id1));
|
||||
CHECK_FALSE(timer_controller.is_active(id2));
|
||||
CHECK_TRUE(timer_controller.is_active(id3));
|
||||
|
||||
// The time to next should be the what's left of the interval for id1.
|
||||
CHECK_EQUAL(1, timerTimeToNextTest.time_to_next);
|
||||
|
||||
// Stop timer id3 so that id1 is the last timeout.
|
||||
timer_controller.stop(id3);
|
||||
|
||||
// Tick the remaining time for id1 to expire.
|
||||
timer_controller.tick(1);
|
||||
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);
|
||||
// There are no active timers so the time to next should be No_Active_Interval.
|
||||
CHECK_EQUAL(etl::timer::interval::No_Active_Interval, timerTimeToNextTest.time_to_next);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user