summaryrefslogtreecommitdiffstats
path: root/timer.cpp
blob: 973b012f6a4a3084dec0de2c9a0291522177e3da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <chrono>
#include <system_error>
#include <string.h>
#include "timer.hpp"

namespace phosphor
{
namespace hwmon
{

static std::chrono::microseconds getTime()
{
    using namespace std::chrono;
    auto usec = steady_clock::now().time_since_epoch();
    return duration_cast<microseconds>(usec);
}

Timer::Timer(sd_event* event,
             std::function<void()> callback,
             std::chrono::microseconds usec,
             timer::Action action):
    event(event),
    callback(callback),
    duration(usec),
    action(action)
{
    auto r = sd_event_add_time(event, &eventSource,
                               CLOCK_MONOTONIC, // Time base
                               (getTime() + usec).count(), // When to fire
                               0, // Use default event accuracy
                               timeoutHandler, // Callback handler on timeout
                               this); // User data
    if (r < 0)
    {
        throw std::system_error(r, std::generic_category(), strerror(-r));
    }
}

int Timer::timeoutHandler(sd_event_source* eventSource,
                          uint64_t usec, void* userData)
{
    auto timer = static_cast<Timer*>(userData);

    if (timer->getAction() == timer::ON)
    {
        auto r = sd_event_source_set_time(
                     eventSource, (getTime() + timer->getDuration()).count());
        if (r < 0)
        {
            throw std::system_error(r, std::generic_category(), strerror(-r));
        }
        r = sd_event_source_set_enabled(eventSource, timer::ON);
        if (r < 0)
        {
            throw std::system_error(r, std::generic_category(), strerror(-r));
        }
    }

    if(timer->callback)
    {
        timer->callback();
    }

    return 0;
}

} // namespace hwmon
} // namespace phosphor
OpenPOWER on IntegriCloud