#847-Add-has_active_timer-to-callback_timer

This commit is contained in:
John Wellbelove 2024-03-13 09:54:29 +00:00
parent 2a5565791c
commit b807bad3e3
17 changed files with 435 additions and 14 deletions

View File

@ -708,12 +708,26 @@ namespace etl
return false;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
return !active_list.empty();
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = active_list.front().delta;
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
if (has_active_timer())
{
delta = active_list.front().delta;
}
return delta;
}

View File

@ -297,13 +297,31 @@ namespace etl
return false;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
++process_semaphore;
bool result = !active_list.empty();
--process_semaphore;
return result;
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
++process_semaphore;
uint32_t delta = active_list.front().delta;
if (!active_list.empty())
{
delta = active_list.front().delta;
}
--process_semaphore;
return delta;

View File

@ -301,14 +301,30 @@ namespace etl
}
//*******************************************
/// Get the time to the next timer event.
/// Check if there is an active timer.
//*******************************************
uint32_t time_to_next() const
bool has_active_timer() const
{
TInterruptGuard guard;
(void)guard; // Silence 'unused variable warnings.
return !active_list.empty();
}
uint32_t delta = active_list.front().delta;
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
TInterruptGuard guard;
(void)guard; // Silence 'unused variable warnings.
if (!active_list.empty())
{
delta = active_list.front().delta;
}
return delta;
}

View File

@ -309,13 +309,31 @@ namespace etl
unlock = unlock_;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
lock();
bool result = !active_list.empty();
unlock();
return result;
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
lock();
uint32_t delta = active_list.front().delta;
if (!active_list.empty())
{
delta = active_list.front().delta;
}
unlock();
return delta;

View File

@ -589,13 +589,31 @@ namespace etl
return false;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
ETL_DISABLE_TIMER_UPDATES;
bool result = !active_list.empty();
ETL_ENABLE_TIMER_UPDATES;
return result;
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
ETL_DISABLE_TIMER_UPDATES;
uint32_t delta = active_list.front().delta;
if (!active_list.empty())
{
delta = active_list.front().delta;
}
ETL_ENABLE_TIMER_UPDATES;
return delta;

View File

@ -302,13 +302,31 @@ namespace etl
return false;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
++process_semaphore;
bool result = !active_list.empty();
--process_semaphore;
return result;
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
++process_semaphore;
uint32_t delta = active_list.front().delta;
if (!active_list.empty())
{
delta = active_list.front().delta;
}
--process_semaphore;
return delta;

View File

@ -312,14 +312,30 @@ namespace etl
}
//*******************************************
/// Get the time to the next timer event.
/// Check if there is an active timer.
//*******************************************
uint32_t time_to_next() const
bool has_active_timer() const
{
TInterruptGuard guard;
(void)guard; // Silence 'unused variable warnings.
return !active_list.empty();
}
uint32_t delta = active_list.front().delta;
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
TInterruptGuard guard;
(void)guard; // Silence 'unused variable warnings.
if (!active_list.empty())
{
delta = active_list.front().delta;
}
return delta;
}

View File

@ -318,14 +318,32 @@ namespace etl
unlock = unlock_;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
lock();
bool result = !active_list.empty();
unlock();
return result;
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
lock();
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
uint32_t delta = active_list.front().delta;
lock();
if (!active_list.empty())
{
delta = active_list.front().delta;
}
unlock();
return delta;
}

View File

@ -104,6 +104,17 @@ namespace etl
Inactive = 0xFFFFFFFFUL
};
};
// Timer time interval.
struct interval
{
enum
{
No_Active_Interval = 0xFFFFFFFFUL
};
typedef uint32_t type;
};
};
}

View File

@ -647,7 +647,7 @@ namespace
}
//*************************************************************************
TEST(message_timer_time_to_next)
TEST(message_timer_time_to_next_repeating)
{
etl::callback_timer<3> timer_controller;
@ -694,6 +694,38 @@ namespace
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
TEST(message_timer_time_to_next_with_has_active_timer)
{
etl::callback_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::type>(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next());
CHECK_FALSE(timer_controller.has_active_timer());
}
//*************************************************************************
class test_object
{

View File

@ -701,6 +701,38 @@ namespace
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
TEST(message_timer_time_to_next_with_has_active_timer)
{
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);
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::type>(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next());
CHECK_FALSE(timer_controller.has_active_timer());
}
//*************************************************************************
class test_object
{

View File

@ -740,6 +740,38 @@ namespace
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
TEST(message_timer_time_to_next_with_has_active_timer)
{
etl::callback_timer_interrupt<3, ScopedGuard> 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_function_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::type>(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next());
CHECK_FALSE(timer_controller.has_active_timer());
}
//*************************************************************************
class test_object
{

View File

@ -871,6 +871,43 @@ namespace
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
TEST(message_timer_time_to_next_with_has_active_timer)
{
locks.clear();
try_lock_type try_lock = try_lock_type::create<Locks, locks, &Locks::try_lock>();
lock_type lock = lock_type::create<Locks, locks, &Locks::lock>();
unlock_type unlock = unlock_type::create<Locks, locks, &Locks::unlock>();
etl::callback_timer_locked<3> timer_controller(try_lock, lock, unlock);
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_function_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::type>(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next());
CHECK_FALSE(timer_controller.has_active_timer());
}
//*************************************************************************
#if REALTIME_TEST

View File

@ -643,6 +643,40 @@ namespace
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
TEST(message_timer_time_to_next_with_has_active_timer)
{
etl::message_timer<3> timer_controller;
etl::timer::id::type id1 = timer_controller.register_timer(message1, router1, 37, etl::timer::mode::Single_Shot);
etl::timer::id::type id2 = timer_controller.register_timer(message2, router1, 23, etl::timer::mode::Single_Shot);
etl::timer::id::type id3 = timer_controller.register_timer(message3, router1, 11, etl::timer::mode::Single_Shot);
router1.clear();
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::type>(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next());
CHECK_FALSE(timer_controller.has_active_timer());
}
//*************************************************************************
#if REALTIME_TEST

View File

@ -643,6 +643,40 @@ namespace
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
TEST(message_timer_time_to_next_with_has_active_timer)
{
etl::message_timer_atomic<3, std::atomic_uint32_t> timer_controller;
etl::timer::id::type id1 = timer_controller.register_timer(message1, router1, 37, etl::timer::mode::Single_Shot);
etl::timer::id::type id2 = timer_controller.register_timer(message2, router1, 23, etl::timer::mode::Single_Shot);
etl::timer::id::type id3 = timer_controller.register_timer(message3, router1, 11, etl::timer::mode::Single_Shot);
router1.clear();
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::type>(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next());
CHECK_FALSE(timer_controller.has_active_timer());
}
//*************************************************************************
#if REALTIME_TEST

View File

@ -690,6 +690,40 @@ namespace
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
TEST(message_timer_time_to_next_with_has_active_timer)
{
etl::message_timer_interrupt<3, ScopedGuard> timer_controller;
etl::timer::id::type id1 = timer_controller.register_timer(message1, router1, 37, etl::timer::mode::Single_Shot);
etl::timer::id::type id2 = timer_controller.register_timer(message2, router1, 23, etl::timer::mode::Single_Shot);
etl::timer::id::type id3 = timer_controller.register_timer(message3, router1, 11, etl::timer::mode::Single_Shot);
router1.clear();
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::type>(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next());
CHECK_FALSE(timer_controller.has_active_timer());
}
//*************************************************************************
class RouterLog : public etl::message_router<RouterLog, Message1, Message2, Message3, Message4>
{

View File

@ -770,6 +770,45 @@ namespace
CHECK_EQUAL(4, timer_controller.time_to_next());
}
//*************************************************************************
TEST(message_timer_time_to_next_with_has_active_timer)
{
locks.clear();
try_lock_type try_lock = try_lock_type::create<Locks, locks, &Locks::try_lock>();
lock_type lock = lock_type::create<Locks, locks, &Locks::lock>();
unlock_type unlock = unlock_type::create<Locks, locks, &Locks::unlock>();
etl::message_timer_locked<3> timer_controller(try_lock, lock, unlock);
etl::timer::id::type id1 = timer_controller.register_timer(message1, router1, 37, etl::timer::mode::Single_Shot);
etl::timer::id::type id2 = timer_controller.register_timer(message2, router1, 23, etl::timer::mode::Single_Shot);
etl::timer::id::type id3 = timer_controller.register_timer(message3, router1, 11, etl::timer::mode::Single_Shot);
router1.clear();
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::type>(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next());
CHECK_FALSE(timer_controller.has_active_timer());
}
//*************************************************************************
#if REALTIME_TEST