@cryptotaxi247 / netdata-1 / commits / 09db66cad

fix clock resolution detection (#16720)

* fix clock resolution detection * print the delta * make sure the resolution is usec_t * use defines for default and max resolution * fixed wrong calculation

Costa Tsaousis committed Jan 3, 2024 at 18:44 UTC 09db66cade4360b245cdc2f266bc07903938dba1
1 file changed +28 -15
libnetdata/clocks/clocks.c
+28 -15
@@ -7,8 +7,14 @@
7 static clockid_t clock_boottime_to_use = CLOCK_MONOTONIC;
8 static clockid_t clock_monotonic_to_use = CLOCK_MONOTONIC;
9
10 -usec_t clock_monotonic_resolution = 1000;
11 -usec_t clock_realtime_resolution = 1000;
10 +// the default clock resolution is 1ms
11 +#define DEFAULT_CLOCK_RESOLUTION_UT ((usec_t)0 * USEC_PER_SEC + (usec_t)1 * USEC_PER_MS)
12 +
13 +// the max clock resolution is 10ms
14 +#define MAX_CLOCK_RESOLUTION_UT ((usec_t)0 * USEC_PER_SEC + (usec_t)10 * USEC_PER_MS)
15 +
16 +usec_t clock_monotonic_resolution = DEFAULT_CLOCK_RESOLUTION_UT;
17 +usec_t clock_realtime_resolution = DEFAULT_CLOCK_RESOLUTION_UT;
18
19 #ifndef HAVE_CLOCK_GETTIME
20 inline int clock_gettime(clockid_t clk_id __maybe_unused, struct timespec *ts) {
@@ -50,9 +56,24 @@ static void test_clock_boottime(void) {
56 }
57
58 static usec_t get_clock_resolution(clockid_t clock) {
53 - struct timespec ts;
54 - clock_getres(clock, &ts);
55 - return ts.tv_sec * USEC_PER_SEC + ts.tv_nsec * NSEC_PER_USEC;
59 + struct timespec ts = { 0 };
60 +
61 + if(clock_getres(clock, &ts) == 0) {
62 + usec_t ret = (usec_t)ts.tv_sec * USEC_PER_SEC + (usec_t)ts.tv_nsec / NSEC_PER_USEC;
63 + if(!ret && ts.tv_nsec > 0 && ts.tv_nsec < NSEC_PER_USEC)
64 + return (usec_t)1;
65 +
66 + else if(ret > MAX_CLOCK_RESOLUTION_UT) {
67 + nd_log(NDLS_DAEMON, NDLP_ERR, "clock_getres(%d) returned %"PRIu64" usec is out of range, using defaults for clock resolution.", (int)clock, ret);
68 + return DEFAULT_CLOCK_RESOLUTION_UT;
69 + }
70 +
71 + return ret;
72 + }
73 + else {
74 + nd_log(NDLS_DAEMON, NDLP_ERR, "clock_getres(%d) failed, using defaults for clock resolution.", (int)clock);
75 + return DEFAULT_CLOCK_RESOLUTION_UT;
76 + }
77 }
78
79 // perform any initializations required for clocks
@@ -66,14 +87,6 @@ void clocks_init(void) {
87
88 clock_monotonic_resolution = get_clock_resolution(clock_monotonic_to_use);
89 clock_realtime_resolution = get_clock_resolution(CLOCK_REALTIME);
69 -
70 - // if for any reason these are zero, netdata will crash
71 - // since we use them as modulo to calculations
72 - if(!clock_realtime_resolution)
73 - clock_realtime_resolution = 1000;
74 -
75 - if(!clock_monotonic_resolution)
76 - clock_monotonic_resolution = 1000;
90 }
91
92 inline time_t now_sec(clockid_t clk_id) {
@@ -91,7 +104,7 @@ inline usec_t now_usec(clockid_t clk_id) {
104 netdata_log_error("clock_gettime(%d, &timespec) failed.", clk_id);
105 return 0;
106 }
94 - return (usec_t)ts.tv_sec * USEC_PER_SEC + (ts.tv_nsec % NSEC_PER_SEC) / NSEC_PER_USEC;
107 + return (usec_t)ts.tv_sec * USEC_PER_SEC + (usec_t)(ts.tv_nsec % NSEC_PER_SEC) / NSEC_PER_USEC;
108 }
109
110 inline int now_timeval(clockid_t clk_id, struct timeval *tv) {
@@ -279,7 +292,7 @@ void heartbeat_statistics(usec_t *min_ptr, usec_t *max_ptr, usec_t *average_ptr,
292
293 inline void heartbeat_init(heartbeat_t *hb) {
294 hb->realtime = 0ULL;
282 - hb->randomness = 250 * USEC_PER_MS + ((now_realtime_usec() * clock_realtime_resolution) % (250 * USEC_PER_MS));
295 + hb->randomness = (usec_t)250 * USEC_PER_MS + ((usec_t)(now_realtime_usec() * clock_realtime_resolution) % (250 * USEC_PER_MS));
296 hb->randomness -= (hb->randomness % clock_realtime_resolution);
297
298 netdata_mutex_lock(&heartbeat_alignment_mutex);