]> arthur.barton.de Git - netdata.git/commitdiff
introduce heartbeat API using monotonic clock
authorRémi Lefèvre <remi.lefevre@parrot.com>
Tue, 13 Dec 2016 15:12:23 +0000 (16:12 +0100)
committerRémi Lefèvre <remi.lefevre@parrot.com>
Mon, 23 Jan 2017 16:17:25 +0000 (17:17 +0100)
Signed-off-by: Rémi Lefèvre <remi.lefevre@parrot.com>
src/clocks.c
src/clocks.h

index c90a07c2f5e8027d41fe782dd2c77533e43de037..f8dc9b628342072bf4ca2eeecb4107205b5f49f1 100644 (file)
@@ -71,3 +71,38 @@ inline usec_t dt_usec(struct timeval *now, struct timeval *old) {
     usec_t ts2 = timeval_usec(old);
     return (ts1 > ts2) ? (ts1 - ts2) : (ts2 - ts1);
 }
+
+inline void heartbeat_init(heartbeat_t *hb)
+{
+    *hb = 0ULL;
+}
+
+usec_t heartbeat_next(heartbeat_t *hb, usec_t tick)
+{
+    heartbeat_t now = now_monotonic_usec();
+    usec_t next = now - (now % tick) + tick;
+
+    while(now < next) {
+        sleep_usec(next - now);
+        now = now_monotonic_usec();
+    }
+
+    if(likely(*hb != 0ULL)) {
+        usec_t dt = now - *hb;
+        *hb = now;
+        if(unlikely(dt / tick > 1))
+            error("heartbeat missed between %llu usec and %llu usec", *hb, now);
+        return dt;
+    }
+    else {
+        *hb = now;
+        return 0ULL;
+    }
+}
+
+inline usec_t heartbeat_dt_usec(heartbeat_t *hb)
+{
+    if(!*hb)
+        return 0ULL;
+    return now_monotonic_usec() - *hb;
+}
index c1b8e70179ec93acda3025e0afa0e3163e03d290..39c0436f8327b4a86df06339e04b53a3fcddec2e 100644 (file)
@@ -12,6 +12,10 @@ struct timespec {
 typedef int clockid_t;
 #endif
 
+typedef unsigned long long usec_t;
+
+typedef usec_t heartbeat_t;
+
 #ifndef HAVE_CLOCK_GETTIME
 int clock_gettime(clockid_t clk_id, struct timespec *ts);
 #endif
@@ -35,8 +39,6 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts);
 #endif
 #endif
 
-typedef unsigned long long usec_t;
-
 #define NSEC_PER_SEC    1000000000ULL
 #define NSEC_PER_MSEC   1000000ULL
 #define NSEC_PER_USEC   1000ULL
@@ -89,4 +91,14 @@ extern usec_t now_boottime_usec(void);
 extern usec_t timeval_usec(struct timeval *ts);
 extern usec_t dt_usec(struct timeval *now, struct timeval *old);
 
+extern void heartbeat_init(heartbeat_t *hb);
+
+/* Sleeps until next multiple of tick using monotonic clock.
+ * Returns elapsed time in microseconds since previous heartbeat
+ */
+extern usec_t heartbeat_next(heartbeat_t *hb, usec_t tick);
+
+/* Returns elapsed time in microseconds since last heartbeat */
+extern usec_t heartbeat_dt_usec(heartbeat_t *hb);
+
 #endif /* NETDATA_CLOCKS_H */