#include #include #include "timer.hpp" namespace phosphor { namespace ipmi { using namespace phosphor::logging; // Initializes the timer object void Timer::initialize() { // This can not be called more than once. if (eventSource) { throw std::runtime_error("Timer already initialized"); } // Add infinite expiration time auto r = sd_event_add_time(timeEvent, &eventSource, CLOCK_MONOTONIC, // Time base UINT64_MAX, // Expire time - way long time 0, // Use default event accuracy timeoutHandler, // Callback handler on timeout this); // User data if (r < 0) { log("Failure to set initial expiration time value", entry("ERROR=%s", strerror(-r))); throw std::runtime_error("Timer initialization failed"); } // Disable the timer for now r = setTimer(SD_EVENT_OFF); if (r < 0) { log("Failure to disable timer", entry("ERROR=%s", strerror(-r))); throw std::runtime_error("Disabling the timer failed"); } return; } /** @brief callback handler on timeout */ int Timer::timeoutHandler(sd_event_source* eventSource, uint64_t usec, void* userData) { auto timer = static_cast(userData); timer->expired = true; log("Timer expired"); return 0; } // Gets the time from steady_clock std::chrono::microseconds Timer::getTime() { using namespace std::chrono; auto usec = steady_clock::now().time_since_epoch(); return duration_cast(usec); } // Enables or disables the timer int Timer::setTimer(int action) { return sd_event_source_set_enabled(eventSource, action); } // Sets the time and arms the timer int Timer::startTimer(std::chrono::microseconds timeValue) { // Disable the timer setTimer(SD_EVENT_OFF); // Get the current MONOTONIC time and add the delta auto expireTime = getTime() + timeValue; // Set the time auto r = sd_event_source_set_time(eventSource, expireTime.count()); if (r < 0) { log("Failure to set timer", entry("ERROR=%s", strerror(-r))); return r; } // A ONESHOT timer means that when the timer goes off, // its moves to disabled state. r = setTimer(SD_EVENT_ONESHOT); if (r < 0) { log("Failure to start timer", entry("ERROR=%s", strerror(-r))); } return r; } } // namespace ipmi } // namespace phosphor