diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2006-06-17 18:40:43 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2006-06-17 18:40:43 +0000 |
commit | 0687c41ffcf408ac7d8bdbf417add41082bfc17e (patch) | |
tree | debcf58bc9c9e51fee6c165320e0423bbb891a7b /usr.sbin/ntpd/ntp.c | |
parent | 016f1a0ab32171b68e64f9180970978adfa21a52 (diff) |
Import frequency conrrection code from dragonfly, whith some changes:
only do frequency compensation if the clock is synced, and a slightly
diffent way of computing the linear regression.
You'll need a recent kernel and libc to use this.
Testing by naddy@ and ckuethe@ and others, thanks!
ok henning@
Diffstat (limited to 'usr.sbin/ntpd/ntp.c')
-rw-r--r-- | usr.sbin/ntpd/ntp.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/usr.sbin/ntpd/ntp.c b/usr.sbin/ntpd/ntp.c index 6f849ca17a9..b970c1f9b80 100644 --- a/usr.sbin/ntpd/ntp.c +++ b/usr.sbin/ntpd/ntp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntp.c,v 1.86 2006/06/09 07:42:08 otto Exp $ */ +/* $OpenBSD: ntp.c,v 1.87 2006/06/17 18:40:42 otto Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -149,6 +149,14 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf) client_peer_init(p); bzero(&conf->status, sizeof(conf->status)); + + conf->freq.samples = 0; + conf->freq.x = 0.0; + conf->freq.xx = 0.0; + conf->freq.xy = 0.0; + conf->freq.y = 0.0; + conf->freq.overall_offset = 0.0; + conf->status.synced = 0; clock_getres(CLOCK_REALTIME, &tp); b = 1000000000 / tp.tv_nsec; /* convert to Hz */ @@ -428,6 +436,50 @@ peer_remove(struct ntp_peer *p) peer_cnt--; } +static void +priv_adjfreq(double offset) +{ + double curtime, freq; + + if (!conf->status.synced) + return; + + conf->freq.samples++; + + if (conf->freq.samples <= 0) + return; + + conf->freq.overall_offset += offset; + offset = conf->freq.overall_offset; + + curtime = gettime_corrected(); + conf->freq.xy += offset * curtime; + conf->freq.x += curtime; + conf->freq.y += offset; + conf->freq.xx += curtime * curtime; + + if (conf->freq.samples % FREQUENCY_SAMPLES != 0) + return; + + freq = + (conf->freq.xy - conf->freq.x * conf->freq.y / conf->freq.samples) + / + (conf->freq.xx - conf->freq.x * conf->freq.x / conf->freq.samples); + + if (freq > MAX_FREQUENCY_ADJUST) + freq = MAX_FREQUENCY_ADJUST; + else if (freq < -MAX_FREQUENCY_ADJUST) + freq = -MAX_FREQUENCY_ADJUST; + + imsg_compose(ibuf_main, IMSG_ADJFREQ, 0, 0, &freq, sizeof(freq)); + conf->freq.xy = 0.0; + conf->freq.x = 0.0; + conf->freq.y = 0.0; + conf->freq.xx = 0.0; + conf->freq.samples = 0; + conf->freq.overall_offset = 0.0; +} + int priv_adjtime(void) { @@ -491,6 +543,8 @@ priv_adjtime(void) imsg_compose(ibuf_main, IMSG_ADJTIME, 0, 0, &offset_median, sizeof(offset_median)); + priv_adjfreq(offset_median); + conf->status.reftime = gettime(); conf->status.stratum++; /* one more than selected peer */ update_scale(offset_median); |