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
adj_logical defined in line 134; used 2 times
init_logical_clock defined in line 107; used 2 times

Defined variables

RCSid defined in line 2; never used
adj_precision defined in line 101; used 3 times
adj_residual defined in line 102; used 3 times
adjustment defined in line 232; used 7 times
drift_comp defined in line 96; used 5 times
firstpass defined in line 103; used 3 times
update_timer defined in line 99; used 5 times

Defined macros

abs defined in line 105; used 1 times
Last modified: 1995-01-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1733
Valid CSS Valid XHTML 1.0 Strict