* ntpd/refclock_wwvb.c (wwvb_start): Cosmetic reorder.
* ntpd/refclock_atom.c (RANGEGATE): Cleanup. Add ASTAGE.
Add ppsparams to struct ppsunit.
(atom_start): Init peer->burst to ASTAGE.
(atom_shutdown): Multi-handle
(atom_pps): Multi-handle
(atom_pps): RANGEGATE cleanup
(atom_poll): Poll count cleanup. Error check cleanup. Burst cleanup.
* ntpd/ntp_refclock.c (refclock_transmit): Lose the pre-burst
check poll_update().
(refclock_sample): Fix the jitter calc.
(refclock_receive): Pass the jitter to the clock_filter().
* ntpd/ntp_proto.c (clock_update): If we lose sync, reset the poll
to NTP_MINDPOLL.
(poll_update): Poll wiggles. Make sure peer->nextdate is timely.
(clock_select): If we lose sync, reset the poll to NTP_MINDPOLL.
* ntpd/ntp_loopfilter.c (local_clock): Show the asocid in debug
output. popcorn debug message changes. Clamp the poll interval
if the system peer has changed. PPS wiggle changes.
From Dave Mills.
ChangeLog, aclocal.m4, configure, configure.in:
* configure.in: 4.0.99k10
bk: 39fa8350J0sndca4wyZgUMbpV7fVJw
+2000-10-28 Harlan Stenn <stenn@whimsy.udel.edu>
+
+ * configure.in: 4.0.99k10
+
+ * ntpd/refclock_wwvb.c (wwvb_start): Cosmetic reorder.
+ * ntpd/refclock_atom.c (RANGEGATE): Cleanup. Add ASTAGE.
+ Add ppsparams to struct ppsunit.
+ (atom_start): Init peer->burst to ASTAGE.
+ (atom_shutdown): Multi-handle
+ (atom_pps): Multi-handle
+ (atom_pps): RANGEGATE cleanup
+ (atom_poll): Poll count cleanup. Error check cleanup. Burst cleanup.
+ * ntpd/ntp_refclock.c (refclock_transmit): Lose the pre-burst
+ check poll_update().
+ (refclock_sample): Fix the jitter calc.
+ (refclock_receive): Pass the jitter to the clock_filter().
+
+ * ntpd/ntp_proto.c (clock_update): If we lose sync, reset the poll
+ to NTP_MINDPOLL.
+ (poll_update): Poll wiggles. Make sure peer->nextdate is timely.
+ (clock_select): If we lose sync, reset the poll to NTP_MINDPOLL.
+ * ntpd/ntp_loopfilter.c (local_clock): Show the asocid in debug
+ output. popcorn debug message changes. Clamp the poll interval
+ if the system peer has changed. PPS wiggle changes.
+ From Dave Mills.
+
2000-10-16 Harlan Stenn <stenn@whimsy.udel.edu>
* ntpd/refclock_pcf.c (pcf_start):
# Define the identity of the package.
PACKAGE=ntp
-VERSION=4.0.99k9
+VERSION=4.0.99k10
cat >>confdefs.h <<EOF
#define PACKAGE "$PACKAGE"
AC_DEFINE_UNQUOTED(STR_SYSTEM, "$target")
AM_CONFIG_HEADER(config.h)
AC_ARG_PROGRAM
-AM_INIT_AUTOMAKE(ntp, 4.0.99k9)
+AM_INIT_AUTOMAKE(ntp, 4.0.99k10)
AC_PREREQ(2.49)
ac_cv_var_oncore_ok=no
#ifdef DEBUG
if (debug)
printf(
- "local_clock: offset %.6f jitter %.6f state %d\n",
- fp_offset, SQRT(epsil), state);
+ "local_clock: assid %d offset %.6f jitter %.6f state %d\n",
+ peer->associd, fp_offset, SQRT(epsil), state);
#endif
if (!ntp_enable) {
record_loop_stats();
if (debug)
printf(
"local_clock: popcorn %.6f %.6f\n",
- fp_offset, last_offset);
+ fabs(fp_offset - last_offset),
+ CLOCK_SGATE * oerror);
#endif
last_offset = fp_offset;
return (0);
}
}
+ /*
+ * Clamp the poll interval if the system peer has changed.
+ */
+ if (sys_poll > peer->maxpoll)
+ sys_poll = peer->maxpoll;
+ else if (sys_poll < peer->minpoll)
+ sys_poll = peer->minpoll;
+
#if defined(KERNEL_PLL)
/*
* This code segment works when clock adjustments are made using
*/
if (sys_poll > NTP_MAXDPOLL)
ntv.status |= STA_FLL;
- }
- /*
- * Wiggle the PPS bits according to the health of the
- * prefer peer. Note that we explicitly turn off the
- * PPS if not enabled.
- */
- if (pps_enable) {
- if (pll_status & STA_PPSSIGNAL)
+ /*
+ * If the PPS signal is up and enabled, light
+ * the frequency bit. If the PPS driver is
+ * working, light the phase bit as well. If not,
+ * douse the lights, since somebody else may
+ * have left the switch on.
+ */
+ if (pps_enable && pll_status & STA_PPSSIGNAL) {
ntv.status |= STA_PPSFREQ;
- if (pll_status & STA_PPSFREQ && pps_stratum <
- STRATUM_UNSPEC)
- ntv.status |= STA_PPSTIME;
- } else {
- pll_status &= ~(STA_PPSFREQ | STA_PPSTIME);
+ if (pps_stratum < STRATUM_UNSPEC)
+ ntv.status |= STA_PPSTIME;
+ } else {
+ ntv.status &= ~(STA_PPSFREQ |
+ STA_PPSTIME);
+ }
}
/*
- * Update the offset and frequency from the kernel
- * variables.
+ * Pass the stuff to the kernel. If it squeals, turn off
+ * the pigs. In any case, fetch the kernel offset and
+ * frequency and pretend we did it here.
*/
if (ntp_adjtime(&ntv) == TIME_ERROR) {
if (ntv.status != pll_status)
msyslog(LOG_ERR,
"kernel time discipline status change %x",
ntv.status);
+ ntv.status &= ~(STA_PPSFREQ | STA_PPSTIME);
}
pll_status = ntv.status;
if (pll_nano)
flladj = plladj = 0;
/*
- * If the kernel pps discipline is working, monitor its
- * performance.
+ * If the kernel PPS is lit, monitor its performance.
*/
if (ntv.status & STA_PPSTIME) {
if (!pps_control)
sys_jitter = ntv.jitter / 1e9;
else
sys_jitter = ntv.jitter / 1e6;
- sys_poll = NTP_MINDPOLL;
}
}
#endif /* KERNEL_PLL */
NLOG(NLOG_SYNCSTATUS)
msyslog(LOG_INFO, "synchronisation lost");
sys_peer = NULL;
+ sys_poll = NTP_MINDPOLL;
sys_stratum = STRATUM_UNSPEC;
report_event(EVNT_CLOCKRESET, (struct peer *)0);
break;
* The wiggle-the-poll-interval dance. Broadcasters dance only
* the minpoll beat. Reference clock partners sit this one out.
* Dancers surviving the clustering algorithm beat to the system
- * clock. Broadcast clients are usually lead by their broadcast
+ * poll. Broadcast clients are usually lead by their broadcast
* partner, but faster in the initial mating dance.
*/
oldpoll = peer->kpoll;
#endif /* AUTOKEY */
- if (peer->hmode == MODE_BROADCAST) {
+ if (peer->hmode == MODE_BROADCAST)
peer->hpoll = peer->minpoll;
- } else if (peer->flags & FLAG_SYSPEER) {
+ else if (peer->flags & FLAG_SYSPEER)
peer->hpoll = sys_poll;
- } else {
- if (hpoll > peer->maxpoll)
- peer->hpoll = peer->maxpoll;
- else if (hpoll < peer->minpoll)
- peer->hpoll = peer->minpoll;
- else
- peer->hpoll = hpoll;
- }
+ else
+ peer->hpoll = hpoll;
+ if (peer->hpoll > peer->maxpoll)
+ peer->hpoll = peer->maxpoll;
+ else if (peer->hpoll < peer->minpoll)
+ peer->hpoll = peer->minpoll;
if (peer->burst > 0) {
if (peer->nextdate != current_time)
return;
peer->minpoll);
peer->nextdate = peer->outdate + RANDPOLL(peer->kpoll);
}
-
+ if (peer->nextdate < current_time)
+ peer->nextdate = current_time;
#ifdef AUTOKEY
/*
* Bit of crass arrogance at this point. If the poll interval
nlist = 1;
} else {
if (sys_peer != NULL) {
+ sys_peer = NULL;
+ sys_poll = NTP_MINDPOLL;
report_event(EVNT_PEERSTCHG,
(struct peer *)0);
NLOG(NLOG_SYNCSTATUS)
msyslog(LOG_INFO,
"synchronisation lost");
}
- sys_peer = NULL;
return;
}
}
sys_prefer = peer_list[i];
}
} else {
- if (peer_list[i] == sys_peer)
+ if (peer_list[i] == sys_peer) {
sys_peer = NULL;
+ sys_poll = NTP_MINDPOLL;
+ }
}
}
if (refclock_conf[clktype]->clock_poll != noentry)
(refclock_conf[clktype]->clock_poll)(unit, peer);
peer->outdate = next;
- poll_update(peer, hpoll);
if (peer->burst > 0)
peer->burst--;
poll_update(peer, hpoll);
)
{
int i, j, k, m, n;
- double offset, jitter;
+ double offset;
double off[MAXSTAGE];
/*
/*
* Determine the offset and jitter.
*/
- offset = jitter = 0;
- for (k = i; k < j; k++) {
+ offset = 0;
+ for (k = i; k < j; k++)
offset += off[k];
- if (k > i)
- jitter += SQUARE(off[k] - off[k - 1]);
- }
pp->offset = offset / m;
- pp->jitter = jitter / m;
+ if (m > 1)
+ pp->jitter = SQUARE(off[i] - off[j - 1]);
+ else
+ pp->jitter = 0;
#ifdef DEBUG
if (debug)
printf(
get_systime(&peer->rec);
if (!refclock_sample(pp))
return;
- clock_filter(peer, pp->offset, 0., 0.);
+ clock_filter(peer, pp->offset, 0., pp->jitter);
clock_select();
record_peer_stats(&peer->srcadr, ctlpeerstatus(peer),
peer->offset, peer->delay, CLOCK_PHI * (current_time -
peer->epoch), SQRT(peer->jitter));
if (cal_enable && last_offset < MINDISPERSE) {
- if (
- peer != sys_peer
#ifdef KERNEL_PLL
- || pll_status & STA_PPSTIME
+ if (peer != sys_peer || pll_status & STA_PPSTIME)
+#else
+ if (peer != sys_peer)
#endif /* KERNEL_PLL */
- )
pp->fudgetime1 -= pp->offset * FUDGEFAC;
else
pp->fudgetime1 -= pp->fudgetime1 * FUDGEFAC;
#define REFID "PPS\0" /* reference ID */
#define DESCRIPTION "PPS Clock Discipline" /* WRU */
#define NANOSECOND 1000000000 /* one second (ns) */
-#define RANGEGATE (NANOSECOND - 500000) /* range gate (ns) */
+#define RANGEGATE 500000 /* range gate (ns) */
+#define ASTAGE 8 /* filter stages */
static struct peer *pps_peer; /* atom driver for PPS sources */
struct ppsunit {
struct timespec ts; /* last timestamp */
int fddev; /* pps device descriptor */
+ pps_params_t pps_params; /* pps parameters */
pps_info_t pps_info; /* last pps data */
pps_handle_t handle; /* pps handlebars */
};
pps_peer = peer;
pp = peer->procptr;
peer->precision = PRECISION;
- peer->stratum = STRATUM_UNSPEC;
pp->clockdesc = DESCRIPTION;
memcpy((char *)&pp->refid, REFID, 4);
+ peer->burst = ASTAGE;
+ peer->stratum = STRATUM_UNSPEC;
#ifdef HAVE_PPSAPI
up = emalloc(sizeof(struct ppsunit));
memset(up, 0, sizeof(struct ppsunit));
{
struct refclockproc *pp;
register struct ppsunit *up;
- pps_params_t pps_params;
int capability;
pp = peer->procptr;
"refclock_atom: time_pps_getcap failed: %m");
return (0);
}
- memset(&pps_params, 0, sizeof(pps_params_t));
+ memset(&up->pps_params, 0, sizeof(pps_params_t));
if (enb_clear)
- pps_params.mode = capability & PPS_CAPTURECLEAR;
+ up->pps_params.mode = capability & PPS_CAPTURECLEAR;
else
- pps_params.mode = capability & PPS_CAPTUREASSERT;
- if (!pps_params.mode) {
+ up->pps_params.mode = capability & PPS_CAPTUREASSERT;
+ if (!up->pps_params.mode) {
msyslog(LOG_ERR,
"refclock_atom: invalid capture edge %d",
pps_assert);
return (0);
}
- if (time_pps_setparams(up->handle, &pps_params) < 0) {
+ if (time_pps_setparams(up->handle, &up->pps_params) < 0) {
msyslog(LOG_ERR,
"refclock_atom: time_pps_setparams failed: %m");
return (0);
}
if (enb_hardpps) {
if (time_pps_kcbind(up->handle, PPS_KC_HARDPPS,
- pps_params.mode, PPS_TSFMT_TSPEC) < 0) {
+ up->pps_params.mode, PPS_TSFMT_TSPEC) < 0) {
msyslog(LOG_ERR,
"refclock_atom: time_pps_kcbind failed: %m");
return (0);
}
#if DEBUG
if (debug) {
- time_pps_getparams(up->handle, &pps_params);
+ time_pps_getparams(up->handle, &up->pps_params);
printf(
"refclock_ppsapi: fd %d capability 0x%x version %d mode 0x%x kern %d\n",
- up->fddev, capability, pps_params.api_version,
- pps_params.mode, enb_hardpps);
+ up->fddev, capability, up->pps_params.api_version,
+ up->pps_params.mode, enb_hardpps);
}
#endif
return (1);
up = (struct ppsunit *)pp->unitptr;
if (up->fddev > 0)
close(up->fddev);
- if (up->handle > 0)
+ if (up->handle != 0)
time_pps_destroy(up->handle);
if (pps_peer == peer)
pps_peer = 0;
*/
pp = peer->procptr;
up = (struct ppsunit *)pp->unitptr;
- if (up->handle <= 0)
- return (1);
+ if (up->handle == 0)
+ return (-1);
timeout.tv_sec = 0;
timeout.tv_nsec = 0;
memcpy(&pps_info, &up->pps_info, sizeof(pps_info_t));
if (time_pps_fetch(up->handle, PPS_TSFMT_TSPEC, &up->pps_info,
&timeout) < 0)
return (-1);
- if (up->pps_info.current_mode & PPS_CAPTUREASSERT) {
+ if (up->pps_params.mode & PPS_CAPTUREASSERT) {
if (pps_info.assert_sequence ==
up->pps_info.assert_sequence)
return (1);
ts = up->pps_info.assert_timestamp;
- } else if (up->pps_info.current_mode & PPS_CAPTURECLEAR) {
+ } else if (up->pps_params.mode & PPS_CAPTURECLEAR) {
if (pps_info.clear_sequence ==
up->pps_info.clear_sequence)
return (1);
} else {
return (-1);
}
- if (ts.tv_sec == up->ts.tv_sec && ts.tv_nsec < up->ts.tv_nsec +
- RANGEGATE)
+ if (!((ts.tv_sec == up->ts.tv_sec && ts.tv_nsec -
+ up->ts.tv_nsec > NANOSECOND - RANGEGATE) ||
+ (ts.tv_sec - up->ts.tv_sec == 1 && ts.tv_nsec -
+ up->ts.tv_nsec < RANGEGATE))) {
+ up->ts = ts;
return (1);
+ }
up->ts = ts;
pp->lastrec.l_ui = ts.tv_sec + JAN_1970;
dtemp = ts.tv_nsec * FRAC / 1e9;
pp->lastrec.l_uf = (u_int32)dtemp;
if (ts.tv_nsec > NANOSECOND / 2)
ts.tv_nsec -= NANOSECOND;
- dtemp = -ts.tv_nsec;
- SAMPLE(dtemp / NANOSECOND + pp->fudgetime1);
+ dtemp = -(double)ts.tv_nsec / NANOSECOND;
+ SAMPLE(dtemp + pp->fudgetime1);
+#ifdef DEBUG
+ if (debug > 1)
+ printf("atom_pps %f %f\n", dtemp, pp->fudgetime1);
+#endif
return (0);
}
#endif /* HAVE_PPSAPI */
* little bookeeping and process the surviving samples.
*/
pp = peer->procptr;
+ pp->polls++;
#ifdef HAVE_PPSAPI
err = atom_pps(peer);
- if (err > 0) {
- return;
- } else if (err < 0) {
+ if (err < 0) {
refclock_report(peer, CEVNT_FAULT);
return;
}
#endif /* HAVE_PPSAPI */
+
/*
* Valid time is returned only if the prefer peer has survived
* the intersection algorithm and within clock_max of local time
* the first valid update and the stratum is set at the prefer
* peer.
*/
+ if (peer->burst > 0)
+ return;
peer->stratum = STRATUM_UNSPEC;
- if (!sys_prefer)
+ if (pp->codeproc == pp->coderecv) {
+ refclock_report(peer, CEVNT_TIMEOUT);
+ peer->burst = ASTAGE;
return;
- if (fabs(sys_prefer->offset) > clock_max)
+
+ } else if (!sys_prefer) {
+ pp->codeproc = pp->coderecv;
+ peer->burst = ASTAGE;
+ return;
+
+ } else if (fabs(sys_prefer->offset) > clock_max) {
+ pp->codeproc = pp->coderecv;
+ peer->burst = ASTAGE;
return;
+ }
peer->stratum = sys_prefer->stratum;
if (peer->stratum <= 1)
peer->refid = pp->refid;
else
peer->refid = peer->srcadr.sin_addr.s_addr;
pp->leap = LEAP_NOWARNING;
- pp->polls++;
- if (peer->burst > 0)
- return;
- if (pp->coderecv == pp->codeproc) {
- refclock_report(peer, CEVNT_TIMEOUT);
- return;
- }
refclock_receive(peer);
- peer->burst = MAXSTAGE;
+ peer->burst = ASTAGE;
}
-
#else
int refclock_atom_bs;
int
* Initialize miscellaneous variables
*/
peer->precision = PRECISION;
- peer->burst = NSTAGE;
pp->clockdesc = DESCRIPTION;
memcpy((char *)&pp->refid, REFID, 4);
+ peer->burst = NSTAGE;
return (1);
}