Some code in ntpd applies a dither using ntp_random.  However,
ntp_random (which is also used elsewhere, e.g. in getting an
initial association ID) generates only positive integers,
resulting in a one-sided offset bias.  The following patch
compensates for this bias by offsetting the return value
from ntp_random to produce approximately zero mean dither
in both positive and negative offset directions in the
functions which use ntp_random for dither.

*** libntp/systime.c.orig       Wed Dec  9 02:36:35 2009
--- libntp/systime.c    Sat Nov 19 09:10:31 2011
***************
*** 62,67 ****
--- 62,68 ----
        )
  {
        double  dtemp;
+       long correction = (1L << 30) + 1L; /* compensate for ntp_random bias */
  
  #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_GETCLOCK)
        struct timespec ts;     /* seconds and nanoseconds */
***************
*** 78,86 ****
        now->l_i = (int32)ts.tv_sec + JAN_1970;
        dtemp = 0;
        if (sys_tick > FUZZ)
!               dtemp = ntp_random() * 2. / FRAC * sys_tick * 1e9;
        else if (sys_tick > 0)
!               dtemp = ntp_random() * 2. / FRAC;
        dtemp = (ts.tv_nsec + dtemp) * 1e-9 + sys_residual;
        if (dtemp >= 1.) {
                dtemp -= 1.;
--- 79,87 ----
        now->l_i = (int32)ts.tv_sec + JAN_1970;
        dtemp = 0;
        if (sys_tick > FUZZ)
!               dtemp = (ntp_random() - correction) * 2. / FRAC * sys_tick * 
1e9;
        else if (sys_tick > 0)
!               dtemp = (ntp_random() - correction) * 2. / FRAC;
        dtemp = (ts.tv_nsec + dtemp) * 1e-9 + sys_residual;
        if (dtemp >= 1.) {
                dtemp -= 1.;
***************
*** 102,110 ****
        now->l_i = tv.tv_sec + JAN_1970;
        dtemp = 0;
        if (sys_tick > FUZZ)
!               dtemp = ntp_random() * 2. / FRAC * sys_tick * 1e6;
        else if (sys_tick > 0)
!               dtemp = ntp_random() * 2. / FRAC;
        dtemp = (tv.tv_usec + dtemp) * 1e-6 + sys_residual;
        if (dtemp >= 1.) {
                dtemp -= 1.;
--- 103,111 ----
        now->l_i = tv.tv_sec + JAN_1970;
        dtemp = 0;
        if (sys_tick > FUZZ)
!               dtemp = (ntp_random() - correction) * 2. / FRAC * sys_tick * 
1e6;
        else if (sys_tick > 0)
!               dtemp = (ntp_random() - correction) * 2. / FRAC;
        dtemp = (tv.tv_usec + dtemp) * 1e-6 + sys_residual;
        if (dtemp >= 1.) {
                dtemp -= 1.;
*** ntpd/ntp_io.c.orig  Sat Dec 25 04:40:36 2010
--- ntpd/ntp_io.c       Sat Oct 29 08:12:06 2011
***************
*** 3344,3350 ****
                                    tvp->tv_sec, tvp->tv_usec));
                        nts.l_i = tvp->tv_sec + JAN_1970;
                        dtemp = (tvp->tv_usec 
!                                + (ntp_random() * 2. / FRAC)) / 1e6;
                        nts.l_uf = (u_int32)(dtemp * FRAC);
  #ifdef DEBUG_TIMING
                        {
--- 3344,3350 ----
                                    tvp->tv_sec, tvp->tv_usec));
                        nts.l_i = tvp->tv_sec + JAN_1970;
                        dtemp = (tvp->tv_usec 
!                                + ((ntp_random() - (1L << 30) - 1) * 2. / 
FRAC)) / 1e6;
                        nts.l_uf = (u_int32)(dtemp * FRAC);
  #ifdef DEBUG_TIMING
                        {

_______________________________________________
questions mailing list
questions@lists.ntp.org
http://lists.ntp.org/listinfo/questions

Reply via email to