blob: 72c9f962d9b2273418d8e256d7a4daae555b2443 [file] [log] [blame]
Patrick Venture043d3232018-08-31 10:10:53 -07001#include "timer.hpp"
2
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -06003#include <chrono>
Patrick Ventureaf6227a2018-09-11 18:08:16 -07004#include <cstring>
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -06005#include <system_error>
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -06006
7namespace phosphor
8{
9namespace hwmon
10{
11
12static std::chrono::microseconds getTime()
13{
14 using namespace std::chrono;
15 auto usec = steady_clock::now().time_since_epoch();
16 return duration_cast<microseconds>(usec);
17}
18
Patrick Venture043d3232018-08-31 10:10:53 -070019Timer::Timer(sd_event* event, std::function<void()> callback,
20 std::chrono::microseconds usec, timer::Action action) :
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -060021 event(event),
Patrick Venture043d3232018-08-31 10:10:53 -070022 callback(callback), duration(usec), action(action)
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -060023{
24 auto r = sd_event_add_time(event, &eventSource,
Patrick Venture043d3232018-08-31 10:10:53 -070025 CLOCK_MONOTONIC, // Time base
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -060026 (getTime() + usec).count(), // When to fire
Patrick Venture043d3232018-08-31 10:10:53 -070027 0, // Use default event accuracy
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -060028 timeoutHandler, // Callback handler on timeout
Patrick Venture043d3232018-08-31 10:10:53 -070029 this); // User data
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -060030 if (r < 0)
31 {
Patrick Ventureaf6227a2018-09-11 18:08:16 -070032 throw std::system_error(r, std::generic_category(), std::strerror(-r));
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -060033 }
34}
35
Patrick Venture043d3232018-08-31 10:10:53 -070036int Timer::timeoutHandler(sd_event_source* eventSource, uint64_t usec,
37 void* userData)
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -060038{
39 auto timer = static_cast<Timer*>(userData);
40
41 if (timer->getAction() == timer::ON)
42 {
43 auto r = sd_event_source_set_time(
Patrick Venture043d3232018-08-31 10:10:53 -070044 eventSource, (getTime() + timer->getDuration()).count());
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -060045 if (r < 0)
46 {
Patrick Ventureaf6227a2018-09-11 18:08:16 -070047 throw std::system_error(r, std::generic_category(),
48 std::strerror(-r));
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -060049 }
50 r = sd_event_source_set_enabled(eventSource, timer::ON);
51 if (r < 0)
52 {
Patrick Ventureaf6227a2018-09-11 18:08:16 -070053 throw std::system_error(r, std::generic_category(),
54 std::strerror(-r));
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -060055 }
56 }
57
Patrick Venture043d3232018-08-31 10:10:53 -070058 if (timer->callback)
Deepak Kodihalli6aa24d42018-03-07 01:10:03 -060059 {
60 timer->callback();
61 }
62
63 return 0;
64}
65
66} // namespace hwmon
67} // namespace phosphor