[ntpsec commit] Repair the jitter sort in ntpfrob, and fix output mode handling.

Eric S. Raymond esr at ntpsec.org
Wed Oct 21 01:33:15 UTC 2015


Module:    ntpsec
Branch:    master
Commit:    b3c3ac409d6c932a96b4c61abfbd04d003e3beaf
Changeset: http://git.ntpsec.org/ntpsec/commit/?id=b3c3ac409d6c932a96b4c61abfbd04d003e3beaf

Author:    Eric S. Raymond <esr at thyrsus.com>
Date:      Tue Oct 20 21:31:17 2015 -0400

Repair the jitter sort in ntpfrob, and fix output mode handling.

It had a bubble sort.  In 2015!  I marvel.

---

 devel/TODO                     |  3 ---
 docs/includes/ntpfrob-body.txt | 17 +++++++++++------
 ntpfrob/jitter.c               | 32 ++++++++++++++++----------------
 ntpfrob/main.c                 | 25 ++++++++++---------------
 ntpfrob/ntpfrob.h              | 12 ++++++++++++
 ntpfrob/precision.c            |  6 ++++--
 ntpfrob/tickadj.c              |  4 +++-
 7 files changed, 56 insertions(+), 43 deletions(-)

diff --git a/devel/TODO b/devel/TODO
index 059a4d4..1e83359 100644
--- a/devel/TODO
+++ b/devel/TODO
@@ -48,9 +48,6 @@ None right now. (Sep-22 2015)
 * systime.c needs patching to put ntpdsim's hook back in place. Deferred
   until the ntpdsim build is fixed.
 
-* ntpfrob -c behaves mysteriously.  Someone with domain knowledge (probably Hal)
-  should review the code.
-
 * Fixup copyright notices.
   See Mark's message of Oct-13th.
   Subject: FLOSS license policy and copyright marking policy
diff --git a/docs/includes/ntpfrob-body.txt b/docs/includes/ntpfrob-body.txt
index b48f4bf..ff77249 100644
--- a/docs/includes/ntpfrob-body.txt
+++ b/docs/includes/ntpfrob-body.txt
@@ -5,7 +5,7 @@
 [[synop]]
 == Synopsis ==
 
-+{ntpfrob}+ [ +-A+] [ +-a+ 'tick' ] [ +-p+ 'ppsdev' ] [+-c+] [+-e+] [+-s+]
++{ntpfrob}+ [ +-A+] [ +-a+ 'tick' ] [ +-p+ 'ppsdev' ] [+-c+] [+-e+] [+-r+] [+-s+]
 
 [[descr]]
 == Description ==
@@ -23,16 +23,19 @@ utilities.
   Set the kernel variable +tick+ to the value _tick_ specifies.
 +-A+::
   Display the kernel variable +tick+.
-+-p+ 'ppsdev'::
-  Look for PPS pulses on a specified device
 +-c+::
   Compute and display clock jitter.
 +-e+::
   Measure clock precision.
-+-s+::
-  Check for stepback bug.
 +-j+::
   Report in self-describing JSON.
++-p+ 'ppsdev'::
+  Look for PPS pulses on a specified device
++-r+::
+  Raw mode.  Only applies to the jitter mode, and means the raw
+  clock samples should be emitted to stdout for postanalysis.
++-s+::
+  Check for stepback bug.
 
 [[usage]]
 == Usage ==
@@ -73,7 +76,9 @@ hardware interrupt, usually in the range 10 us-1 ms. For those systems
 with microsecond counters the jitter is dominated only by the
 operating system.
 
-The -j option is applicable to this mode.
+The -j option is applicable to this mode.  With the -r option, write
+the raw unsorted clock samples to standard output for post-analysis.
+All but the last -j or -r option before the -c mode flag is ignored
 
 === Pulse-per-second check ==
 
diff --git a/ntpfrob/jitter.c b/ntpfrob/jitter.c
index 4ec5730..782b58f 100644
--- a/ntpfrob/jitter.c
+++ b/ntpfrob/jitter.c
@@ -19,6 +19,8 @@
 
 #include "ntp_fp.h"
 
+#include "ntpfrob.h"
+
 #define NBUF	800002
 #define JAN_1970 2208988800UL		/* Unix base epoch */
 #define NSAMPLES 10
@@ -61,11 +63,16 @@ get_clocktime(
 	now->l_uf = (uint32_t)dtemp;
 }
 
-void jitter(const bool json)
+static int doublecmp(const void *a, const void *b)
+{
+    return (int)(*((double *)a) - *((double *)b));
+}
+
+void jitter(const iomode mode)
 {
 	l_fp tr;
-	int i, j;
-	double dtemp, gtod[NBUF];
+	int i;
+	double gtod[NBUF];
 
 	/*
 	 * Force pages into memory
@@ -87,24 +94,17 @@ void jitter(const bool json)
 	average = 0;
 	for (i = 0; i < NBUF - 2; i++) {
 		gtod[i] = gtod[i + 1] - gtod[i];
-		printf("%13.9f\n", gtod[i]);
+		if (mode == raw)
+			printf("%13.9f\n", gtod[i]);
 		average += gtod[i];
 	}
-
+	
 	/*
 	 * Sort the gtod array and display deciles
 	 */
-	for (i = 0; i < NBUF - 2; i++) {
-		for (j = 0; j <= i; j++) {
-			if (gtod[j] > gtod[i]) {
-				dtemp = gtod[j];
-				gtod[j] = gtod[i];
-				gtod[i] = dtemp;
-			}
-		}
-	}
+	qsort(gtod, NBUF, sizeof(gtod[0]), doublecmp);
 	average = average / (NBUF - 2);
-	if (json) {
+	if (mode == json) {
 		fprintf(stdout, "{\"Average\":%13.9f,", average);
 		fprintf(stdout, "\"First rank\":[");
 		for (i = 0; i < NSAMPLES; i++) {
@@ -121,7 +121,7 @@ void jitter(const bool json)
 		    fputs("]}\n", stdout);
 		}
 	}
-	else
+	else if (mode != raw)
 	{
 		fprintf(stdout, "Average %13.9f\n", average);
 		fprintf(stdout, "First rank\n");
diff --git a/ntpfrob/main.c b/ntpfrob/main.c
index a4fe01b..597f1df 100644
--- a/ntpfrob/main.c
+++ b/ntpfrob/main.c
@@ -8,22 +8,14 @@
 #include <stdbool.h>
 
 #include "config.h"
-
-/*
- * Our methods, one per linked module
- */
-extern void ppscheck(char *device);
-extern void tickadj(const bool json, const int tick);
-extern void jitter(const bool json);
-extern void stepback(void);
-extern void precision(const bool json);
+#include "ntpfrob.h"
 
 int
 main(int argc, char **argv)
 {
 	int ch;
-	bool json = false;
-	while ((ch = getopt(argc, argv, "a:Acejp:")) != EOF) {
+	iomode mode = plain_text;
+	while ((ch = getopt(argc, argv, "a:Acejp:r")) != EOF) {
 		switch (ch) {
 		case 'A':
 #ifdef HAVE_ADJTIMEX
@@ -35,22 +27,22 @@ main(int argc, char **argv)
 		    break;
 		case 'a':
 #ifdef HAVE_ADJTIMEX
-		    tickadj(json, atoi(optarg));
+		    tickadj(mode, atoi(optarg));
 #else
 		    fputs("ntpfrob: no adjtimex(2) call.\n", stderr);
 		    exit(0);
 #endif
 		    break;
 		case 'c':
-		    jitter(json);
+		    jitter(mode);
 		    exit(0);
 		    break;
 		case 'e':
-		    precision(json);
+		    precision(mode);
 		    exit(0);
 		    break;
 		case 'j':
-		    json = true;
+		    mode = json;
 		    break;
 		case 'p':
 #ifdef HAVE_SYS_TIMEPPS_H
@@ -60,6 +52,9 @@ main(int argc, char **argv)
 		    exit(0);
 #endif
 		    break;
+		case 'r':
+		    mode = raw;
+		    break;
 		default:
 		    fputs("ntpfrob: no mode option specified.\n", stderr);
 		    exit(1);
diff --git a/ntpfrob/ntpfrob.h b/ntpfrob/ntpfrob.h
new file mode 100644
index 0000000..e53c888
--- /dev/null
+++ b/ntpfrob/ntpfrob.h
@@ -0,0 +1,12 @@
+/*
+ * Our methods, one per linked module
+ */
+typedef enum {plain_text, raw, json} iomode;
+
+extern void ppscheck(char *device);
+extern void tickadj(const iomode mode, const int tick);
+extern void jitter(const iomode mode);
+extern void stepback(void);
+extern void precision(const iomode mode);
+
+/*end */
diff --git a/ntpfrob/precision.c b/ntpfrob/precision.c
index 29d01f2..aa5cf01 100644
--- a/ntpfrob/precision.c
+++ b/ntpfrob/precision.c
@@ -8,14 +8,16 @@
 #include <stdio.h>
 #include <stdbool.h>
 
+#include "ntpfrob.h"
+
 #define	DEFAULT_SYS_PRECISION	-99
 
 int default_get_resolution(void);
 int default_get_precision(void);
 
-void precision(const bool json)
+void precision(const iomode mode)
 {
-	if (json)
+	if (mode == json)
 		printf("{\"log2 of resolution\":%d, \"log2 of precision\":%d}\n",
 		       default_get_resolution(),
 		       default_get_precision());
diff --git a/ntpfrob/tickadj.c b/ntpfrob/tickadj.c
index 5f6e25c..7913979 100644
--- a/ntpfrob/tickadj.c
+++ b/ntpfrob/tickadj.c
@@ -17,6 +17,8 @@
 #include <unistd.h>
 #include <stdlib.h>
 
+#include "ntpfrob.h"
+
 #ifdef HAVE_ADJTIMEX
 # include <sys/time.h>	/* prerequisite on NetBSD */
 # include <sys/timex.h>
@@ -24,7 +26,7 @@
 static struct timex txc;
 #endif /* HAVE_ADJTIMEX */
 
-void tickadj(const bool json, const int newtick)
+void tickadj(const iomode mode, const int newtick)
 {
 #ifndef HAVE_ADJTIMEX
 	fputs("ntpfrob: \n", stderr);



More information about the vc mailing list