[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