On Sat, May 16, 2009 at 20:41 +0000, Michael Shalayeff wrote:
> re
> suddenly bugs started to popup (:

looks like i hit this bug also.

ntpd[7676]: Lost child: child terminated; signal 8 (Floating point exception)

> there was a division by zero in poll scaling.
> i guess the offset never been small enough (:
> i would really appreciate if somebody actually
> read through the diff for possibly more tiny little
> stupid mistakes that might've crept in (:
> cu
> 
> On Fri, May 15, 2009 at 04:13:29PM +0000, Michael Shalayeff wrote:
> > re
> > we've found a real bug behind the buffer sizes.
> > dns resolver was not limiting the response (ip list)
> > to any maximum number which is even defined already
> > as MAX_SERVERS_DNS. thus check that now.
> > now we can get away w/ much smaller buffers and
> > correct (non-overflowing) behaviour (;
> > cu
> > 
> > On Fri, May 15, 2009 at 03:19:02PM +0000, Michael Shalayeff wrote:
> > > re
> > > first try out of the zoo shown that we need to keep MAX_IMSGSIZE
> > > at 8k for more dns addresses (:
> > > diff updated
> > > cu
> > > 
> > > On Fri, May 15, 2009 at 02:58:36PM +0000, Michael Shalayeff wrote:
> > > > re
> > > > forgot to mention that while there touching structs
> > > > also rearrange fields for optimal alignment (save memory)
> > > > and shrink io buffers to a half K from 8k since we will
> > > > never have a valid packet larger than that.
> > > > cu
> > > > 
> > > > On Fri, May 15, 2009 at 02:39:29PM +0000, Michael Shalayeff wrote:
> > > > > 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.
> 
> 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  16 May 2009 19:04:47 -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  16 May 2009 19:04:47 -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     16 May 2009 19:04:48 -0000
> @@ -1,4 +1,3 @@
> -
>  /*
>   * Copyright (c) 2003, 2004 Henning Brauer <[email protected]>
>   * Copyright (c) 2004 Alexander Guy <[email protected]>
> @@ -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();
> +     struct timeval tv;
> +     int64_t qsmax, qsmin;
> +
> +     getoffset(&tv);
> +     offset += timeval2int64(&tv);
>       if (offset < 0)
> -             offset = -offset;
> +             offset = (-offset);
>  
> -     if (offset > QSCALE_OFF_MAX || !conf->status.synced ||
> -         conf->freq.num < 3)
> +     qsmax = int64init(QSCALE_OFF_MAX / 1000000, QSCALE_OFF_MAX % 1000000);
> +     qsmin = int64init(QSCALE_OFF_MIN / 1000000, QSCALE_OFF_MIN % 1000000);
> +     if (offset > qsmax || !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 if (offset < qsmin)
> +             conf->scale = qsmax / QSCALE_OFF_MIN;
>       else
> -             conf->scale = QSCALE_OFF_MAX / offset;
> +             conf->scale = qsmax / offset;
>  }
>  
>  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     16 May 2009 19:04:48 -0000
> @@ -43,11 +43,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 +137,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 +169,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: ntp_dns.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ntpd/ntp_dns.c,v
> retrieving revision 1.2
> diff -u -p -r1.2 ntp_dns.c
> --- ntp_dns.c 14 May 2009 12:23:33 -0000      1.2
> +++ ntp_dns.c 16 May 2009 19:04:48 -0000
> @@ -147,14 +147,15 @@ dns_dispatch_imsg(void)
>                               fatalx("invalid IMSG_HOST_DNS received");
>                       if ((cnt = host_dns(name, &hn, conf)) == -1)
>                               break;
> +                     if (cnt > MAX_SERVERS_DNS)
> +                             cnt = MAX_SERVERS_DNS;
>                       buf = imsg_create(ibuf_dns, IMSG_HOST_DNS,
>                           imsg.hdr.peerid, 0,
>                           cnt * sizeof(struct sockaddr_storage));
>                       if (buf == NULL)
>                               break;
> -                     if (cnt > 0)
> -                             for (h = hn; h != NULL; h = h->next)
> -                                     imsg_add(buf, &h->ss, sizeof(h->ss));
> +                     for (h = hn; cnt-- && h != NULL; h = h->next)
> +                             imsg_add(buf, &h->ss, sizeof(h->ss));
>  
>                       imsg_close(ibuf_dns, buf);
>                       break;
> 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    16 May 2009 19:04:48 -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,48 @@ ntpd_adjtime(double d)
>  }
>  
>  void
> -ntpd_adjfreq(double relfreq, int wrlog)
> +ntpd_adjfreq(int64_t relfreq, int wrlog)
>  {
>       int64_t curfreq;
> -     double ppmfreq;
>       int r;
>  
>       if (adjfreq(NULL, &curfreq) == -1) {
>               log_warn("adjfreq failed");
>               return;
>       }
> +     curfreq += relfreq;
> +     if (adjfreq(&curfreq, NULL) == -1)
> +             log_warn("adjfreq failed");
>  
>       /*
> -      * 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;
> +     r = writefreq(curfreq);
>       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)");
> -     }
> +             char *s1 = "", *s2 = "";
>  
> -     if (adjfreq(&curfreq, NULL) == -1)
> -             log_warn("adjfreq failed");
> +             if (relfreq < 0) {
> +                     relfreq = -relfreq;
> +                     s1 = "-";
> +             }
> +             if (curfreq < 0) {
> +                     curfreq = -curfreq;
> +                     s2 = "-";
> +             }
> +             log_info("adjusting clock frequency by %s0.%06d to "
> +                 "%s%d.%06dppm%s",
> +                 s1, (int)(relfreq >> 32) % 1000000,
> +                 s2, (int)(curfreq >> 32) / 1000000,
> +                 (int)(curfreq >> 32) % 1000000,
> +                 r ? " (no drift file)" : "");
> +     }
>  }
>  
>  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 +444,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 +455,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 +478,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 +487,7 @@ readfreq(void)
>  }
>  
>  int
> -writefreq(double d)
> +writefreq(int64_t d)
>  {
>       int r;
>       FILE *fp;
> @@ -484,10 +499,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 +510,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    16 May 2009 19:04:48 -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           (256 * 10)
>  
>  #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                  10000   /* 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            (256 * 10)
>  
>  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 16 May 2009 19:04:48 -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  16 May 2009 19:04:48 -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 <[email protected]>
> - *
> - * 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