blob: f1887fd214aebb20a6d0d7374c656b889b0f294f [file] [log] [blame]
Patrick Venture0b02be92018-08-31 11:55:55 -07001#include "timer.hpp"
2
Vishwanatha Subbannad27e71e2017-02-01 18:02:38 +05303#include <chrono>
Vishwanatha Subbannabcb76882017-01-25 16:29:43 +05304#include <phosphor-logging/log.hpp>
Vishwanatha Subbannabcb76882017-01-25 16:29:43 +05305namespace phosphor
6{
7namespace ipmi
8{
9
10using namespace phosphor::logging;
11
12// Initializes the timer object
13void Timer::initialize()
14{
15 // This can not be called more than once.
16 if (eventSource)
17 {
18 throw std::runtime_error("Timer already initialized");
19 }
20
21 // Add infinite expiration time
22 auto r = sd_event_add_time(timeEvent, &eventSource,
23 CLOCK_MONOTONIC, // Time base
Vishwanatha Subbannad27e71e2017-02-01 18:02:38 +053024 UINT64_MAX, // Expire time - way long time
Vishwanatha Subbannabcb76882017-01-25 16:29:43 +053025 0, // Use default event accuracy
26 timeoutHandler, // Callback handler on timeout
27 this); // User data
28 if (r < 0)
29 {
30 log<level::ERR>("Failure to set initial expiration time value",
Patrick Venture0b02be92018-08-31 11:55:55 -070031 entry("ERROR=%s", strerror(-r)));
Vishwanatha Subbannabcb76882017-01-25 16:29:43 +053032
33 throw std::runtime_error("Timer initialization failed");
34 }
35
36 // Disable the timer for now
Vishwanatha Subbannad27e71e2017-02-01 18:02:38 +053037 r = setTimer(SD_EVENT_OFF);
Vishwanatha Subbannabcb76882017-01-25 16:29:43 +053038 if (r < 0)
39 {
40 log<level::ERR>("Failure to disable timer",
Patrick Venture0b02be92018-08-31 11:55:55 -070041 entry("ERROR=%s", strerror(-r)));
Vishwanatha Subbannabcb76882017-01-25 16:29:43 +053042
Vishwanatha Subbannad27e71e2017-02-01 18:02:38 +053043 throw std::runtime_error("Disabling the timer failed");
Vishwanatha Subbannabcb76882017-01-25 16:29:43 +053044 }
45 return;
46}
47
48/** @brief callback handler on timeout */
Patrick Venture0b02be92018-08-31 11:55:55 -070049int Timer::timeoutHandler(sd_event_source* eventSource, uint64_t usec,
50 void* userData)
Vishwanatha Subbannabcb76882017-01-25 16:29:43 +053051{
52 auto timer = static_cast<Timer*>(userData);
53 timer->expired = true;
54
Ratan Gupta32cbd652018-03-07 16:03:53 +053055 log<level::INFO>("Timer expired");
Andrew Geissler8622f692017-04-02 18:19:00 -050056 // Call optional user call back function if available
Patrick Venture0b02be92018-08-31 11:55:55 -070057 if (timer->userCallBack)
Andrew Geissler8622f692017-04-02 18:19:00 -050058 {
59 timer->userCallBack();
60 }
61
Ratan Gupta32cbd652018-03-07 16:03:53 +053062 sd_event_source_set_enabled(eventSource, SD_EVENT_OFF);
Vishwanatha Subbannabcb76882017-01-25 16:29:43 +053063 return 0;
64}
65
Vishwanatha Subbannad27e71e2017-02-01 18:02:38 +053066// Gets the time from steady_clock
67std::chrono::microseconds Timer::getTime()
68{
69 using namespace std::chrono;
70 auto usec = steady_clock::now().time_since_epoch();
71 return duration_cast<microseconds>(usec);
72}
73
74// Enables or disables the timer
75int Timer::setTimer(int action)
76{
77 return sd_event_source_set_enabled(eventSource, action);
78}
79
80// Sets the time and arms the timer
81int Timer::startTimer(std::chrono::microseconds timeValue)
82{
83 // Disable the timer
84 setTimer(SD_EVENT_OFF);
Ratan Gupta32cbd652018-03-07 16:03:53 +053085 expired = false;
Vishwanatha Subbannad27e71e2017-02-01 18:02:38 +053086
87 // Get the current MONOTONIC time and add the delta
88 auto expireTime = getTime() + timeValue;
89
90 // Set the time
91 auto r = sd_event_source_set_time(eventSource, expireTime.count());
92 if (r < 0)
93 {
94 log<level::ERR>("Failure to set timer",
Patrick Venture0b02be92018-08-31 11:55:55 -070095 entry("ERROR=%s", strerror(-r)));
Vishwanatha Subbannad27e71e2017-02-01 18:02:38 +053096 return r;
97 }
98
99 // A ONESHOT timer means that when the timer goes off,
100 // its moves to disabled state.
101 r = setTimer(SD_EVENT_ONESHOT);
102 if (r < 0)
103 {
104 log<level::ERR>("Failure to start timer",
Patrick Venture0b02be92018-08-31 11:55:55 -0700105 entry("ERROR=%s", strerror(-r)));
Vishwanatha Subbannad27e71e2017-02-01 18:02:38 +0530106 }
107 return r;
108}
109
Vishwanatha Subbannabcb76882017-01-25 16:29:43 +0530110} // namespace ipmi
111} // namespace phosphor