--- /dev/null
+/*
+ * 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 -*- */
syssignal.c \
timetoa.c \
timevalops.c \
+ timexsup.c \
uglydate.c \
vint64ops.c \
work_fork.c \
--- /dev/null
+/*
+ * 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);
+}
+
#include "ntp_io.h"
#include "ntp_unixtime.h"
#include "ntp_stdlib.h"
+#include "timexsup.h"
#include <limits.h>
#include <stdio.h>
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;
/*
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