| Vishwanatha Subbanna | d27e71e | 2017-02-01 18:02:38 +0530 | [diff] [blame] | 1 | #include <chrono> | 
| Vishwanatha Subbanna | bcb7688 | 2017-01-25 16:29:43 +0530 | [diff] [blame] | 2 | #include <phosphor-logging/log.hpp> | 
|  | 3 | #include "timer.hpp" | 
|  | 4 | namespace phosphor | 
|  | 5 | { | 
|  | 6 | namespace ipmi | 
|  | 7 | { | 
|  | 8 |  | 
|  | 9 | using namespace phosphor::logging; | 
|  | 10 |  | 
|  | 11 | // Initializes the timer object | 
|  | 12 | void Timer::initialize() | 
|  | 13 | { | 
|  | 14 | // This can not be called more than once. | 
|  | 15 | if (eventSource) | 
|  | 16 | { | 
|  | 17 | throw std::runtime_error("Timer already initialized"); | 
|  | 18 | } | 
|  | 19 |  | 
|  | 20 | // Add infinite expiration time | 
|  | 21 | auto r = sd_event_add_time(timeEvent, &eventSource, | 
|  | 22 | CLOCK_MONOTONIC, // Time base | 
| Vishwanatha Subbanna | d27e71e | 2017-02-01 18:02:38 +0530 | [diff] [blame] | 23 | UINT64_MAX,      // Expire time - way long time | 
| Vishwanatha Subbanna | bcb7688 | 2017-01-25 16:29:43 +0530 | [diff] [blame] | 24 | 0,               // Use default event accuracy | 
|  | 25 | timeoutHandler,  // Callback handler on timeout | 
|  | 26 | this);           // User data | 
|  | 27 | if (r < 0) | 
|  | 28 | { | 
|  | 29 | log<level::ERR>("Failure to set initial expiration time value", | 
|  | 30 | entry("ERROR=%s", strerror(-r))); | 
|  | 31 |  | 
|  | 32 | throw std::runtime_error("Timer initialization failed"); | 
|  | 33 | } | 
|  | 34 |  | 
|  | 35 | // Disable the timer for now | 
| Vishwanatha Subbanna | d27e71e | 2017-02-01 18:02:38 +0530 | [diff] [blame] | 36 | r = setTimer(SD_EVENT_OFF); | 
| Vishwanatha Subbanna | bcb7688 | 2017-01-25 16:29:43 +0530 | [diff] [blame] | 37 | if (r < 0) | 
|  | 38 | { | 
|  | 39 | log<level::ERR>("Failure to disable timer", | 
|  | 40 | entry("ERROR=%s", strerror(-r))); | 
|  | 41 |  | 
| Vishwanatha Subbanna | d27e71e | 2017-02-01 18:02:38 +0530 | [diff] [blame] | 42 | throw std::runtime_error("Disabling the timer failed"); | 
| Vishwanatha Subbanna | bcb7688 | 2017-01-25 16:29:43 +0530 | [diff] [blame] | 43 | } | 
|  | 44 | return; | 
|  | 45 | } | 
|  | 46 |  | 
|  | 47 | /** @brief callback handler on timeout */ | 
|  | 48 | int Timer::timeoutHandler(sd_event_source* eventSource, | 
|  | 49 | uint64_t usec, void* userData) | 
|  | 50 | { | 
|  | 51 | auto timer = static_cast<Timer*>(userData); | 
|  | 52 | timer->expired = true; | 
|  | 53 |  | 
|  | 54 | log<level::INFO>("Timer expired"); | 
|  | 55 | return 0; | 
|  | 56 | } | 
|  | 57 |  | 
| Vishwanatha Subbanna | d27e71e | 2017-02-01 18:02:38 +0530 | [diff] [blame] | 58 | // Gets the time from steady_clock | 
|  | 59 | std::chrono::microseconds Timer::getTime() | 
|  | 60 | { | 
|  | 61 | using namespace std::chrono; | 
|  | 62 | auto usec = steady_clock::now().time_since_epoch(); | 
|  | 63 | return duration_cast<microseconds>(usec); | 
|  | 64 | } | 
|  | 65 |  | 
|  | 66 | // Enables or disables the timer | 
|  | 67 | int Timer::setTimer(int action) | 
|  | 68 | { | 
|  | 69 | return sd_event_source_set_enabled(eventSource, action); | 
|  | 70 | } | 
|  | 71 |  | 
|  | 72 | // Sets the time and arms the timer | 
|  | 73 | int Timer::startTimer(std::chrono::microseconds timeValue) | 
|  | 74 | { | 
|  | 75 | // Disable the timer | 
|  | 76 | setTimer(SD_EVENT_OFF); | 
|  | 77 |  | 
|  | 78 | // Get the current MONOTONIC time and add the delta | 
|  | 79 | auto expireTime = getTime() + timeValue; | 
|  | 80 |  | 
|  | 81 | // Set the time | 
|  | 82 | auto r = sd_event_source_set_time(eventSource, expireTime.count()); | 
|  | 83 | if (r < 0) | 
|  | 84 | { | 
|  | 85 | log<level::ERR>("Failure to set timer", | 
|  | 86 | entry("ERROR=%s", strerror(-r))); | 
|  | 87 | return r; | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 | // A ONESHOT timer means that when the timer goes off, | 
|  | 91 | // its moves to disabled state. | 
|  | 92 | r = setTimer(SD_EVENT_ONESHOT); | 
|  | 93 | if (r < 0) | 
|  | 94 | { | 
|  | 95 | log<level::ERR>("Failure to start timer", | 
|  | 96 | entry("ERROR=%s", strerror(-r))); | 
|  | 97 | } | 
|  | 98 | return r; | 
|  | 99 | } | 
|  | 100 |  | 
| Vishwanatha Subbanna | bcb7688 | 2017-01-25 16:29:43 +0530 | [diff] [blame] | 101 | } // namespace ipmi | 
|  | 102 | } // namespace phosphor |