From: Juergen Perlinger Date: Thu, 3 Jan 2019 22:58:11 +0000 (+0100) Subject: refactor 'struct timex' access (MOD_NANO/STA_NANO) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2f23626b14e209926ad09174b92fb24d9bad2f08;p=thirdparty%2Fntp.git refactor 'struct timex' access (MOD_NANO/STA_NANO) bk: 5c2e93837Co2Ubu-gP0VwtVlN0Yjng --- diff --git a/include/timexsup.h b/include/timexsup.h new file mode 100644 index 000000000..81afe41e2 --- /dev/null +++ b/include/timexsup.h @@ -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 -*- */ diff --git a/libntp/Makefile.am b/libntp/Makefile.am index 04b53b0cb..37bb66200 100644 --- a/libntp/Makefile.am +++ b/libntp/Makefile.am @@ -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 index 000000000..5f7b7730f --- /dev/null +++ b/libntp/timexsup.c @@ -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 +#include + +#ifdef HAVE_SYS_TIMEX_H +# include +#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); +} + diff --git a/ntpd/ntp_loopfilter.c b/ntpd/ntp_loopfilter.c index 01772bd1f..b9ed675de 100644 --- a/ntpd/ntp_loopfilter.c +++ b/ntpd/ntp_loopfilter.c @@ -15,6 +15,7 @@ #include "ntp_io.h" #include "ntp_unixtime.h" #include "ntp_stdlib.h" +#include "timexsup.h" #include #include @@ -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