From 6dda0dcd1d0eeacb3d005d6a65efb8df23b0e952 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 12 Jul 2021 15:03:54 -0700 Subject: [PATCH] [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. --- src/core/common/instance.hpp | 10 +- src/core/common/timer.cpp | 51 ++++--- src/core/common/timer.hpp | 258 ++++++++++++----------------------- 3 files changed, 124 insertions(+), 195 deletions(-) diff --git a/src/core/common/instance.hpp b/src/core/common/instance.hpp index 8dd1966ea..366804c24 100644 --- a/src/core/common/instance.hpp +++ b/src/core/common/instance.hpp @@ -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; } diff --git a/src/core/common/timer.cpp b/src/core/common/timer.cpp index ea6bdc22e..59a0ebfca 100644 --- a/src/core/common/timer.cpp +++ b/src/core/common/timer.cpp @@ -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().Add(*this); + Get().Add(*this); } void TimerMilli::FireAtIfEarlier(TimeMilli aFireTime) @@ -95,10 +104,10 @@ void TimerMilli::FireAtIfEarlier(TimeMilli aFireTime) void TimerMilli::Stop(void) { - Get().Remove(*this); + Get().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(aInstance); VerifyOrExit(otInstanceIsInitialized(aInstance)); - instance->Get().ProcessTimers(); + instance->Get().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().Add(*this); + Get().Add(*this); } void TimerMicro::Stop(void) { - Get().Remove(*this); + Get().Remove(*this); } extern "C" void otPlatAlarmMicroFired(otInstance *aInstance) @@ -225,7 +238,7 @@ extern "C" void otPlatAlarmMicroFired(otInstance *aInstance) Instance *instance = static_cast(aInstance); VerifyOrExit(otInstanceIsInitialized(aInstance)); - instance->Get().ProcessTimers(); + instance->Get().ProcessTimers(); exit: return; diff --git a/src/core/common/timer.hpp b/src/core/common/timer.hpp index 7158fb19d..b109a9721 100644 --- a/src/core/common/timer.hpp +++ b/src/core/common/timer.hpp @@ -51,8 +51,6 @@ namespace ot { -class TimerMilliScheduler; - /** * @addtogroup core-timer * @@ -69,7 +67,6 @@ class TimerMilliScheduler; */ class Timer : public InstanceLocator, public LinkedListEntry { - friend class TimerScheduler; friend class LinkedListEntry; 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 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 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 /**