[Git][NTPsec/ntpsec][master] Add clockstats line to ATOM/PPS driver

Hal Murray gitlab at mg.gitlab.com
Tue Dec 22 02:32:03 UTC 2015


Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
2807ed51 by Hal Murray at 2015-12-21T18:31:18Z
Add clockstats line to ATOM/PPS driver

- - - - -


4 changed files:

- docs/driver22.txt
- include/refclock_atom.h
- ntpd/ntp_refclock.c
- ntpd/refclock_atom.c


Changes:

=====================================
docs/driver22.txt
=====================================
--- a/docs/driver22.txt
+++ b/docs/driver22.txt
@@ -123,6 +123,35 @@ synchronization without needing the Internet at all.
   Record a timestamp once for each second if 1. Useful for constructing
   Allan deviation plots.
 
+== Clockstats  ==
+
+If clockstats is enabled, the driver will log a few counters.  Examples:
+
+----------------------------------------------------------------------------
+57378 3313.351 127.127.22.0 423681 64 0 0 0
+57378 3377.352 127.127.22.0 423745 64 0 0 0
+57378 3441.352 127.127.22.0 423809 64 0 0 0
+57378 3505.351 127.127.22.0 423873 64 0 0 0
+----------------------------------------------------------------------------
+
+.Clockstats
+[cols="10%,20%,70%",options="header"]
+|=============================================================================
+|Column|Sample          |Meaning
+|1     |57378           |MJD
+|2     |3505.351        |Time of day in seconds
+|3     |127.127.22.0    |IP Address from server config line
+|4     |423873          |Total number of PPS pulses the kernel has seen
+|5     |64              |Number of PPS pulses the driver processed
+                         This should be the difference between col 4 and
+                         col 4 from the previous line
+|6     |0               |ntpd doesn't know the time yet
+|7     |0               |Error from Kernel
+|8     |0               |Number of times there was no pulse ready
+|=============================================================================
+
+
+
 == Additional Information ==
 
 link:refclock.html[Reference Clock Drivers]
@@ -142,3 +171,4 @@ David L. Mills <mills at udel.edu>
 '''''
 
 include::includes/footer.txt[]
+


=====================================
include/refclock_atom.h
=====================================
--- a/include/refclock_atom.h
+++ b/include/refclock_atom.h
@@ -1,15 +1,22 @@
 /*
  * Definitions for the atom driver and its friends
  */
-#undef NANOSECOND	/* some systems define it differently */
-#define NANOSECOND	1000000000 /* one second (ns) */
 
 struct refclock_atom {
 	pps_handle_t handle;
 	pps_params_t pps_params;
 	struct timespec ts;
+	unsigned long sequence;
 };
 
+typedef enum {
+  PPS_OK,
+  PPS_SETUP,  /* PPS not setup */
+  PPS_KERNEL, /* PPS error from kernel */
+  PPS_NREADY  /* PPS not ready */
+} pps_status;
+
 extern	bool	refclock_ppsapi(int, struct refclock_atom *);
 extern	bool	refclock_params(int, struct refclock_atom *);
-extern	bool	refclock_pps(struct peer *, struct refclock_atom *, int);
+extern  pps_status refclock_pps(struct peer *, struct refclock_atom *, int);
+


=====================================
ntpd/ntp_refclock.c
=====================================
--- a/ntpd/ntp_refclock.c
+++ b/ntpd/ntp_refclock.c
@@ -65,7 +65,7 @@ bool	cal_enable;		/* enable refclock calibrate */
  * Forward declarations
  */
 static int refclock_cmpl_fp (const void *, const void *);
-static int refclock_sample (struct refclockproc *);
+static int refclock_sample (struct peer *);
 static bool refclock_ioctl(int, u_int);
 
 
@@ -443,12 +443,14 @@ refclock_process(
  */
 static int
 refclock_sample(
-	struct refclockproc *pp		/* refclock structure pointer */
+	struct peer *peer               /* peer structure pointer */
 	)
 {
+	struct  refclockproc *pp = peer->procptr;
 	size_t	i, j, k, m, n;
 	double	off[MAXSTAGE];
-	double	offset;
+	double	offset, std_dev;
+	double	mean_all, std_dev_all;
 
 	/*
 	 * Copy the raw offsets and sort into ascending order. Don't do
@@ -492,6 +494,26 @@ refclock_sample(
 	}
 	pp->offset /= m;
 	pp->jitter = max(SQRT(pp->jitter / m), LOGTOD(sys_precision));
+
+	std_dev = 0;
+	for (k = i; k < j; k++)
+	    std_dev += SQUARE(off[k] - pp->offset);
+	std_dev = SQRT(std_dev / m);
+
+	mean_all = 0;
+	for (k = 0; k < n; k++)
+	    mean_all += off[k];
+	mean_all /= n;
+	std_dev_all = 0;
+	for (k = 0; k < n; k++)
+	    std_dev_all += SQUARE(off[k] - mean_all);
+	std_dev_all = SQRT(std_dev_all / n);
+
+	record_ref_stats(&peer->srcadr, n, i, j-1,
+	    off[0], off[i], pp->offset, off[j-1], off[n-1],
+	    pp->jitter, std_dev, std_dev_all);
+
+
 #ifdef DEBUG
 	if (debug)
 		printf(
@@ -545,7 +567,7 @@ refclock_receive(
 	peer->aorg = pp->lastrec;
 	peer->rootdisp = pp->disp;
 	get_systime(&peer->dst);
-	if (!refclock_sample(pp))
+	if (!refclock_sample(peer))
 		return;
 
 	clock_filter(peer, pp->offset, 0., pp->jitter);
@@ -1169,7 +1191,7 @@ refclock_params(
  * timestamp from the kernel and saves the sign-extended fraction in
  * a circular buffer for processing at the next poll event.
  */
-bool
+pps_status
 refclock_pps(
 	struct peer *peer,		/* peer structure pointer */
 	struct refclock_atom *ap,	/* atom structure pointer */
@@ -1190,11 +1212,11 @@ refclock_pps(
 	 */ 
 	pp = peer->procptr;
 	if (ap->handle == 0)
-		return false;
+		return PPS_SETUP;
 
 	if (ap->pps_params.mode == 0 && sys_leap != LEAP_NOTINSYNC) {
 		if (refclock_params(pp->sloppyclockflag, ap) < 1)
-			return false;
+			return PPS_SETUP;
 	}
 	timeout.tv_sec = 0;
 	timeout.tv_nsec = 0;
@@ -1202,18 +1224,26 @@ refclock_pps(
 	if (time_pps_fetch(ap->handle, PPS_TSFMT_TSPEC, &pps_info,
 	    &timeout) < 0) {
 		refclock_report(peer, CEVNT_FAULT);
-		return false;
+		return PPS_KERNEL;
 	}
 	timeout = ap->ts;
-	if (ap->pps_params.mode & PPS_CAPTUREASSERT)
+	if (ap->pps_params.mode & PPS_CAPTUREASSERT) {
 		ap->ts = pps_info.assert_timestamp;
-	else if (ap->pps_params.mode & PPS_CAPTURECLEAR)
+		ap->sequence = pps_info.assert_sequence;
+	}
+	else if (ap->pps_params.mode & PPS_CAPTURECLEAR) {
 		ap->ts = pps_info.clear_timestamp;
+		ap->sequence = pps_info.clear_sequence;
+	}
 	else
-		return false;
+		return PPS_NREADY;
 
+	/* Check for duplicates.
+	 * Sequence number might not be implemented.
+	 * saved (above) for debugging.
+	 */
 	if (0 == memcmp(&timeout, &ap->ts, sizeof(timeout)))
-		return false;
+		return PPS_NREADY;
 
 	/*
 	 * Convert to signed fraction offset and stuff in median filter.
@@ -1229,7 +1259,7 @@ refclock_pps(
 		printf("refclock_pps: %lu %f %f\n", current_time,
 		    dtemp, pp->fudgetime1);
 #endif
-	return true;
+	return PPS_OK;
 }
 #endif /* HAVE_PPSAPI */
 #endif /* REFCLOCK */


=====================================
ntpd/refclock_atom.c
=====================================
--- a/ntpd/refclock_atom.c
+++ b/ntpd/refclock_atom.c
@@ -84,6 +84,10 @@
 struct ppsunit {
 	struct refclock_atom atom; /* atom structure pointer */
 	int	fddev;		/* file descriptor */
+	int	pcount;		/* PPS samples added to FIFO */
+	int	scount;		/* PPS not setup */
+	int	kcount;		/* PPS error from kernel */
+	int	rcount;		/* PPS not ready */
 };
 
 /*
@@ -183,16 +187,31 @@ atom_timer(
 	struct peer *peer	/* peer structure pointer */
 	)
 {
-	struct ppsunit *up;
-	struct refclockproc *pp;
-	char	tbuf[80];
+	struct	ppsunit *up;
+	struct	refclockproc *pp;
+	pps_status rc;
 
 	UNUSED_ARG(unit);
 
 	pp = peer->procptr;
 	up = pp->unitptr;
-	if (refclock_pps(peer, &up->atom, pp->sloppyclockflag) <= 0)
-		return;
+	rc = refclock_pps(peer, &up->atom, pp->sloppyclockflag);
+        switch (rc) {
+            case PPS_OK:
+                up->pcount++;
+                break;
+            default:
+            case PPS_SETUP:
+                up->scount++;
+                break;
+            case PPS_KERNEL:
+                up->kcount++;
+                break;
+            case PPS_NREADY:
+                up->rcount++;
+                break;
+        }
+        if (rc != PPS_OK) return;
 
 	peer->flags |= FLAG_PPS;
 
@@ -201,9 +220,8 @@ atom_timer(
 	 * That's so we can make awesome Allan deviation plots.
 	 */
 	if (pp->sloppyclockflag & CLK_FLAG4) {
-		snprintf(tbuf, sizeof(tbuf), "%.9f",
-			 pp->filter[pp->coderecv]);
-		record_clock_stats(&peer->srcadr, tbuf);
+		mprintf_clock_stats(&peer->srcadr, "%.9f",
+			pp->filter[pp->coderecv]);
 	}
 }
 
@@ -217,19 +235,32 @@ atom_poll(
 	struct peer *peer	/* peer structure pointer */
 	)
 {
+	struct ppsunit *up;
 	struct refclockproc *pp;
 
 	UNUSED_ARG(unit);
 
+	pp = peer->procptr;
+	up = (struct ppsunit *)pp->unitptr;
+
 	/*
 	 * Don't wiggle the clock until some other driver has numbered
 	 * the seconds.
 	 */
-	if (sys_leap == LEAP_NOTINSYNC)
+	if (sys_leap == LEAP_NOTINSYNC) {
+		pp->codeproc = pp->coderecv;  // xxx ??
+		up->pcount = up->scount = up->kcount = up->rcount = 0;
 		return;
+        }
 
-	pp = peer->procptr;
 	pp->polls++;
+
+	mprintf_clock_stats(&peer->srcadr,
+	    "%ld %d %d %d %d",
+	    up->atom.sequence,
+	    up->pcount, up->scount, up->kcount, up->rcount);
+	up->pcount = up->scount = up->kcount = up->rcount = 0;
+
 	if (pp->codeproc == pp->coderecv) {
 		peer->flags &= ~FLAG_PPS;
 		refclock_report(peer, CEVNT_TIMEOUT);



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/2807ed51ec562bed4bee2034b9d12143cb251914
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20151222/814b3e04/attachment.html>


More information about the vc mailing list