Add a Timer class
The class provides for a timer, callback invocation on timer expiry, and
timer control/cleanup. This will be used in subsequent commits.
Change-Id: Ieb04e5ec76a1023efa2c3f5c5b88f03e9819c3eb
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/timer.cpp b/timer.cpp
new file mode 100644
index 0000000..973b012
--- /dev/null
+++ b/timer.cpp
@@ -0,0 +1,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