mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 14:49:53 +08:00
Fix bug if timer list is empty for 49+ days. (Internal tick count rollover)
This commit is contained in:
parent
8455e108bc
commit
e174276556
@ -1,5 +1,5 @@
|
||||
name=Embedded Template Library
|
||||
version=10.0.0
|
||||
version=10.0.1
|
||||
author= John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
sentence=A C++ template library tailored for embedded systems.
|
||||
|
||||
@ -467,34 +467,37 @@ namespace etl
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
tick_count += count;
|
||||
|
||||
if (process_semaphore == 0)
|
||||
{
|
||||
// We have something to do?
|
||||
while (!active_list.empty() && (tick_count >= active_list.front().delta))
|
||||
if (!active_list.empty())
|
||||
{
|
||||
etl::callback_timer_data& timer = active_list.front();
|
||||
tick_count += count;
|
||||
|
||||
tick_count -= timer.delta;
|
||||
|
||||
active_list.remove(timer.id, true);
|
||||
|
||||
if (timer.repeating)
|
||||
while (!active_list.empty() && (tick_count >= active_list.front().delta))
|
||||
{
|
||||
timer.delta = timer.period;
|
||||
active_list.insert(timer.id);
|
||||
}
|
||||
|
||||
if (timer.p_callback != nullptr)
|
||||
{
|
||||
if (timer.is_c_callback)
|
||||
etl::callback_timer_data& timer = active_list.front();
|
||||
|
||||
tick_count -= timer.delta;
|
||||
|
||||
active_list.remove(timer.id, true);
|
||||
|
||||
if (timer.repeating)
|
||||
{
|
||||
reinterpret_cast<void (*)()>(timer.p_callback)();
|
||||
timer.delta = timer.period;
|
||||
active_list.insert(timer.id);
|
||||
}
|
||||
else
|
||||
|
||||
if (timer.p_callback != nullptr)
|
||||
{
|
||||
(*reinterpret_cast<etl::ifunction<void>*>(timer.p_callback))();
|
||||
if (timer.is_c_callback)
|
||||
{
|
||||
reinterpret_cast<void(*)()>(timer.p_callback)();
|
||||
}
|
||||
else
|
||||
{
|
||||
(*reinterpret_cast<etl::ifunction<void>*>(timer.p_callback))();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -529,6 +532,7 @@ namespace etl
|
||||
active_list.remove(timer.id, false);
|
||||
}
|
||||
|
||||
// Compensate for current tick count.
|
||||
timer.delta = tick_count;
|
||||
|
||||
if (!immediate_)
|
||||
|
||||
@ -431,37 +431,40 @@ namespace etl
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
tick_count += count;
|
||||
|
||||
if (process_semaphore == 0)
|
||||
{
|
||||
// We have something to do?
|
||||
while (!active_list.empty() && (tick_count >= active_list.front().delta))
|
||||
if (!active_list.empty())
|
||||
{
|
||||
etl::message_timer_data& timer = active_list.front();
|
||||
tick_count += count;
|
||||
|
||||
tick_count -= timer.delta;
|
||||
|
||||
active_list.remove(timer.id, true);
|
||||
|
||||
if (timer.repeating)
|
||||
while (!active_list.empty() && (tick_count >= active_list.front().delta))
|
||||
{
|
||||
timer.delta = timer.period;
|
||||
active_list.insert(timer.id);
|
||||
}
|
||||
etl::message_timer_data& timer = active_list.front();
|
||||
|
||||
if (timer.p_router != nullptr)
|
||||
{
|
||||
if (timer.p_router->get_message_router_id() == etl::imessage_router::MESSAGE_BUS)
|
||||
tick_count -= timer.delta;
|
||||
|
||||
active_list.remove(timer.id, true);
|
||||
|
||||
if (timer.repeating)
|
||||
{
|
||||
// Send to a message bus.
|
||||
etl::imessage_bus& bus = static_cast<etl::imessage_bus&>(*(timer.p_router));
|
||||
bus.receive(timer.destination_router_id, *(timer.p_message));
|
||||
timer.delta = timer.period;
|
||||
active_list.insert(timer.id);
|
||||
}
|
||||
else
|
||||
|
||||
if (timer.p_router != nullptr)
|
||||
{
|
||||
// Send to a router.
|
||||
timer.p_router->receive(*(timer.p_message));
|
||||
if (timer.p_router->get_message_router_id() == etl::imessage_router::MESSAGE_BUS)
|
||||
{
|
||||
// Send to a message bus.
|
||||
etl::imessage_bus& bus = static_cast<etl::imessage_bus&>(*(timer.p_router));
|
||||
bus.receive(timer.destination_router_id, *(timer.p_message));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send to a router.
|
||||
timer.p_router->receive(*(timer.p_message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -496,6 +499,7 @@ namespace etl
|
||||
active_list.remove(timer.id, false);
|
||||
}
|
||||
|
||||
// Compensate for current tick count.
|
||||
timer.delta = tick_count;
|
||||
|
||||
if (!immediate_)
|
||||
|
||||
@ -439,6 +439,44 @@ namespace
|
||||
CHECK_ARRAY_EQUAL(compare2.data(), free_tick_list2.data(), compare2.size());
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(callback_timer_one_shot_empty_list_huge_tick_before_insert)
|
||||
{
|
||||
etl::callback_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 = 5;
|
||||
|
||||
for (uint32_t i = 0; 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 = 0; i < step; ++i)
|
||||
{
|
||||
++ticks;
|
||||
timer_controller.tick(1);
|
||||
}
|
||||
std::vector<uint64_t> compare1 = { 5, 10 };
|
||||
|
||||
CHECK_ARRAY_EQUAL(compare1.data(), free_tick_list1.data(), compare1.size());
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
#if REALTIME_TEST
|
||||
etl::callback_timer<3> controller;
|
||||
|
||||
@ -510,6 +510,44 @@ namespace
|
||||
CHECK_ARRAY_EQUAL(compare2.data(), router1.message2.data(), compare2.size());
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(callback_timer_one_shot_empty_list_huge_tick_before_insert)
|
||||
{
|
||||
etl::message_timer<3> timer_controller;
|
||||
|
||||
etl::timer::id::type id1 = timer_controller.register_timer(message1, router1, 5, etl::timer::mode::SINGLE_SHOT);
|
||||
|
||||
router1.clear();
|
||||
|
||||
timer_controller.start(id1);
|
||||
|
||||
timer_controller.enable(true);
|
||||
|
||||
ticks = 0;
|
||||
|
||||
const uint32_t step = 5;
|
||||
|
||||
for (uint32_t i = 0; 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 = 0; i < step; ++i)
|
||||
{
|
||||
++ticks;
|
||||
timer_controller.tick(1);
|
||||
}
|
||||
std::vector<uint64_t> compare1 = { 5, 10 };
|
||||
|
||||
CHECK_ARRAY_EQUAL(compare1.data(), router1.message1.data(), compare1.size());
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
#if REALTIME_TEST
|
||||
etl::message_timer<3> controller;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user