re
using floating point for ntpd math is not a good idea.
this comes from the fact that mixing small and large numbers
in one fp expression leads to a huge loss of precision.
besides the fact that there is no need to change representation
from fixed point (ntp timestamps) to floating point and
back all the time. plus to that using fpu in daemons is
not polite and eats even more cpu time (:

this diff converts internal math to fixed point (64bit)
except for one place -- local clock frequency drift.
this part is still broken as one can see by constantly
flipping frequency adjucements in the logs since math
currently used performs computation on very large
numbers (products of time stamps) and very small
ones (products of time offsets) and thus totally useless.
i have figured a better way to follow frequency drift
but that can be done in the next step.

this has ran on both i386 and sparc64 for months now
and only has shown massive improvement in precision
(decrease of deviation). thus local clock offset still
flips every few hours from positive to negative and back
due to broken frequency adjucements.

please read and try.
cu
-- 
    paranoic mickey       (my employers have changed but, the name has remained)

Index: Makefile
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/Makefile,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile
--- Makefile    13 May 2009 18:10:04 -0000      1.2
+++ Makefile    15 May 2009 14:26:35 -0000
@@ -3,7 +3,7 @@
 
 PROG=  ntpd
 SRCS=  ntpd.c buffer.c log.c imsg.c ntp.c ntp_msg.c ntp_dns.c \
-       parse.y config.c server.c client.c sensors.c util.c
+       parse.y config.c server.c client.c sensors.c
 CFLAGS+= -Wall -I${.CURDIR}
 CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
 CFLAGS+= -Wmissing-declarations
Index: client.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/client.c,v
retrieving revision 1.4
diff -u -p -r1.4 client.c
--- client.c    15 May 2009 11:40:42 -0000      1.4
+++ client.c    15 May 2009 14:26:35 -0000
@@ -195,19 +195,21 @@ client_query(struct ntp_peer *p)
 int
 client_dispatch(struct ntp_peer *p, u_int8_t settime)
 {
-       struct ntp_msg           msg;
-       struct msghdr            somsg;
-       struct iovec             iov[1];   
-       struct timeval           tv1;
-       char                     buf[NTP_MSGSIZE];
+       extern int debug; /* from log.c */
+       struct ntp_msg  msg;
+       struct msghdr   somsg;
+       struct iovec    iov[1];
+       struct timeval  tv1, tv2;
+       char            buf[NTP_MSGSIZE];
        union {
                struct cmsghdr hdr;
                char buf[CMSG_SPACE(sizeof tv1)];
        } cmsgbuf;
-       struct cmsghdr          *cmsg;
-       ssize_t                  size;
-       double                   T1, T2, T3, T4;
-       time_t                   interval;
+       int64_t         T1, T2, T3, T4;
+       struct cmsghdr  *cmsg;
+       struct ntp_offset *reply;
+       ssize_t         size;
+       time_t          interval;
 
        somsg.msg_name = NULL;
        somsg.msg_namelen = 0;
@@ -219,7 +221,7 @@ client_dispatch(struct ntp_peer *p, u_in
        somsg.msg_controllen = sizeof cmsgbuf.buf;
        somsg.msg_flags = 0;
 
-       T4 = getoffset();
+       getoffset(&tv2);
        if ((size = recvmsg(p->query->fd, &somsg, 0)) < 0) {
                if (errno == EHOSTUNREACH || errno == EHOSTDOWN ||
                    errno == ENETUNREACH || errno == ENETDOWN ||
@@ -243,17 +245,20 @@ client_dispatch(struct ntp_peer *p, u_in
                return (0);
        }
 
+       T4 = 0;
        for (cmsg = CMSG_FIRSTHDR(&somsg); cmsg != NULL;
            cmsg = CMSG_NXTHDR(&somsg, cmsg)) {
                if (cmsg->cmsg_level == SOL_SOCKET &&
                    cmsg->cmsg_type == SCM_TIMESTAMP) {
                        memcpy(&tv1, CMSG_DATA(cmsg), sizeof tv1);
-                       T4 += tv1.tv_sec + JAN_1970 + 1.0e-6 * tv1.tv_usec;
+                       T4 = timeval2int64(&tv1);
+                       T4 += (int64_t)JAN_1970 << 31;
+                       T4 += timeval2int64(&tv2);
                        break;
                }
        }
 
-       if (T4 < JAN_1970) {
+       if (T4 == 0) {
                client_log_error(p, "recvmsg control format", EBADF);
                set_next(p, error_interval());
                return (0);
@@ -301,8 +306,8 @@ client_dispatch(struct ntp_peer *p, u_in
         */
 
        T1 = p->query->xmttime;
-       T2 = lfp_to_d(msg.rectime);
-       T3 = lfp_to_d(msg.xmttime);
+       T2 = lfxt2int64(&msg.rectime);
+       T3 = lfxt2int64(&msg.xmttime);
 
        /*
         * XXX workaround: time_t / tv_sec must never wrap.
@@ -314,32 +319,51 @@ client_dispatch(struct ntp_peer *p, u_in
                return (0);
        }
 
-       p->reply[p->shift].offset = ((T2 - T1) + (T3 - T4)) / 2;
-       p->reply[p->shift].delay = (T4 - T1) - (T3 - T2);
-       if (p->reply[p->shift].delay < 0) {
+       if (T4 <= T1) {
                interval = error_interval();
                set_next(p, interval);
-               log_info("reply from %s: negative delay %fs, "
+               log_info("local clock is not monotonic");
+               return (0);
+       }
+
+       reply = &p->reply[p->shift];
+
+       reply->offset = ((T2 - T1) + (T3 - T4)) / 2;
+       reply->delay = (T4 - T1) - (T3 - T2);
+       if (reply->delay < 0) {
+               char *s = "";
+               int64_t val = reply->delay;
+               if (val < 0) {
+                       s = "-";
+                       val = -val;
+               }
+               int642timeval(val, &tv2);
+               interval = error_interval();
+               set_next(p, interval);
+               log_info("reply from %s: negative delay %s%ld.%06lus "
                    "next query %ds",
                    log_sockaddr((struct sockaddr *)&p->addr->ss),
-                   p->reply[p->shift].delay, interval);
+                   s, tv2.tv_sec, tv2.tv_usec, interval);
                return (0);
        }
-       p->reply[p->shift].error = (T2 - T1) - (T3 - T4);
-       p->reply[p->shift].rcvd = getmonotime();
-       p->reply[p->shift].good = 1;
-
-       p->reply[p->shift].status.leap = (msg.status & LIMASK);
-       p->reply[p->shift].status.precision = msg.precision;
-       p->reply[p->shift].status.rootdelay = sfp_to_d(msg.rootdelay);
-       p->reply[p->shift].status.rootdispersion = sfp_to_d(msg.dispersion);
-       p->reply[p->shift].status.refid = msg.refid;
-       p->reply[p->shift].status.reftime = lfp_to_d(msg.reftime);
-       p->reply[p->shift].status.poll = msg.ppoll;
-       p->reply[p->shift].status.stratum = msg.stratum;
+
+       p->shift = (p->shift + 1) % OFFSET_ARRAY_SIZE;
+
+       reply->error = (T2 - T1) - (T3 - T4);
+       reply->rcvd = getmonotime();
+       reply->good = 1;
+
+       reply->status.leap = msg.status & LIMASK;
+       reply->status.precision = msg.precision;
+       reply->status.refid = ntohl(msg.refid);
+       reply->status.poll = msg.ppoll;
+       reply->status.stratum = msg.stratum;
+       reply->status.rootdelay = sfxt2int64(&msg.rootdelay);
+       reply->status.rootdispersion = sfxt2int64(&msg.dispersion);
+       reply->status.reftime = lfxt2int64(&msg.reftime);
 
        if (p->addr->ss.ss_family == AF_INET) {
-               p->reply[p->shift].status.send_refid =
+               reply->status.send_refid =
                    ((struct sockaddr_in *)&p->addr->ss)->sin_addr.s_addr;
        } else if (p->addr->ss.ss_family == AF_INET6) {
                MD5_CTX         context;
@@ -349,10 +373,10 @@ client_dispatch(struct ntp_peer *p, u_in
                MD5Update(&context, ((struct sockaddr_in6 *)&p->addr->ss)->
                    sin6_addr.s6_addr, sizeof(struct in6_addr));
                MD5Final(digest, &context);
-               memcpy((char *)&p->reply[p->shift].status.send_refid, digest,
+               memcpy((char *)&reply->status.send_refid, digest,
                    sizeof(u_int32_t));
        } else
-               p->reply[p->shift].status.send_refid = msg.xmttime.fractionl;
+               reply->status.send_refid = msg.xmttime.fractionl;
 
        if (p->trustlevel < TRUSTLEVEL_PATHETIC)
                interval = scale_interval(INTERVAL_QUERY_PATHETIC);
@@ -373,16 +397,25 @@ client_dispatch(struct ntp_peer *p, u_in
                p->trustlevel++;
        }
 
-       log_debug("reply from %s: offset %f delay %f, "
-           "next query %ds", log_sockaddr((struct sockaddr *)&p->addr->ss),
-           p->reply[p->shift].offset, p->reply[p->shift].delay, interval);
+       if (debug) {
+               char *s = "";
+               int64_t val = reply->offset;
+               if (val < 0) {
+                       s = "-";
+                       val = -val;
+               }
+               int642timeval(val, &tv1);
+               int642timeval(reply->delay, &tv2);
+               log_debug("reply from %s: "
+                   "offset %s%ld.%06lus delay %ld.%06lus, next query %ds",
+                   log_sockaddr((struct sockaddr *)&p->addr->ss),
+                   s, tv1.tv_sec, tv1.tv_usec, tv2.tv_sec, tv2.tv_usec,
+                   interval);
+       }
 
        client_update(p);
        if (settime)
-               priv_settime(p->reply[p->shift].offset);
-
-       if (++p->shift >= OFFSET_ARRAY_SIZE)
-               p->shift = 0;
+               priv_settime(reply->offset);
 
        return (0);
 }
@@ -390,7 +423,8 @@ client_dispatch(struct ntp_peer *p, u_in
 int
 client_update(struct ntp_peer *p)
 {
-       int     i, best = 0, good = 0;
+       struct ntp_offset       *reply, *best, *last;
+       int     good;
 
        /*
         * clock filter
@@ -399,28 +433,26 @@ client_update(struct ntp_peer *p)
         * invalidate it and all older ones
         */
 
-       for (i = 0; good == 0 && i < OFFSET_ARRAY_SIZE; i++)
-               if (p->reply[i].good) {
-                       good++;
-                       best = i;
-               }
-
-       for (; i < OFFSET_ARRAY_SIZE; i++)
-               if (p->reply[i].good) {
-                       good++;
-                       if (p->reply[i].delay < p->reply[best].delay)
-                               best = i;
-               }
+       for (good = 0, best = NULL, reply = &p->reply[0],
+           last = &p->reply[OFFSET_ARRAY_SIZE]; reply < last; reply++) {
+               if (!reply->good)
+                       continue;
+               good++;
+               if (!best)
+                       best = reply;
+               if (reply->delay < best->delay)
+                       best = reply;
+       }
 
-       if (good < 8)
+       if (good < OFFSET_ARRAY_SIZE)
                return (-1);
 
-       memcpy(&p->update, &p->reply[best], sizeof(p->update));
-       if (priv_adjtime() == 0) {
-               for (i = 0; i < OFFSET_ARRAY_SIZE; i++)
-                       if (p->reply[i].rcvd <= p->reply[best].rcvd)
-                               p->reply[i].good = 0;
-       }
+       memcpy(&p->update, best, sizeof(p->update));
+       if (priv_adjtime() == 0)
+               for (reply = &p->reply[0], last = &p->reply[OFFSET_ARRAY_SIZE];
+                   reply < last; reply++)
+                       if (reply->rcvd <= best->rcvd)
+                               reply->good = 0;
        return (0);
 }
 
Index: ntp.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntp.c,v
retrieving revision 1.3
diff -u -p -r1.3 ntp.c
--- ntp.c       13 May 2009 18:10:04 -0000      1.3
+++ ntp.c       15 May 2009 14:26:35 -0000
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henn...@openbsd.org>
  * Copyright (c) 2004 Alexander Guy <alexander....@andern.org>
@@ -168,7 +167,7 @@ ntp_main(int pipe_prnt[2], struct ntpd_c
        conf->freq.xx = 0.0;
        conf->freq.xy = 0.0;
        conf->freq.y = 0.0;
-       conf->freq.overall_offset = 0.0;
+       conf->freq.overall_offset = 0;
 
        conf->status.synced = 0;
        clock_getres(CLOCK_REALTIME, &tp);
@@ -522,9 +521,10 @@ peer_remove(struct ntp_peer *p)
 }
 
 static void
-priv_adjfreq(double offset)
+priv_adjfreq(int64_t offset)
 {
-       double curtime, freq;
+       double curtime, freq, doff;
+       int64_t relfreq;
 
        if (!conf->status.synced)
                return;
@@ -535,12 +535,12 @@ priv_adjfreq(double offset)
                return;
 
        conf->freq.overall_offset += offset;
-       offset = conf->freq.overall_offset;
 
        curtime = gettime_corrected();
-       conf->freq.xy += offset * curtime;
+       doff = conf->freq.overall_offset;
+       conf->freq.xy += doff * curtime;
        conf->freq.x += curtime;
-       conf->freq.y += offset;
+       conf->freq.y += doff;
        conf->freq.xx += curtime * curtime;
 
        if (conf->freq.samples % FREQUENCY_SAMPLES != 0)
@@ -556,13 +556,14 @@ priv_adjfreq(double offset)
        else if (freq < -MAX_FREQUENCY_ADJUST)
                freq = -MAX_FREQUENCY_ADJUST;
 
-       imsg_compose(ibuf_main, IMSG_ADJFREQ, 0, 0, &freq, sizeof(freq));
+       relfreq = freq * 1e9 * (1LL << 32);
+       imsg_compose(ibuf_main, IMSG_ADJFREQ, 0, 0, &relfreq, sizeof(relfreq));
        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;
+       conf->freq.overall_offset = 0;
        conf->freq.num++;
 }
 
@@ -573,7 +574,7 @@ priv_adjtime(void)
        struct ntp_sensor        *s;
        int                       offset_cnt = 0, i = 0, j;
        struct ntp_offset       **offsets;
-       double                    offset_median;
+       int64_t                   offset_median;
 
        TAILQ_FOREACH(p, &conf->ntp_peers, entry) {
                if (p->trustlevel < TRUSTLEVEL_BADPEER)
@@ -626,8 +627,8 @@ priv_adjtime(void)
        }
        conf->status.leap = offsets[i]->status.leap;
 
-       imsg_compose(ibuf_main, IMSG_ADJTIME, 0, 0,
-           &offset_median, sizeof(offset_median));
+       imsg_compose(ibuf_main, IMSG_ADJTIME, 0, 0, &offset_median,
+           sizeof(offset_median));
 
        priv_adjfreq(offset_median);
 
@@ -671,9 +672,12 @@ offset_compare(const void *aa, const voi
 }
 
 void
-priv_settime(double offset)
+priv_settime(int64_t offset)
 {
-       imsg_compose(ibuf_main, IMSG_SETTIME, 0, 0, &offset, sizeof(offset));
+       struct timeval tv;
+
+       int642timeval(offset, &tv);
+       imsg_compose(ibuf_main, IMSG_SETTIME, 0, 0, &tv, sizeof(tv));
        conf->settime = 0;
 }
 
@@ -687,19 +691,24 @@ priv_host_dns(char *name, u_int32_t peer
 }
 
 void
-update_scale(double offset)
+update_scale(int64_t offset)
 {
-       offset += getoffset();
-       if (offset < 0)
-               offset = -offset;
+       struct timeval tv;
+       int64_t qscale;
+
+       getoffset(&tv);
+       offset += timeval2int64(&tv);
 
-       if (offset > QSCALE_OFF_MAX || !conf->status.synced ||
-           conf->freq.num < 3)
+       qscale = int64init(QSCALE_OFF_MAX / 1000000, QSCALE_OFF_MAX % 1000000);
+       if (offset > qscale || !conf->status.synced || conf->freq.num < 3)
                conf->scale = 1;
-       else if (offset < QSCALE_OFF_MIN)
-               conf->scale = QSCALE_OFF_MAX / QSCALE_OFF_MIN;
-       else
-               conf->scale = QSCALE_OFF_MAX / offset;
+       else {
+               conf->scale = qscale / offset;  /* XXX */
+               qscale = int64init(QSCALE_OFF_MIN / 1000000,
+                   QSCALE_OFF_MIN % 1000000);
+               if (offset < qscale)
+                       conf->scale = QSCALE_OFF_MAX / QSCALE_OFF_MIN;
+       }
 }
 
 time_t
@@ -776,4 +785,41 @@ report_peers(int always)
                                log_warnx("bad sensor %s", s->device);
                }
        }
+}
+
+int64_t
+gettime_corrected()
+{
+       struct timeval tv;
+       getoffset(&tv);
+       return gettime() + timeval2int64(&tv);
+}
+
+void
+getoffset(struct timeval *tv)
+{
+       if (adjtime(NULL, tv) == -1)
+               memset(tv, 0, sizeof(*tv));
+}
+
+int64_t
+gettime()
+{
+       struct timeval  tv;
+
+       if (gettimeofday(&tv, NULL) == -1)
+               fatal("gettimeofday");
+
+       return timeval2int64(&tv) + ((int64_t)JAN_1970 << 31);
+}
+
+time_t
+getmonotime(void)
+{
+       struct timespec ts;
+
+       if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
+               fatal("clock_gettime");
+
+       return (ts.tv_sec);
 }
Index: ntp.h
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntp.h,v
retrieving revision 1.2
diff -u -p -r1.2 ntp.h
--- ntp.h       13 May 2009 18:10:04 -0000      1.2
+++ ntp.h       15 May 2009 14:26:36 -0000
@@ -34,6 +34,7 @@
  *
  *    0                          1                   2                   3
  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+F
  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *   |           Integer Part       |     Fraction Part             |
  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -43,11 +44,41 @@ struct l_fixedpt {
        u_int32_t fractionl;
 };
 
+       /* 2147 = 2^31 / 1000000 */
+#define        timeval2int64(tv)                                       \
+    (((int64_t)(tv)->tv_sec << 31) + (2147U * (tv)->tv_usec))
+
+#define        int64init(s,u)  (((int64_t)(s) << 31) + (2147U * (u)))
+
+#define        int642timeval(i,tv) do {                                \
+       (tv)->tv_sec = (i) >> 31;                               \
+       (tv)->tv_usec = ((i) & 0x7fffffff) / 2148;              \
+} while (0)
+
+#define        lfxt2int64(lf)                                          \
+    (((int64_t)ntohl((lf)->int_partl) << 31) + (ntohl((lf)->fractionl) >> 1))
+
+#define        int642lfxt(i,lf) do {                                   \
+       (lf)->int_partl = htonl((i) >> 31);                     \
+       (lf)->fractionl = htonl((i) << 1);                      \
+} while (0)
+
+#define        us2int64(us)    (2147ULL * (us))
+
 struct s_fixedpt {
        u_int16_t int_parts;
        u_int16_t fractions;
 };
 
+#define        int642sfxt(i,lf) do {                                   \
+       (lf)->int_parts = htons((i) >> 31);                     \
+       (lf)->fractions = htons((i & 0x7fffffff) >> 15);        \
+} while (0)
+
+#define        sfxt2int64(lf)                          \
+    (((int64_t)ntohs((lf)->int_parts) << 31) + \
+    ((u_int)ntohs((lf)->fractions) << 15))
+
 /* RFC Section 4
  *
  *    0                          1                   2                   3
@@ -107,9 +138,9 @@ struct ntp_msg {
 } __packed;
 
 struct ntp_query {
-       int                     fd;
-       struct ntp_msg          msg;
-       double                  xmttime;
+       struct ntp_msg  msg;
+       int64_t         xmttime;
+       int             fd;
 };
 
 /*
@@ -139,8 +170,8 @@ struct ntp_query {
 #define        MODE_RES1       6       /* reserved for NTP control message */
 #define        MODE_RES2       7       /* reserved for private use */
 
-#define        JAN_1970        2208988800UL    /* 1970 - 1900 in seconds */
-#define        JAN_2030        1893456000UL + JAN_1970 /* 1. 1. 2030 00:00:00 
*/
+#define        JAN_1970 2208988800LL   /* 1970 - 1900 in seconds */
+#define        JAN_2030 ((JAN_1970 + 1893456000LL) << 31) /* 1. 1. 2030 
00:00:00 */
 
 #define        NTP_VERSION     4
 #define        NTP_MAXSTRATUM  15
Index: ntpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntpd.c,v
retrieving revision 1.4
diff -u -p -r1.4 ntpd.c
--- ntpd.c      14 May 2009 12:23:33 -0000      1.4
+++ ntpd.c      15 May 2009 14:26:36 -0000
@@ -38,11 +38,11 @@ int         main(int, char *[]);
 int            check_child(pid_t, const char *);
 int            dispatch_imsg(struct ntpd_conf *);
 void           reset_adjtime(void);
-int            ntpd_adjtime(double);
-void           ntpd_adjfreq(double, int);
-void           ntpd_settime(double);
+int            ntpd_adjtime(int64_t);
+void           ntpd_adjfreq(int64_t, int);
+void           ntpd_settime(struct timeval *);
 void           readfreq(void);
-int            writefreq(double);
+int            writefreq(int64_t);
 
 volatile sig_atomic_t   quit = 0;
 volatile sig_atomic_t   reconfig = 0;
@@ -271,10 +271,11 @@ dispatch_imsg(struct ntpd_conf *lconf)
 {
        struct imsg              imsg;
        int                      n, cnt;
-       double                   d;
+       struct timeval           tv;
        char                    *name;
        struct ntp_addr         *h, *hn;
        struct buf              *buf;
+       int64_t                  d;
 
        if ((n = imsg_read(ibuf)) == -1)
                return (-1);
@@ -306,13 +307,13 @@ dispatch_imsg(struct ntpd_conf *lconf)
                        ntpd_adjfreq(d, 1);
                        break;
                case IMSG_SETTIME:
-                       if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d))
+                       if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(tv))
                                fatalx("invalid IMSG_SETTIME received");
                        if (!lconf->settime)
                                break;
                        log_init(lconf->debug);
-                       memcpy(&d, imsg.data, sizeof(d));
-                       ntpd_settime(d);
+                       memcpy(&tv, imsg.data, sizeof(tv));
+                       ntpd_settime(&tv);
                        /* daemonize now */
                        if (!lconf->debug)
                                if (daemon(1, 0))
@@ -361,19 +362,30 @@ reset_adjtime(void)
 }
 
 int
-ntpd_adjtime(double d)
+ntpd_adjtime(int64_t d)
 {
-       struct timeval  tv, olddelta;
-       int             synced = 0;
        static int      firstadj = 1;
+       struct timeval  tv, tv1, olddelta;
+       char            *s = "";
+       int             synced = 0;
 
-       d += getoffset();
-       if (d >= (double)LOG_NEGLIGIBLE_ADJTIME / 1000 ||
-           d <= -1 * (double)LOG_NEGLIGIBLE_ADJTIME / 1000)
-               log_info("adjusting local clock by %fs", d);
+       getoffset(&olddelta);
+       int642timeval(d, &tv);
+       timeradd(&tv, &olddelta, &tv);
+
+       if (d < 0) {
+               s = "-";
+               d = -d;
+       }
+
+       int642timeval(d, &tv1);
+       if (tv1.tv_sec || tv1.tv_usec >= LOG_NEGLIGEE * 1000)
+               log_info("adjusting local clock by %s%ld.%06lus",
+                   s, tv1.tv_sec, tv1.tv_usec);
        else
-               log_debug("adjusting local clock by %fs", d);
-       d_to_tv(d, &tv);
+               log_debug("adjusting local clock by %s%ld.%06lus",
+                   s, tv1.tv_sec, tv1.tv_usec);
+
        if (adjtime(&tv, &olddelta) == -1)
                log_warn("adjtime failed");
        else if (!firstadj && olddelta.tv_sec == 0 && olddelta.tv_usec == 0)
@@ -383,44 +395,42 @@ ntpd_adjtime(double d)
 }
 
 void
-ntpd_adjfreq(double relfreq, int wrlog)
+ntpd_adjfreq(int64_t relfreq, int wrlog)
 {
        int64_t curfreq;
-       double ppmfreq;
+       char *sign = "";
        int r;
 
        if (adjfreq(NULL, &curfreq) == -1) {
                log_warn("adjfreq failed");
                return;
        }
+       curfreq += relfreq;
 
        /*
-        * adjfreq's unit is ns/s shifted left 32; convert relfreq to
-        * that unit before adding. We log values in part per million.
+        * adjfreq's unit is ns/s shifted left 32.
+        * We log values in part per million.
         */
-       curfreq += relfreq * 1e9 * (1LL << 32);
-       r = writefreq(curfreq / 1e9 / (1LL << 32));
-       ppmfreq = relfreq * 1e6;
-       if (wrlog) {
-               if (ppmfreq >= LOG_NEGLIGIBLE_ADJFREQ ||
-                   ppmfreq <= -LOG_NEGLIGIBLE_ADJFREQ)
-                       log_info("adjusting clock frequency by %f to %fppm%s",
-                           ppmfreq, curfreq / 1e3 / (1LL << 32),
-                           r ? "" : " (no drift file)");
-               else
-                       log_debug("adjusting clock frequency by %f to %fppm%s",
-                           ppmfreq, curfreq / 1e3 / (1LL << 32),
-                           r ? "" : " (no drift file)");
-       }
+       r = writefreq(curfreq);
+       if (relfreq < 0) {
+               relfreq = -relfreq;
+               sign = "-";
+       }
+       if (wrlog)
+               log_info("adjusting clock frequency by %s0.%06d to 
%d.%06dppm%s",
+                   sign, (int)(relfreq >> 32) % 1000000,
+                   (int)(curfreq >> 32) / 1000000,
+                   (int)(curfreq >> 32) % 1000000,
+                   r ? " (no drift file)" : "");
 
        if (adjfreq(&curfreq, NULL) == -1)
                log_warn("adjfreq failed");
 }
 
 void
-ntpd_settime(double d)
+ntpd_settime(struct timeval *tv)
 {
-       struct timeval  tv, curtime;
+       struct timeval  curtime;
        char            buf[80];
        time_t          tval;
 
@@ -428,9 +438,8 @@ ntpd_settime(double d)
                log_warn("gettimeofday");
                return;
        }
-       d_to_tv(d, &tv);
-       curtime.tv_usec += tv.tv_usec + 1000000;
-       curtime.tv_sec += tv.tv_sec - 1 + (curtime.tv_usec / 1000000);
+       curtime.tv_usec += tv->tv_usec + 1000000;
+       curtime.tv_sec += tv->tv_sec - 1 + (curtime.tv_usec / 1000000);
        curtime.tv_usec %= 1000000;
 
        if (settimeofday(&curtime, NULL) == -1) {
@@ -440,15 +449,15 @@ ntpd_settime(double d)
        tval = curtime.tv_sec;
        strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y",
            localtime(&tval));
-       log_info("set local clock to %s (offset %fs)", buf, d);
+       log_info("set local clock to %s (offset %ld.%06lus)", buf,
+           tv->tv_sec, tv->tv_usec);
 }
 
 void
 readfreq(void)
 {
+       int64_t current, d;
        FILE *fp;
-       int64_t current;
-       double d;
 
        fp = fopen(DRIFTFILE, "r");
        if (fp == NULL) {
@@ -463,7 +472,7 @@ readfreq(void)
        if (adjfreq(NULL, &current) == -1)
                log_warn("adjfreq failed");
        else if (current == 0) {
-               if (fscanf(fp, "%le", &d) == 1)
+               if (fscanf(fp, "%lld", &d) == 1)
                        ntpd_adjfreq(d, 0);
                else
                        log_warnx("can't read %s", DRIFTFILE);
@@ -472,7 +481,7 @@ readfreq(void)
 }
 
 int
-writefreq(double d)
+writefreq(int64_t d)
 {
        int r;
        FILE *fp;
@@ -484,10 +493,10 @@ writefreq(double d)
                        log_warn("can't open %s", DRIFTFILE);
                        warnonce = 0;
                }
-               return 0;
+               return -1;
        }
 
-       fprintf(fp, "%e\n", d);
+       fprintf(fp, "%lld\n", d);
        r = ferror(fp);
        if (fclose(fp) != 0 || r != 0) {
                if (warnonce) {
@@ -495,7 +504,7 @@ writefreq(double d)
                        warnonce = 0;
                }
                unlink(DRIFTFILE);
-               return 0;
+               return -1;
        }
-       return 1;
+       return 0;
 }
Index: ntpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntpd.h,v
retrieving revision 1.4
diff -u -p -r1.4 ntpd.h
--- ntpd.h      14 May 2009 12:23:33 -0000      1.4
+++ ntpd.h      15 May 2009 14:26:36 -0000
@@ -34,7 +34,7 @@
 #define        CONFFILE        "/etc/ntpd.conf"
 #define DRIFTFILE      "/var/db/ntpd.drift"
 
-#define        READ_BUF_SIZE           8192
+#define        READ_BUF_SIZE           512
 
 #define        INTERVAL_QUERY_NORMAL           30      /* sync to peers every 
n secs */
 #define        INTERVAL_QUERY_PATHETIC         60
@@ -47,15 +47,14 @@
 
 #define        MAX_SERVERS_DNS                 8
 
-#define        QSCALE_OFF_MIN                  0.001
-#define        QSCALE_OFF_MAX                  0.050
+#define        QSCALE_OFF_MIN                  50000   /* us */
+#define        QSCALE_OFF_MAX                  500000  /* us */
 
 #define        QUERYTIME_MAX           15      /* single query might take n 
secs max */
 #define        OFFSET_ARRAY_SIZE       8
 #define        SENSOR_OFFSETS          7
 #define        SETTIME_TIMEOUT         15      /* max seconds to wait with -s 
*/
-#define        LOG_NEGLIGIBLE_ADJTIME  32      /* negligible drift to not log 
(ms) */
-#define        LOG_NEGLIGIBLE_ADJFREQ  0.05    /* negligible rate to not log 
(ppm) */
+#define        LOG_NEGLIGEE            32      /* negligible drift to not log 
(ms) */
 #define        FREQUENCY_SAMPLES       8       /* samples for est. of 
permanent drift */
 #define        MAX_FREQUENCY_ADJUST    128e-5  /* max correction per iteration 
*/
 #define REPORT_INTERVAL                (24*60*60) /* interval between status 
reports */
@@ -94,9 +93,9 @@ struct ntp_addr_wrap {
 };
 
 struct ntp_status {
-       double          rootdelay;
-       double          rootdispersion;
-       double          reftime;
+       int64_t         rootdelay;
+       int64_t         rootdispersion;
+       int64_t         reftime;
        u_int32_t       refid;
        u_int32_t       send_refid;
        u_int8_t        synced;
@@ -108,9 +107,9 @@ struct ntp_status {
 
 struct ntp_offset {
        struct ntp_status       status;
-       double                  offset;
-       double                  delay;
-       double                  error;
+       int64_t                 offset;
+       int64_t                 delay;
+       int64_t                 error;
        time_t                  rcvd;
        u_int8_t                good;
 };
@@ -126,56 +125,56 @@ struct ntp_peer {
        time_t                           next;
        time_t                           deadline;
        u_int32_t                        id;
+       int                              lasterror;
+       int                              senderrors;
        u_int8_t                         shift;
        u_int8_t                         trustlevel;
        u_int8_t                         weight;
-       int                              lasterror;
-       int                              senderrors;
 };
 
 struct ntp_sensor {
        TAILQ_ENTRY(ntp_sensor)          entry;
        struct ntp_offset                offsets[SENSOR_OFFSETS];
        struct ntp_offset                update;
+       int64_t                          correction;
        time_t                           next;
        time_t                           last;
        char                            *device;
        u_int32_t                        refid;
        int                              sensordevid;
-       int                              correction;
        u_int8_t                         weight;
        u_int8_t                         shift;
 };
 
 struct ntp_conf_sensor {
-       TAILQ_ENTRY(ntp_conf_sensor)             entry;
-       char                                    *device;
-       char                                    *refstr;
-       int                                      correction;
-       u_int8_t                                 weight;
+       TAILQ_ENTRY(ntp_conf_sensor)     entry;
+       char                            *device;
+       char                            *refstr;
+       int                              correction;
+       u_int8_t                         weight;
 };
 
 struct ntp_freq {
-       double                          overall_offset;
-       double                          x, y;
-       double                          xx, xy;
-       int                             samples;
-       u_int                           num;
+       double  x, y;
+       double  xx, xy;
+       int64_t overall_offset;
+       int     samples;
+       u_int   num;
 };
 
 struct ntpd_conf {
-       TAILQ_HEAD(listen_addrs, listen_addr)           listen_addrs;
-       TAILQ_HEAD(ntp_peers, ntp_peer)                 ntp_peers;
-       TAILQ_HEAD(ntp_sensors, ntp_sensor)             ntp_sensors;
-       TAILQ_HEAD(ntp_conf_sensors, ntp_conf_sensor)   ntp_conf_sensors;
-       struct ntp_status                               status;
-       struct ntp_freq                                 freq;
-       u_int8_t                                        listen_all;
-       u_int8_t                                        settime;
-       u_int8_t                                        debug;
-       u_int32_t                                       scale;
-       u_int8_t                                        noaction;
-       u_int8_t                                        family;
+       TAILQ_HEAD(, listen_addr)       listen_addrs;
+       TAILQ_HEAD(, ntp_peer)          ntp_peers;
+       TAILQ_HEAD(, ntp_sensor)        ntp_sensors;
+       TAILQ_HEAD(, ntp_conf_sensor)   ntp_conf_sensors;
+       struct ntp_status               status;
+       struct ntp_freq                 freq;
+       u_int32_t                       scale;
+       u_int8_t                        listen_all;
+       u_int8_t                        settime;
+       u_int8_t                        debug;
+       u_int8_t                        noaction;
+       u_int8_t                        family;
 };
 
 struct buf {
@@ -201,7 +200,7 @@ struct buf_read {
 /* ipc messages */
 
 #define        IMSG_HEADER_SIZE        sizeof(struct imsg_hdr)
-#define        MAX_IMSGSIZE            8192
+#define        MAX_IMSGSIZE            512
 
 struct imsgbuf {
        int                     fd;
@@ -264,14 +263,18 @@ int        imsg_close(struct imsgbuf *, struct
 void    imsg_free(struct imsg *);
 
 /* ntp.c */
-pid_t   ntp_main(int[2], struct ntpd_conf *, struct passwd *);
-int     priv_adjtime(void);
-void    priv_settime(double);
-void    priv_host_dns(char *, u_int32_t);
-int     offset_compare(const void *, const void *);
-void    update_scale(double);
-time_t  scale_interval(time_t);
-time_t  error_interval(void);
+pid_t  ntp_main(int[2], struct ntpd_conf *, struct passwd *);
+int    priv_adjtime(void);
+void   priv_settime(int64_t);
+void   priv_host_dns(char *, u_int32_t);
+int    offset_compare(const void *, const void *);
+void   update_scale(int64_t);
+time_t scale_interval(time_t);
+time_t error_interval(void);
+int64_t        gettime_corrected(void);
+void   getoffset(struct timeval *);
+int64_t        gettime(void);
+time_t getmonotime(void);
 extern struct ntpd_conf *conf;
 
 /* parse.y */
@@ -301,23 +304,12 @@ int       client_dispatch(struct ntp_peer *, u
 void   client_log_error(struct ntp_peer *, const char *, int);
 void   set_next(struct ntp_peer *, time_t);
 
-/* util.c */
-double                 gettime_corrected(void);
-double                 getoffset(void);
-double                 gettime(void);
-time_t                 getmonotime(void);
-void                   d_to_tv(double, struct timeval *);
-double                 lfp_to_d(struct l_fixedpt);
-struct l_fixedpt       d_to_lfp(double);
-double                 sfp_to_d(struct s_fixedpt);
-struct s_fixedpt       d_to_sfp(double);
-
 /* sensors.c */
-void                   sensor_init(void);
-int                    sensor_scan(void);
-void                   sensor_query(struct ntp_sensor *);
-int                    sensor_hotplugfd(void);
-void                   sensor_hotplugevent(int);
+void   sensor_init(void);
+int    sensor_scan(void);
+void   sensor_query(struct ntp_sensor *);
+int    sensor_hotplugfd(void);
+void   sensor_hotplugevent(int);
 
 /* ntp_dns.c */
 pid_t  ntp_dns(int[2], struct ntpd_conf *, struct passwd *);
Index: sensors.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/sensors.c,v
retrieving revision 1.3
diff -u -p -r1.3 sensors.c
--- sensors.c   13 May 2009 18:10:04 -0000      1.3
+++ sensors.c   15 May 2009 14:26:36 -0000
@@ -121,7 +121,7 @@ sensor_add(int sensordev, char *dxname)
 
        s->next = getmonotime();
        s->weight = cs->weight;
-       s->correction = cs->correction;
+       s->correction = us2int64(cs->correction);
        if ((s->device = strdup(dxname)) == NULL)
                fatal("sensor_add strdup");
        s->sensordevid = sensordev;
@@ -135,8 +135,10 @@ sensor_add(int sensordev, char *dxname)
 
        TAILQ_INSERT_TAIL(&conf->ntp_sensors, s, entry);
 
-       log_debug("sensor %s added (weight %d, correction %.6f, refstr %.4s)",
-           s->device, s->weight, s->correction / 1e6, &s->refid);
+       log_debug(
+           "sensor %s added (weight %d, correction %d.%06u, refstr %-4s)",
+           s->device, s->weight,
+           cs->correction / 1000000, cs->correction % 1000000, &s->refid);
 }
 
 void
@@ -152,6 +154,7 @@ sensor_query(struct ntp_sensor *s)
 {
        char             dxname[MAXDEVNAMLEN];
        struct sensor    sensor;
+       struct timeval   tv;
 
        if (conf->settime)
                s->next = getmonotime() + SENSOR_QUERY_INTERVAL_SETTIME;
@@ -186,16 +189,17 @@ sensor_query(struct ntp_sensor *s)
         * sensor.value = TS - TD in ns
         * if value is positive, system time is ahead
         */
-       s->offsets[s->shift].offset = (sensor.value / -1e9) - getoffset() +
-           (s->correction / 1e6);
+       getoffset(&tv);
+       s->offsets[s->shift].offset = s->correction +
+           us2int64(sensor.value / 1000) - timeval2int64(&tv);
        s->offsets[s->shift].rcvd = sensor.tv.tv_sec;
        s->offsets[s->shift].good = 1;
 
        s->offsets[s->shift].status.send_refid = s->refid;
-       s->offsets[s->shift].status.stratum = 0;        /* increased when sent 
out */
+       s->offsets[s->shift].status.stratum = 0;  /* increased when sent out */
        s->offsets[s->shift].status.rootdelay = 0;
        s->offsets[s->shift].status.rootdispersion = 0;
-       s->offsets[s->shift].status.reftime = sensor.tv.tv_sec;
+       s->offsets[s->shift].status.reftime = timeval2int64(&sensor.tv);
        s->offsets[s->shift].status.synced = 1;
 
        log_debug("sensor %s: offset %f", s->device,
@@ -226,10 +230,9 @@ sensor_update(struct ntp_sensor *s)
 
        i = SENSOR_OFFSETS / 2;
        memcpy(&s->update, offsets[i], sizeof(s->update));
-       if (SENSOR_OFFSETS % 2 == 0) {
+       if (SENSOR_OFFSETS % 2 == 0)
                s->update.offset =
                    (offsets[i - 1]->offset + offsets[i]->offset) / 2;
-       }
        free(offsets);
 
        log_debug("sensor update %s: offset %f", s->device, s->update.offset);
Index: server.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/server.c,v
retrieving revision 1.3
diff -u -p -r1.3 server.c
--- server.c    13 May 2009 18:10:04 -0000      1.3
+++ server.c    15 May 2009 14:26:36 -0000
@@ -127,11 +127,11 @@ server_dispatch(int fd, struct ntpd_conf
 {
        ssize_t                  size;
        u_int8_t                 version;
-       double                   rectime;
        struct sockaddr_storage  fsa;
        socklen_t                fsa_len;
        struct ntp_msg           query, reply;
        char                     buf[NTP_MSGSIZE];
+       int64_t                  rectime;
 
        fsa_len = sizeof(fsa);
        if ((size = recvfrom(fd, &buf, sizeof(buf), 0,
@@ -146,7 +146,6 @@ server_dispatch(int fd, struct ntpd_conf
        }
 
        rectime = gettime_corrected();
-
        if (ntp_getmsg((struct sockaddr *)&fsa, buf, size, &query) == -1)
                return (0);
 
@@ -163,15 +162,16 @@ server_dispatch(int fd, struct ntpd_conf
        else
                reply.status |= MODE_SYM_PAS;
 
+       reply.refid = lconf->status.refid;
        reply.stratum = lconf->status.stratum;
        reply.ppoll = query.ppoll;
        reply.precision = lconf->status.precision;
-       reply.rectime = d_to_lfp(rectime);
-       reply.reftime = d_to_lfp(lconf->status.reftime);
-       reply.xmttime = d_to_lfp(gettime_corrected());
        reply.orgtime = query.xmttime;
-       reply.rootdelay = d_to_sfp(lconf->status.rootdelay);
-       reply.refid = lconf->status.refid;
+       int642lfxt(rectime, &reply.rectime);
+       int642lfxt(lconf->status.reftime, &reply.reftime);
+       int642sfxt(lconf->status.rootdelay, &reply.rootdelay);
+       rectime = gettime_corrected();
+       int642lfxt(rectime, &reply.xmttime);  
 
        ntp_sendmsg(fd, (struct sockaddr *)&fsa, &reply, size, 0);
        return (0);
Index: util.c
===================================================================
RCS file: util.c
diff -N util.c
--- util.c      26 Aug 2008 14:44:25 -0000      1.1.1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,118 +0,0 @@
-
-/*
- * Copyright (c) 2004 Alexander Guy <alexander....@andern.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/time.h>
-#include <limits.h>
-
-#include "ntpd.h"
-
-double
-gettime_corrected(void)
-{
-       return (gettime() + getoffset());
-}
-
-double
-getoffset(void)
-{
-       struct timeval  tv;
-       if (adjtime(NULL, &tv) == -1)
-               return (0.0);
-       return (tv.tv_sec + 1.0e-6 * tv.tv_usec);
-}
-
-double
-gettime(void)
-{
-       struct timeval  tv;
-
-       if (gettimeofday(&tv, NULL) == -1)
-               fatal("gettimeofday");
-
-       return (tv.tv_sec + JAN_1970 + 1.0e-6 * tv.tv_usec);
-}
-
-time_t
-getmonotime(void)
-{
-       struct timespec ts;
-
-       if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
-               fatal("clock_gettime");
-
-       return (ts.tv_sec);
-}
-
-
-void
-d_to_tv(double d, struct timeval *tv)
-{
-       tv->tv_sec = (long)d;
-       tv->tv_usec = (d - tv->tv_sec) * 1000000;
-       while (tv->tv_usec < 0) {
-               tv->tv_usec += 1000000;
-               tv->tv_sec -= 1;
-       }
-}
-
-double
-lfp_to_d(struct l_fixedpt lfp)
-{
-       double  ret;
-
-       lfp.int_partl = ntohl(lfp.int_partl);
-       lfp.fractionl = ntohl(lfp.fractionl);
-
-       ret = (double)(lfp.int_partl) + ((double)lfp.fractionl / UINT_MAX);
-
-       return (ret);
-}
-
-struct l_fixedpt
-d_to_lfp(double d)
-{
-       struct l_fixedpt        lfp;
-
-       lfp.int_partl = htonl((u_int32_t)d);
-       lfp.fractionl = htonl((u_int32_t)((d - (u_int32_t)d) * UINT_MAX));
-
-       return (lfp);
-}
-
-double
-sfp_to_d(struct s_fixedpt sfp)
-{
-       double  ret;
-
-       sfp.int_parts = ntohs(sfp.int_parts);
-       sfp.fractions = ntohs(sfp.fractions);
-
-       ret = (double)(sfp.int_parts) + ((double)sfp.fractions / USHRT_MAX);
-
-       return (ret);
-}
-
-struct s_fixedpt
-d_to_sfp(double d)
-{
-       struct s_fixedpt        sfp;
-
-       sfp.int_parts = htons((u_int16_t)d);
-       sfp.fractions = htons((u_int16_t)((d - (u_int16_t)d) * USHRT_MAX));
-
-       return (sfp);
-}

Reply via email to