# 2.11BSD#431 - /usr/src/usr.sbin/ntp/ntp_adjust.c

##### Functions

    adj_host_clock    X
    adj_logical       X
    init_logical_clockX

##### Variables

    adj_precision     X
    adj_residual      X
    adjustment        X
    drift_comp        X
    firstpass         X
    update_timer      X

##### Macros

    abs               X

       1: #if !defined(lint) && defined(DOSCCS)
       2: static char *RCSid = "$Source: /usr/src/new/ntp/ntp_adjust.c,v $ $Revision: 3.4.1.5 $ $Date: 95/01/27 17:23:36 $";
       3: #endif
       4:
       5: /*
       6:  * This module implemenets the logical Local Clock, as described in section
       7:  * 5. of the NTP specification.
       8:  *
       9:  * $Log:	ntp_adjust.c,v $
      10:  * Revision 3.4.1.5  95/01/27  17:23:36  sms
      11:  * Remove SETTICKADJ - see rational in ntpd.c
      12:  *
      13:  * Revision 3.4.1.4  89/05/18  18:23:36  louie
      14:  * A couple of changes to debug NeXT support in ntp_adjust.c
      15:  *
      16:  * Revision 3.4.1.3  89/04/07  18:05:17  louie
      17:  * Removed unused variable from ntp_adjust.c module.
      18:  *
      19:  * Revision 3.4.1.2  89/03/22  18:30:52  louie
      20:  * patch3: Use new RCS headers.
      21:  *
      22:  * Revision 3.4.1.1  89/03/20  00:09:06  louie
      23:  * patch1: Don't zero the drift compensation or compliance values when a step
      24:  * patch1: adjustment of the clock occurs.  Use symbolic definition of
      25:  * patch1: CLOCK_FACTOR rather than constant.
      26:  *
      27:  * Revision 3.4  89/03/17  18:37:03  louie
      28:  * Latest test release.
      29:  *
      30:  * Revision 3.3.1.2  89/03/17  18:25:03  louie
      31:  * Applied suggested code from Dennis Ferguson for logical clock model based on
      32:  * the equations in section 5.  Many thanks.
      33:  *
      34:  * Revision 3.3.1.1  89/03/16  19:19:29  louie
      35:  * Attempt to implement using the equations in section 5 of the NTP spec,
      36:  * rather then modeling the Fuzzball implementation.
      37:  *
      38:  * Revision 3.3  89/03/15  14:19:45  louie
      39:  * New baseline for next release.
      40:  *
      41:  * Revision 3.2.1.1  89/03/15  13:47:24  louie
      42:  * Use "%f" in format strings rather than "%lf".
      43:  *
      44:  * Revision 3.2  89/03/07  18:22:54  louie
      45:  * New version of UNIX NTP daemon and software based on the 6 March 1989
      46:  * draft of the new NTP protocol specification.  This module attempts to
      47:  * conform to the new logical clock described in section 5 of the spec.  Note
      48:  * that the units of the drift_compensation register have changed.
      49:  *
      50:  * This version also accumulates the residual adjtime() truncation and
      51:  * adds it in on subsequent adjustments.
      52:  *
      53:  * Revision 3.1.1.1  89/02/15  08:55:48  louie
      54:  * *** empty log message ***
      55:  *
      56:  *
      57:  * Revision 3.1  89/01/30  14:43:08  louie
      58:  * Second UNIX NTP test release.
      59:  *
      60:  * Revision 3.0  88/12/12  16:00:38  louie
      61:  * Test release of new UNIX NTP software.  This version should conform to the
      62:  * revised NTP protocol specification.
      63:  *
      64:  */
      65:
      66: #include <stdio.h>
      67: #include <sys/types.h>
      68: #include <sys/param.h>
      69: #include <sys/socket.h>
      70: #include <sys/time.h>
      71: #include <sys/ioctl.h>
      72: #include <sys/resource.h>
      73:
      74: #include <netinet/in.h>
      75: #include <netinet/in_systm.h>
      76: #include <netinet/ip.h>
      77: #include <netinet/udp.h>
      78:
      79: #include <arpa/inet.h>
      80: #include <netdb.h>
      81: #include <strings.h>
      82: #include <errno.h>
      83: #include <syslog.h>
      84:
      85: #include "ntp.h"
      86:
      87: #ifdef  DEBUG
      88: extern int debug;
      89: #endif
      90:
      91: extern int doset;
      92: extern int debuglevel;
      93: extern char *ntoa();
      94: extern struct sysdata sys;
      95:
      96: double  drift_comp = 0.0,
      97:     compliance,
      98:     clock_adjust;
      99: long    update_timer = 0;
     100:
     101: int adj_precision;
     102: double  adj_residual;
     103: int firstpass = 1;
     104:
     105: #define abs(x)  ((x) < 0 ? -(x) : (x))
     106:
     107: void
     108: init_logical_clock()
     109: {
     110:     adj_precision = 1;
     111:     /*
     112: 	 *  If you have the "fix" for adjtime() installed in you kernel, you'll
     113: 	 *  have to make sure that adj_precision is set to 1 here.
     114: 	 */
     115: }
     116:
     117:
     118: /*
     119:  *  5.0 Logical clock procedure
     120:  *
     121:  *  Only paramter is an offset to vary the clock by, in seconds.  We'll either
     122:  *  arrange for the clock to slew to accomodate the adjustment, or just preform
     123:  *  a step adjustment if the offset is too large.
     124:  *
     125:  *  The update which is to be performed is left in the external
     126:  *  clock_adjust.
     127:  *
     128:  *  Returns non-zero if clock was reset rather than slewed.
     129:  *
     130:  *  Many thanks for Dennis Ferguson <dennis@gw.ccie.utoronto.ca> for his
     131:  *  corrections to my code.
     132:  */
     133:
     134: int
     135: adj_logical(offset)
     136:     double offset;
     137: {
     138:     struct timeval tv1, tv2;
     139: #ifdef  XADJTIME2
     140:     struct timeval delta, olddelta;
     141: #endif
     142:
     143:     /*
     144: 	 *  Now adjust the logical clock
     145: 	 */
     146:     if (!doset)
     147:         return 0;
     148:
     149:     adj_residual = 0.0;
     150:     if (offset > CLOCK_MAX || offset < -CLOCK_MAX) {
     151:         double steptime = offset;
     152:
     153:         (void) gettimeofday(&tv2, (struct timezone *) 0);
     154:         steptime += tv2.tv_sec;
     155:         steptime += tv2.tv_usec / 1000000.0;
     156:         tv1.tv_sec = steptime;
     157:         tv1.tv_usec = (steptime - tv1.tv_sec) * 1000000;
     158: #ifdef  DEBUG
     159:         if (debug > 2) {
     160:             steptime = (tv1.tv_sec + tv1.tv_usec/1000000.0) -
     161:                 (tv2.tv_sec + tv2.tv_usec/1000000.0);
     162:             printf("adj_logical: %f %f\n", offset, steptime);
     163:         }
     164: #endif
     165:         if (settimeofday(&tv1, (struct timezone *) 0) < 0) {
     166:             syslog(LOG_ERR, "Can't set time: %m");
     167:             return(-1);
     168:         }
     169:         clock_adjust = 0.0;
     170:         firstpass = 1;
     171:         update_timer = 0;
     172:         return (1);   /* indicate that step adjustment was done */
     173:     } else  {
     174:         double ai;
     175:
     176:         /*
     177: 		 * If this is our very first adjustment, don't touch
     178: 		 * the drift compensation (this is f in the spec
     179: 		 * equations), else update using the *old* value
     180: 		 * of the compliance.
     181: 		 */
     182:         clock_adjust = offset;
     183:         if (firstpass)
     184:             firstpass = 0;
     185:         else if (update_timer > 0) {
     186:             ai = abs(compliance);
     187:             ai = (double)(1<<CLOCK_COMP) -
     188:                 (double)(1<<CLOCK_FACTOR) * ai;
     189:             if (ai < 1.0)       /* max(... , 1.0) */
     190:                 ai = 1.0;
     191:             drift_comp += offset / (ai * (double)update_timer);
     192:         }
     193:
     194:         /*
     195: 		 * Set the timer to zero.  adj_host_clock() increments it
     196: 		 * so we can tell the period between updates.
     197: 		 */
     198:         update_timer = 0;
     199:
     200:         /*
     201: 		 * Now update the compliance.  The compliance is h in the
     202: 		 * equations.
     203: 		 */
     204:         compliance += (offset - compliance)/(double)(1<<CLOCK_TRACK);
     205:
     206: #ifdef XADJTIME2
     207:         delta.tv_sec = offset;
     208:         delta.tv_usec = (offset - delta.tv_sec) * 1000;
     209:         (void) adjtime2(&delta, &olddelta);
     210: #endif
     211:         return(0);
     212:     }
     213: }
     214:
     215: #ifndef XADJTIME2
     216: extern int adjtime();
     217:
     218: /*
     219:  *  This is that routine that performs the periodic clock adjustment.
     220:  *  The procedure is best described in the the NTP document.  In a
     221:  *  nutshell, we prefer to do lots of small evenly spaced adjustments.
     222:  *  The alternative, one large adjustment, creates two much of a
     223:  *  clock disruption and as a result oscillation.
     224:  *
     225:  *  This function is called every 2**CLOCK_ADJ seconds.
     226:  *
     227:  */
     228:
     229: /*
     230:  * global for debugging?
     231:  */
     232: double adjustment;
     233:
     234: void
     235: adj_host_clock()
     236: {
     237:
     238:     struct timeval delta, olddelta;
     239:
     240:     if (!doset)
     241:         return;
     242:
     243:     /*
     244: 	 * Add update period into timer so we know how long it
     245: 	 * took between the last update and the next one.
     246: 	 */
     247:     update_timer += 1<<CLOCK_ADJ;
     248:     /*
     249: 	 * Should check to see if update_timer > 1 day here?
     250: 	 */
     251:
     252:     /*
     253: 	 * Compute phase part of adjustment here and update clock_adjust.
     254: 	 * Note that the equations used here are implicit in the last
     255: 	 * two equations in the spec (in particular, look at the equation
     256: 	 * for g and figure out how to  find the k==1 term given the k==0 term.)
     257: 	 */
     258:     adjustment = clock_adjust / (double)(1<<CLOCK_PHASE);
     259:     clock_adjust -= adjustment;
     260:
     261:     /*
     262: 	 * Now add in the frequency component.  Be careful to note that
     263: 	 * the ni occurs in the last equation since those equations take
     264: 	 * you from 64 second update to 64 second update (ei is the total
     265: 	 * adjustment done over 64 seconds) and we're only deal in the
     266: 	 * little 4 second adjustment interval here.
     267: 	 */
     268:     adjustment += drift_comp / (double)(1<<CLOCK_FREQ);
     269:
     270:     /*
     271: 	 * Add in old adjustment residual
     272: 	 */
     273:     adjustment += adj_residual;
     274:
     275:     /*
     276: 	 * Simplify.  Adjustment shouldn't be bigger than 2 ms.  Hope
     277: 	 * writer of spec was truth telling.
     278: 	 */
     279: #ifdef  DEBUG
     280:     delta.tv_sec = adjustment;
     281:     if (debug && delta.tv_sec) abort();
     282: #else
     283:     delta.tv_sec = 0;
     284: #endif
     285:     delta.tv_usec = ((long)(adjustment * 1000000.0) / adj_precision)
     286:            * adj_precision;
     287:
     288:     adj_residual = adjustment - (double) delta.tv_usec / 1000000.0;
     289:
     290:     if (delta.tv_usec == 0)
     291:         return;
     292:
     293:     if (adjtime(&delta, &olddelta) < 0)
     294:         syslog(LOG_ERR, "Can't adjust time: %m");
     295:
     296: #ifdef  DEBUG
     297:     if(debug > 2)
     298:         printf("adj: %ld us  %f %f\n",
     299:                delta.tv_usec, drift_comp, clock_adjust);
     300: #endif
     301: }
     302: #endif

#### Defined functions

adj_host_clock defined in line 234; used 2 times

- in /usr/src/usr.sbin/ntp/ntpd.c line 645-647(2)

adj_logical defined in line 134; used 2 times

- in /usr/src/usr.sbin/ntp/ntp_proto.c line 660, 722

init_logical_clock defined in line 107; used 2 times

- in /usr/src/usr.sbin/ntp/ntpd.c line 169, 325

#### Defined variables

RCSid defined in line 2; never used
adj_precision defined in line 101; used 3 times

- in line 110, 285-286(2)

adj_residual defined in line 102; used 3 times

- in line 149, 273, 288

adjustment defined in line 232; used 7 times

- in line 258-259(2), 268-273(2), 280-288(3)

drift_comp defined in line 96; used 5 times

- in line 191, 268, 299
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 728, 752

firstpass defined in line 103; used 3 times

- in line 170, 183-184(2)

update_timer defined in line 99; used 5 times

- in line 171, 185, 191, 198, 247

#### Defined macros

abs defined in line 105; used 1 times

- in line 186

Last modified: 1995-01-28 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1618 |