From 2de67cf4d19e2e433e1ea56583e0d5ae043b3d79 Mon Sep 17 00:00:00 2001 From: Matt Spinler Date: Thu, 27 Apr 2017 11:07:53 -0500 Subject: phosphor-fan: Create timer class This class can be used to call an arbitrary function after a certain amount of time, which is set in microseconds. Change-Id: Ifd65bbf0c3482db4e37efc3b1ccc868e62fa0afa Signed-off-by: Matt Spinler --- timer.hpp | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 timer.hpp (limited to 'timer.hpp') diff --git a/timer.hpp b/timer.hpp new file mode 100644 index 0000000..ea28176 --- /dev/null +++ b/timer.hpp @@ -0,0 +1,178 @@ +#pragma once + +#include +#include +#include +#include + +namespace phosphor +{ +namespace fan +{ +namespace util +{ + +struct EventSourceDeleter +{ + void operator()(sd_event_source* eventSource) const + { + sd_event_source_unref(eventSource); + } +}; + +using EventSourcePtr = std::unique_ptr; + +using EventPtr = std::shared_ptr; + +/** + * @class Timer + * + * This class implements a simple timer that runs an arbitrary + * function on expiration. The timeout value is set in microseconds. + * It can be stopped while it is running, and queried to see if it is + * running. + * + * If started with the 'repeating' argument, it will keep calling the + * callback function every microseconds. If started with the + * 'oneshot' argument, it will just call the callback function one time. + * + * It needs an sd_event loop to function. + */ +class Timer +{ + public: + + enum class TimerType + { + oneshot, + repeating + }; + + Timer() = delete; + Timer(const Timer&) = delete; + Timer& operator=(const Timer&) = delete; + Timer(Timer&&) = default; + Timer& operator=(Timer&&) = default; + + /** + * @brief Constructs timer object + * + * @param[in] events - sd_event pointer, previously created + * @param[in] callbackFunc - The function to call on timer expiration + */ + Timer(EventPtr& events, + std::function callbackFunc); + + /** + * @brief Destructor + */ + ~Timer(); + + /** + * @brief Starts the timer + * + * The input is an offset from the current steady clock. + * + * @param[in] usec - the timeout value in microseconds + * @param[in] type - either a oneshot, or repeating + */ + void start(std::chrono::microseconds usec, + TimerType type = TimerType::oneshot); + + /** + * @brief Stop the timer + */ + void stop(); + + /** + * @brief Returns true if the timer is running + */ + bool running(); + + /** + * @brief Returns the timeout value + * + * @return - the last value sent in via start(). + * + * Could be used to restart the timer with the same + * timeout. i.e. start(getTimeout()); + */ + inline auto getTimeout() const + { + return timeout; + } + + /** + * @brief Returns the timer type + */ + inline auto getType() const + { + return type; + } + + private: + + /** + * @brief Callback function when timer goes off + * + * Calls the callback function passed in by the user. + * + * @param[in] eventSource - Source of the event + * @param[in] usec - time in micro seconds + * @param[in] userData - User data pointer + */ + static int timeoutHandler(sd_event_source* eventSource, + uint64_t usec, void* userData); + + /** + * @brief Gets the current time from the steady clock + */ + std::chrono::microseconds getTime(); + + /** + * @brief Wrapper around sd_event_source_set_enabled + * + * @param[in] action - either SD_EVENT_OFF, SD_EVENT_ON, + * or SD_EVENT_ONESHOT + */ + void setTimer(int action); + + + /** + * @brief Sets the expiration time for the timer + * + * Sets it to timeout microseconds in the future + */ + void setTimeout(); + + /** + * @brief The sd_event structure + */ + EventPtr timeEvent; + + /** + * @brief Source of events + */ + EventSourcePtr eventSource; + + /** + * @brief Either 'repeating' or 'oneshot' + */ + TimerType type = TimerType::oneshot; + + /** + * @brief The function to call when the timer expires + */ + std::function callback; + + /** + * @brief What the timer was set to run for + * + * Not cleared on timer expiration + */ + std::chrono::microseconds timeout; +}; + +} +} +} -- cgit v1.2.1