]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
refactor 'struct timex' access (MOD_NANO/STA_NANO)
authorJuergen Perlinger <perlinger@ntp.org>
Thu, 3 Jan 2019 22:58:11 +0000 (23:58 +0100)
committerJuergen Perlinger <perlinger@ntp.org>
Thu, 3 Jan 2019 22:58:11 +0000 (23:58 +0100)
bk: 5c2e93837Co2Ubu-gP0VwtVlN0Yjng

include/timexsup.h [new file with mode: 0644]
libntp/Makefile.am
libntp/timexsup.c [new file with mode: 0644]
ntpd/ntp_loopfilter.c

diff --git a/include/timexsup.h b/include/timexsup.h
new file mode 100644 (file)
index 0000000..81afe41
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * timexsup.h - 'struct timex' support functions
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ */
+#ifndef TIMEXSUP_H
+#define TIMEXSUP_H
+
+
+/* convert a 'long' time value (in usec or nsec) into seconds, expressed
+ * as a 'double'. If 'STA_NANO' is not defined, this will always convert
+ * from usec. ('STA_NANO' is Linux specific at the time of this
+ * writing.)
+ *
+ * If 'STA_NANO' is defined, it will be checked in 'status' to decide
+ * which time base (usec or nsec) applies for this conversion.
+ */
+extern double dbl_from_var_long(long lval, int status);
+
+/* convert a 'long' time value in usec into seconds, expressed as
+ * 'double'.  This function is there for pure symmetry right now -- it
+ * just casts and scales without any additional bells and whistles.
+ */ 
+extern double dbl_from_usec_long(long lval);
+
+/* If MOD_NANO is defined, set the MOD_NANO bit in '*modes' and
+ * calculate the time stamp in nsec; otherwise, calculate the result in
+ * usec.
+ *
+ * Applies proper bounds checks and saturation on LONG_MAX/LONG_MIN to
+ * avoid undefined behaviour.
+ */
+extern long var_long_from_dbl(double dval, unsigned int *modes);
+
+/* convert a 'double' time value (in seconds) into usec with proper
+ * bounds check and range clamp.
+ */
+extern long usec_long_from_dbl(double dval);
+
+#endif
+/* -*- that's all folks -*- */
index 04b53b0cbe971506c3aa4b7a5b68778fea1052d4..37bb662002dd63b6d59e01bb792f8847cdee1883 100644 (file)
@@ -106,6 +106,7 @@ libntp_a_SRCS =                                             \
        syssignal.c                                     \
        timetoa.c                                       \
        timevalops.c                                    \
+       timexsup.c                                      \
        uglydate.c                                      \
        vint64ops.c                                     \
        work_fork.c                                     \
diff --git a/libntp/timexsup.c b/libntp/timexsup.c
new file mode 100644 (file)
index 0000000..5f7b773
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * timexsup.c - 'struct timex' support functions
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ */
+
+#include "config.h"
+#include "timexsup.h"
+#include <limits.h>
+#include <math.h>
+
+#ifdef HAVE_SYS_TIMEX_H
+# include <sys/timex.h>
+#endif
+
+#if defined(MOD_NANO) != defined(STA_NANO)
+# warning inconsistent definitions of MOD_NANO vs STA_NANO
+#endif
+
+static long
+clamp_rounded(
+       double dval
+       )
+{
+       /* round */
+       dval = floor(dval + 0.5);
+
+       /* clamp / saturate */
+       if (dval >= LONG_MAX)
+               return LONG_MAX;
+       if (dval <= LONG_MIN)
+               return LONG_MIN;
+       return (long)dval;
+       
+}
+double
+dbl_from_var_long(
+       long    lval,
+       int     status
+       )
+{
+#ifdef STA_NANO
+       if (status & STA_NANO)
+               return (double)lval * 1e-9;
+#else
+       (void)status;
+#endif
+       return (double)lval * 1e-6;
+}
+
+double
+dbl_from_usec_long(
+       long    lval
+       )
+{
+       return (double)lval * 1e-6;
+}
+
+long
+var_long_from_dbl(
+       double          dval,
+       unsigned int *  modes
+       )
+{
+#ifdef MOD_NANO
+       *modes |= MOD_NANO;
+       dval *= 1e+9;
+#else
+       (void)modes;
+       dval *= 1e+6;
+#endif
+       return clamp_rounded(dval);
+}
+
+long
+usec_long_from_dbl(
+       double          dval
+       )
+{
+       return clamp_rounded(dval * 1e+6);
+}
+
index 01772bd1ffe9e1bdcdc0a63ff5afbf3b47862f7e..b9ed675dee35e6014e819880d8ca37f24644797e 100644 (file)
@@ -15,6 +15,7 @@
 #include "ntp_io.h"
 #include "ntp_unixtime.h"
 #include "ntp_stdlib.h"
+#include "timexsup.h"
 
 #include <limits.h>
 #include <stdio.h>
@@ -761,30 +762,21 @@ local_clock(
                if (ext_enable) {
                        ntv.modes = MOD_STATUS;
                } else {
-#ifdef STA_NANO
-                       ntv.modes = MOD_BITS | MOD_NANO;
-#else /* STA_NANO */
                        ntv.modes = MOD_BITS;
-#endif /* STA_NANO */
-                       if (clock_offset < 0)
-                               dtemp = -.5;
-                       else
-                               dtemp = .5;
+                       ntv.offset = var_long_from_dbl(
+                           clock_offset, &ntv.modes);
 #ifdef STA_NANO
-                       ntv.offset = (int32)(clock_offset * 1e9 +
-                           dtemp);
                        ntv.constant = sys_poll;
 #else /* STA_NANO */
-                       ntv.offset = (int32)(clock_offset * 1e6 +
-                           dtemp);
                        ntv.constant = sys_poll - 4;
 #endif /* STA_NANO */
                        if (ntv.constant < 0)
                                ntv.constant = 0;
 
-                       ntv.esterror = (u_int32)(clock_jitter * 1e6);
-                       ntv.maxerror = (u_int32)((sys_rootdelay / 2 +
-                           sys_rootdisp) * 1e6);
+                       ntv.esterror = usec_long_from_dbl(
+                               clock_jitter);
+                       ntv.maxerror = usec_long_from_dbl(
+                               sys_rootdelay / 2 + sys_rootdisp);
                        ntv.status = STA_PLL;
 
                        /*
@@ -823,22 +815,15 @@ local_clock(
                        ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, hardpps_enable, 0, __LINE__ - 1);
                }
                pll_status = ntv.status;
-#ifdef STA_NANO
-               clock_offset = ntv.offset / 1e9;
-#else /* STA_NANO */
-               clock_offset = ntv.offset / 1e6;
-#endif /* STA_NANO */
+               clock_offset = dbl_from_var_long(ntv.offset, ntv.status);
                clock_frequency = FREQTOD(ntv.freq);
 
                /*
                 * If the kernel PPS is lit, monitor its performance.
                 */
                if (ntv.status & STA_PPSTIME) {
-#ifdef STA_NANO
-                       clock_jitter = ntv.jitter / 1e9;
-#else /* STA_NANO */
-                       clock_jitter = ntv.jitter / 1e6;
-#endif /* STA_NANO */
+                       clock_jitter = dbl_from_var_long(
+                               ntv.jitter, ntv.status);
                }
 
 #if defined(STA_NANO) && NTP_API == 4