mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Fixed remove for timer_active_list
Moved time to nex notifications to inside the lock regions Finished unit tests
This commit is contained in:
parent
f1d188e60c
commit
2aa0c4edb3
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user