summaryrefslogtreecommitdiff
path: root/usr.sbin/ntpd/ntp.c
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2006-06-17 18:40:43 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2006-06-17 18:40:43 +0000
commit0687c41ffcf408ac7d8bdbf417add41082bfc17e (patch)
treedebcf58bc9c9e51fee6c165320e0423bbb891a7b /usr.sbin/ntpd/ntp.c
parent016f1a0ab32171b68e64f9180970978adfa21a52 (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.c56
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);