From c0bbcd9f1db3af7b32ca1b1b385aa6b464d1c925 Mon Sep 17 00:00:00 2001 From: Nuno Goncalves Date: Tue, 14 Jun 2016 00:42:51 +0100 Subject: [PATCH] ntpshmmon: fix cycle Currently ntpshmmon is usually printing 2 messages per second with the default setting, (which is of 1 message per second), and as the shm server most commonly also publish 1 message per second, ntpshmmon will print duplicates. This is mostly because the code is trying to determine the message timestamp incorrectly with tvc while it should do it with tvr. This would fix the problem almost entirely for the default case. But if other cycle is selected (like 5s), then the code once again will misbehave and print a message every 2 or 3 seconds. While the code was trying to account for "missed" samples and clock skew, that is not(?) possible without accounting to a base timestamp and incrementing it by cycle steps and doing diffs on it. So this patch greatly simplifies the code, improving the behaviour, without trying to account for the previous issue, which the current code also failed to do and is most probably not required. Signed-off-by: Nuno Goncalves --- ntpshmmon.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/ntpshmmon.c b/ntpshmmon.c index 59560cd..f2d5b0f 100644 --- a/ntpshmmon.c +++ b/ntpshmmon.c @@ -31,7 +31,7 @@ int main(int argc, char **argv) time_t timeout = (time_t)INT_MAX, starttime = time(NULL); double cycle = 1.0; /* FIXME, One Sec cycle time a bad assumption */ -#define USAGE "usage: ntpshmmon [-s] [-n max] [-t timeout] [-v] [-h] [-V]\n" +#define USAGE "usage: ntpshmmon [-c cycle] [-s] [-n max] [-t timeout] [-v] [-h] [-V]\n" while ((option = getopt(argc, argv, "c:hn:st:vV")) != -1) { switch (option) { case 'c': @@ -90,19 +90,15 @@ int main(int argc, char **argv) switch(status) { case OK: - /* ntpd can slew the clock at 120% real time - * so do not lock out slightly short cycles - * use 50% of cycle time as lock out limit. - * ignore that system time may jump. */ - diff = timespec_diff_ns(shm_stat.tvc, tick[i]); - if ( (cycle * 500000000LL) <= diff) { + diff = timespec_diff_ns(shm_stat.tvr, tick[i]); + if ( diff) { /* new message available? */ printf("sample %s %ld.%09ld %ld.%09ld %ld.%09ld %d %3d\n", ntp_name(i), (long)shm_stat.tvc.tv_sec, shm_stat.tvc.tv_nsec, (long)shm_stat.tvr.tv_sec, shm_stat.tvr.tv_nsec, (long)shm_stat.tvt.tv_sec, shm_stat.tvt.tv_nsec, shm_stat.leap, shm_stat.precision); - tick[i] = shm_stat.tvc; + tick[i] = shm_stat.tvr; --nsamples; } break; @@ -125,13 +121,7 @@ int main(int argc, char **argv) } } - /* - * Even on a 1 Hz PPS, a sleep(1) may end up - * being sleep(1.1) and missing a beat. Since - * we're ignoring duplicates via timestamp, polling - * at interval < 1 sec shouldn't be a problem. - */ - (void)usleep((useconds_t)(cycle * 1000)); + (void)usleep((useconds_t)(cycle * 1000000)); } while (nsamples != 0 && time(NULL) - starttime < timeout); -- 2.7.4