From 101b6b842bc2037d13b0e22d0511ce7d414dff74 Mon Sep 17 00:00:00 2001 From: "Costa Tsaousis (ktsaou)" Date: Thu, 2 Mar 2017 23:30:18 +0200 Subject: [PATCH] prevents usec/msec from using wrong .tv_nsec/.tv_nsec values; #1843 --- src/clocks.c | 12 ++++++++---- src/clocks.h | 30 +++++++++++++++++++++--------- src/rrd2json.c | 7 +++---- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/clocks.c b/src/clocks.c index 239b36e5..4a2c37f2 100644 --- a/src/clocks.c +++ b/src/clocks.c @@ -6,7 +6,7 @@ inline int clock_gettime(clockid_t clk_id, struct timespec *ts) { if(unlikely(gettimeofday(&tv, NULL) == -1)) return -1; ts->tv_sec = tv.tv_sec; - ts->tv_nsec = tv.tv_usec * NSEC_PER_USEC; + ts->tv_nsec = (tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC; return 0; } #endif @@ -22,7 +22,7 @@ static inline usec_t now_usec(clockid_t clk_id) { struct timespec ts; if(unlikely(clock_gettime(clk_id, &ts) == -1)) return 0; - return (usec_t)ts.tv_sec * USEC_PER_SEC + ts.tv_nsec / NSEC_PER_USEC; + return (usec_t)ts.tv_sec * USEC_PER_SEC + (ts.tv_nsec % NSEC_PER_SEC) / NSEC_PER_USEC; } static inline int now_timeval(clockid_t clk_id, struct timeval *tv) { @@ -30,7 +30,7 @@ static inline int now_timeval(clockid_t clk_id, struct timeval *tv) { if(unlikely(clock_gettime(clk_id, &ts) == -1)) return -1; tv->tv_sec = ts.tv_sec; - tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC; + tv->tv_usec = (suseconds_t)((ts.tv_nsec % NSEC_PER_SEC) / NSEC_PER_USEC); return 0; } @@ -71,7 +71,11 @@ inline int now_boottime_timeval(struct timeval *tv) { } inline usec_t timeval_usec(struct timeval *tv) { - return (usec_t)tv->tv_sec * USEC_PER_SEC + tv->tv_usec; + return (usec_t)tv->tv_sec * USEC_PER_SEC + (tv->tv_usec % USEC_PER_SEC); +} + +inline msec_t timeval_msec(struct timeval *tv) { + return (msec_t)tv->tv_sec * MSEC_PER_SEC + ((tv->tv_usec % USEC_PER_SEC) / MSEC_PER_SEC); } inline susec_t dt_usec_signed(struct timeval *now, struct timeval *old) { diff --git a/src/clocks.h b/src/clocks.h index c410a052..197b5431 100644 --- a/src/clocks.h +++ b/src/clocks.h @@ -12,15 +12,13 @@ struct timespec { typedef int clockid_t; #endif +typedef unsigned long long nsec_t; +typedef unsigned long long msec_t; typedef unsigned long long usec_t; typedef long long susec_t; typedef usec_t heartbeat_t; -#ifndef HAVE_CLOCK_GETTIME -int clock_gettime(clockid_t clk_id, struct timespec *ts); -#endif - /* Linux value is as good as any other */ #ifndef CLOCK_REALTIME #define CLOCK_REALTIME 0 @@ -32,18 +30,30 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts); #endif #ifndef CLOCK_BOOTTIME -/* fallback to CLOCK_MONOTONIC if not available */ + +#ifdef CLOCK_UPTIME +/* CLOCK_BOOTTIME falls back to CLOCK_UPTIME on FreeBSD */ +#define CLOCK_BOOTTIME CLOCK_UPTIME +#else // CLOCK_UPTIME +/* CLOCK_BOOTTIME falls back to CLOCK_MONOTONIC */ #define CLOCK_BOOTTIME CLOCK_MONOTONIC -#else +#endif // CLOCK_UPTIME + +#else // CLOCK_BOOTTIME + #ifdef HAVE_CLOCK_GETTIME #define CLOCK_BOOTTIME_IS_AVAILABLE 1 // required for /proc/uptime -#endif -#endif +#endif // HAVE_CLOCK_GETTIME + +#endif // CLOCK_BOOTTIME -#define NSEC_PER_SEC 1000000000ULL #define NSEC_PER_MSEC 1000000ULL + +#define NSEC_PER_SEC 1000000000ULL #define NSEC_PER_USEC 1000ULL + #define USEC_PER_SEC 1000000ULL +#define MSEC_PER_SEC 1000ULL #ifndef HAVE_CLOCK_GETTIME /* Fallback function for POSIX.1-2001 clock_gettime() function. @@ -94,6 +104,8 @@ extern usec_t now_boottime_usec(void); extern usec_t timeval_usec(struct timeval *ts); +extern msec_t timeval_msec(struct timeval *tv); + extern usec_t dt_usec(struct timeval *now, struct timeval *old); extern susec_t dt_usec_signed(struct timeval *now, struct timeval *old); diff --git a/src/rrd2json.c b/src/rrd2json.c index ec10e4d5..8f2ea623 100644 --- a/src/rrd2json.c +++ b/src/rrd2json.c @@ -218,12 +218,11 @@ void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb) { } // calculated_number n = (calculated_number)rd->last_collected_value * (calculated_number)(abs(rd->multiplier)) / (calculated_number)(abs(rd->divisor)); - // buffer_sprintf(wb, "%s.%s " CALCULATED_NUMBER_FORMAT " %llu\n", st->id, rd->id, n, - // (unsigned long long)((rd->last_collected_time.tv_sec * 1000) + (rd->last_collected_time.tv_usec / 1000))); + // buffer_sprintf(wb, "%s.%s " CALCULATED_NUMBER_FORMAT " %llu\n", st->id, rd->id, n, timeval_msec(&rd->last_collected_time)); buffer_sprintf(wb, "%s_%s{instance=\"%s\"} " COLLECTED_NUMBER_FORMAT " %llu\n", - chart, dimension, hostname, rd->last_collected_value, - (unsigned long long)((rd->last_collected_time.tv_sec * 1000) + (rd->last_collected_time.tv_usec / 1000))); + chart, dimension, hostname, rd->last_collected_value, timeval_msec(&rd->last_collected_time) + ); } } -- 2.39.2