[timer] declare Scheduler as nested type of Timer (#6814)

This commit refactors and simplifies the `Timer` module, mainly
declaring the corresponding `Scheduler` as a nested type of `Timer`,
`TimerMilli` or `TimerMicro` classes. It also changes the `Scheduler`
methods to be `protected` or `private` limiting access to them.
This commit is contained in:
Abtin Keshavarzian
2021-07-14 12:10:21 -07:00
committed by Jonathan Hui
parent 82cbc848fb
commit 6dda0dcd1d
3 changed files with 124 additions and 195 deletions
+5 -5
View File
@@ -333,10 +333,10 @@ private:
// Tasklet and Timer Schedulers are first to ensure other
// objects/classes can use them from their constructors.
Tasklet::Scheduler mTaskletScheduler;
TimerMilliScheduler mTimerMilliScheduler;
Tasklet::Scheduler mTaskletScheduler;
TimerMilli::Scheduler mTimerMilliScheduler;
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
TimerMicroScheduler mTimerMicroScheduler;
TimerMicro::Scheduler mTimerMicroScheduler;
#endif
#if OPENTHREAD_MTD || OPENTHREAD_FTD
@@ -950,13 +950,13 @@ template <> inline Tasklet::Scheduler &Instance::Get(void)
return mTaskletScheduler;
}
template <> inline TimerMilliScheduler &Instance::Get(void)
template <> inline TimerMilli::Scheduler &Instance::Get(void)
{
return mTimerMilliScheduler;
}
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
template <> inline TimerMicroScheduler &Instance::Get(void)
template <> inline TimerMicro::Scheduler &Instance::Get(void)
{
return mTimerMicroScheduler;
}
+32 -19
View File
@@ -41,26 +41,35 @@
namespace ot {
const TimerScheduler::AlarmApi TimerMilliScheduler::sAlarmMilliApi = {&otPlatAlarmMilliStartAt, &otPlatAlarmMilliStop,
&otPlatAlarmMilliGetNow};
const Timer::Scheduler::AlarmApi TimerMilli::Scheduler::sAlarmMilliApi = {
&otPlatAlarmMilliStartAt,
&otPlatAlarmMilliStop,
&otPlatAlarmMilliGetNow,
};
bool Timer::DoesFireBefore(const Timer &aSecondTimer, Time aNow) const
{
// Indicates whether the fire time of this timer is strictly
// before the fire time of a second given timer.
bool retval;
bool isBeforeNow = (GetFireTime() < aNow);
// Check if one timer is before `now` and the other one is not.
if ((aSecondTimer.GetFireTime() < aNow) != isBeforeNow)
{
// One timer is before `now` and the other one is not, so if this timer's fire time is before `now` then
// the second fire time would be after `now` and this timer would fire before the second timer.
// One timer is before `now` and the other one is not, so if
// this timer's fire time is before `now` then the second fire
// time would be after `now` and this timer would fire before
// the second timer.
retval = isBeforeNow;
}
else
{
// Both timers are before `now` or both are after `now`. Either way the difference is guaranteed to be less
// than `kMaxDt` so we can safely compare the fire times directly.
// Both timers are before `now` or both are after `now`. Either
// way the difference is guaranteed to be less than `kMaxDt` so
// we can safely compare the fire times directly.
retval = GetFireTime() < aSecondTimer.GetFireTime();
}
@@ -82,7 +91,7 @@ void TimerMilli::StartAt(TimeMilli aStartTime, uint32_t aDelay)
void TimerMilli::FireAt(TimeMilli aFireTime)
{
mFireTime = aFireTime;
Get<TimerMilliScheduler>().Add(*this);
Get<Scheduler>().Add(*this);
}
void TimerMilli::FireAtIfEarlier(TimeMilli aFireTime)
@@ -95,10 +104,10 @@ void TimerMilli::FireAtIfEarlier(TimeMilli aFireTime)
void TimerMilli::Stop(void)
{
Get<TimerMilliScheduler>().Remove(*this);
Get<Scheduler>().Remove(*this);
}
void TimerScheduler::Add(Timer &aTimer, const AlarmApi &aAlarmApi)
void Timer::Scheduler::Add(Timer &aTimer, const AlarmApi &aAlarmApi)
{
Timer *prev = nullptr;
Time now(aAlarmApi.AlarmGetNow());
@@ -124,7 +133,7 @@ void TimerScheduler::Add(Timer &aTimer, const AlarmApi &aAlarmApi)
}
}
void TimerScheduler::Remove(Timer &aTimer, const AlarmApi &aAlarmApi)
void Timer::Scheduler::Remove(Timer &aTimer, const AlarmApi &aAlarmApi)
{
VerifyOrExit(aTimer.IsRunning());
@@ -144,7 +153,7 @@ exit:
return;
}
void TimerScheduler::SetAlarm(const AlarmApi &aAlarmApi)
void Timer::Scheduler::SetAlarm(const AlarmApi &aAlarmApi)
{
if (mTimerList.IsEmpty())
{
@@ -162,7 +171,7 @@ void TimerScheduler::SetAlarm(const AlarmApi &aAlarmApi)
}
}
void TimerScheduler::ProcessTimers(const AlarmApi &aAlarmApi)
void Timer::Scheduler::ProcessTimers(const AlarmApi &aAlarmApi)
{
Timer *timer = mTimerList.GetHead();
@@ -189,16 +198,20 @@ extern "C" void otPlatAlarmMilliFired(otInstance *aInstance)
Instance *instance = static_cast<Instance *>(aInstance);
VerifyOrExit(otInstanceIsInitialized(aInstance));
instance->Get<TimerMilliScheduler>().ProcessTimers();
instance->Get<TimerMilli::Scheduler>().ProcessTimers();
exit:
return;
}
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
const TimerScheduler::AlarmApi TimerMicroScheduler::sAlarmMicroApi = {&otPlatAlarmMicroStartAt, &otPlatAlarmMicroStop,
&otPlatAlarmMicroGetNow};
void TimerMicro::Start(uint32_t aDelay)
const Timer::Scheduler::AlarmApi TimerMicro::Scheduler::sAlarmMicroApi = {
&otPlatAlarmMicroStartAt,
&otPlatAlarmMicroStop,
&otPlatAlarmMicroGetNow,
};
void TimerMicro::Start(uint32_t aDelay)
{
StartAt(GetNow(), aDelay);
}
@@ -212,12 +225,12 @@ void TimerMicro::StartAt(TimeMicro aStartTime, uint32_t aDelay)
void TimerMicro::FireAt(TimeMicro aFireTime)
{
mFireTime = aFireTime;
Get<TimerMicroScheduler>().Add(*this);
Get<Scheduler>().Add(*this);
}
void TimerMicro::Stop(void)
{
Get<TimerMicroScheduler>().Remove(*this);
Get<Scheduler>().Remove(*this);
}
extern "C" void otPlatAlarmMicroFired(otInstance *aInstance)
@@ -225,7 +238,7 @@ extern "C" void otPlatAlarmMicroFired(otInstance *aInstance)
Instance *instance = static_cast<Instance *>(aInstance);
VerifyOrExit(otInstanceIsInitialized(aInstance));
instance->Get<TimerMicroScheduler>().ProcessTimers();
instance->Get<TimerMicro::Scheduler>().ProcessTimers();
exit:
return;
+87 -171
View File
@@ -51,8 +51,6 @@
namespace ot {
class TimerMilliScheduler;
/**
* @addtogroup core-timer
*
@@ -69,7 +67,6 @@ class TimerMilliScheduler;
*/
class Timer : public InstanceLocator, public LinkedListEntry<Timer>
{
friend class TimerScheduler;
friend class LinkedListEntry<Timer>;
public:
@@ -120,18 +117,32 @@ public:
bool IsRunning(void) const { return (mNext != this); }
protected:
/**
* This method indicates if the fire time of this timer is strictly before the fire time of a second given timer.
*
* @param[in] aSecondTimer A reference to the second timer object.
* @param[in] aNow The current time (milliseconds or microsecond, depending on timer type).
*
* @retval TRUE If the fire time of this timer object is strictly before aTimer's fire time
* @retval FALSE If the fire time of this timer object is the same or after aTimer's fire time.
*
*/
bool DoesFireBefore(const Timer &aSecondTimer, Time aNow) const;
class Scheduler : public InstanceLocator, private NonCopyable
{
friend class Timer;
protected:
struct AlarmApi
{
void (*AlarmStartAt)(otInstance *aInstance, uint32_t aT0, uint32_t aDt);
void (*AlarmStop)(otInstance *aInstance);
uint32_t (*AlarmGetNow)(void);
};
explicit Scheduler(Instance &aInstance)
: InstanceLocator(aInstance)
{
}
void Add(Timer &aTimer, const AlarmApi &aAlarmApi);
void Remove(Timer &aTimer, const AlarmApi &aAlarmApi);
void ProcessTimers(const AlarmApi &aAlarmApi);
void SetAlarm(const AlarmApi &aAlarmApi);
LinkedList<Timer> mTimerList;
};
bool DoesFireBefore(const Timer &aSecondTimer, Time aNow) const;
void Fired(void) { mHandler(*this); }
Handler mHandler;
@@ -139,6 +150,8 @@ protected:
Timer * mNext;
};
extern "C" void otPlatAlarmMilliFired(otInstance *aInstance);
/**
* This class implements the millisecond timer.
*
@@ -146,6 +159,35 @@ protected:
class TimerMilli : public Timer
{
public:
/**
* This class implements the millisecond timer scheduler.
*
*/
class Scheduler : private Timer::Scheduler
{
friend class TimerMilli;
friend void otPlatAlarmMilliFired(otInstance *aInstance);
public:
/**
* This constructor initializes the object.
*
* @param[in] aInstance A reference to the instance object.
*
*/
explicit Scheduler(Instance &aInstance)
: Timer::Scheduler(aInstance)
{
}
private:
void Add(TimerMilli &aTimer) { Timer::Scheduler::Add(aTimer, sAlarmMilliApi); }
void Remove(TimerMilli &aTimer) { Timer::Scheduler::Remove(aTimer, sAlarmMilliApi); }
void ProcessTimers(void) { Timer::Scheduler::ProcessTimers(sAlarmMilliApi); }
static const AlarmApi sAlarmMilliApi;
};
/**
* This constructor creates a millisecond timer instance.
*
@@ -245,120 +287,9 @@ private:
void *mContext;
};
/**
* This class implements the base timer scheduler.
*
*/
class TimerScheduler : public InstanceLocator, private NonCopyable
{
friend class Timer;
protected:
/**
* The Alarm APIs definition
*
*/
struct AlarmApi
{
void (*AlarmStartAt)(otInstance *aInstance, uint32_t aT0, uint32_t aDt);
void (*AlarmStop)(otInstance *aInstance);
uint32_t (*AlarmGetNow)(void);
};
/**
* This constructor initializes the object.
*
* @param[in] aInstance A reference to the instance object.
*
*/
explicit TimerScheduler(Instance &aInstance)
: InstanceLocator(aInstance)
{
}
/**
* This method adds a timer instance to the timer scheduler.
*
* @param[in] aTimer A reference to the timer instance.
* @param[in] aAlarmApi A reference to the Alarm APIs.
*
*/
void Add(Timer &aTimer, const AlarmApi &aAlarmApi);
/**
* This method removes a timer instance to the timer scheduler.
*
* @param[in] aTimer A reference to the timer instance.
* @param[in] aAlarmApi A reference to the Alarm APIs.
*
*/
void Remove(Timer &aTimer, const AlarmApi &aAlarmApi);
/**
* This method processes the running timers.
*
* @param[in] aAlarmApi A reference to the Alarm APIs.
*
*/
void ProcessTimers(const AlarmApi &aAlarmApi);
/**
* This method sets the platform alarm based on timer at front of the list.
*
* @param[in] aAlarmApi A reference to the Alarm APIs.
*
*/
void SetAlarm(const AlarmApi &aAlarmApi);
LinkedList<Timer> mTimerList;
};
/**
* This class implements the millisecond timer scheduler.
*
*/
class TimerMilliScheduler : public TimerScheduler
{
public:
/**
* This constructor initializes the object.
*
* @param[in] aInstance A reference to the instance object.
*
*/
explicit TimerMilliScheduler(Instance &aInstance)
: TimerScheduler(aInstance)
{
}
/**
* This method adds a timer instance to the timer scheduler.
*
* @param[in] aTimer A reference to the timer instance.
*
*/
void Add(TimerMilli &aTimer) { TimerScheduler::Add(aTimer, sAlarmMilliApi); }
/**
* This method removes a timer instance to the timer scheduler.
*
* @param[in] aTimer A reference to the timer instance.
*
*/
void Remove(TimerMilli &aTimer) { TimerScheduler::Remove(aTimer, sAlarmMilliApi); }
/**
* This method processes the running timers.
*
*/
void ProcessTimers(void) { TimerScheduler::ProcessTimers(sAlarmMilliApi); }
private:
static const AlarmApi sAlarmMilliApi;
};
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
class TimerMicroScheduler;
extern "C" void otPlatAlarmMicroFired(otInstance *aInstance);
/**
* This class implements the microsecond timer.
@@ -367,6 +298,35 @@ class TimerMicroScheduler;
class TimerMicro : public Timer
{
public:
/**
* This class implements the microsecond timer scheduler.
*
*/
class Scheduler : private Timer::Scheduler
{
friend class TimerMicro;
friend void otPlatAlarmMicroFired(otInstance *aInstance);
public:
/**
* This constructor initializes the object.
*
* @param[in] aInstance A reference to the instance object.
*
*/
explicit Scheduler(Instance &aInstance)
: Timer::Scheduler(aInstance)
{
}
private:
void Add(TimerMicro &aTimer) { Timer::Scheduler::Add(aTimer, sAlarmMicroApi); }
void Remove(TimerMicro &aTimer) { Timer::Scheduler::Remove(aTimer, sAlarmMicroApi); }
void ProcessTimers(void) { Timer::Scheduler::ProcessTimers(sAlarmMicroApi); }
static const AlarmApi sAlarmMicroApi;
};
/**
* This constructor creates a timer instance.
*
@@ -418,50 +378,6 @@ public:
*/
static TimeMicro GetNow(void) { return Time(otPlatAlarmMicroGetNow()); }
};
/**
* This class implements the microsecond timer scheduler.
*
*/
class TimerMicroScheduler : public TimerScheduler
{
public:
/**
* This constructor initializes the object.
*
* @param[in] aInstance A reference to the instance object.
*
*/
explicit TimerMicroScheduler(Instance &aInstance)
: TimerScheduler(aInstance)
{
}
/**
* This method adds a timer instance to the timer scheduler.
*
* @param[in] aTimer A reference to the timer instance.
*
*/
void Add(TimerMicro &aTimer) { TimerScheduler::Add(aTimer, sAlarmMicroApi); }
/**
* This method removes a timer instance to the timer scheduler.
*
* @param[in] aTimer A reference to the timer instance.
*
*/
void Remove(TimerMicro &aTimer) { TimerScheduler::Remove(aTimer, sAlarmMicroApi); }
/**
* This method processes the running timers.
*
*/
void ProcessTimers(void) { TimerScheduler::ProcessTimers(sAlarmMicroApi); }
private:
static const AlarmApi sAlarmMicroApi;
};
#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
/**