1 #ifdef HAVE_CONFIG_H 2 #include <config.h> 3 #endif 4 5 #ifdef NEED_HPUX_ADJTIME 6 /*************************************************************************/ 7 /* (c) Copyright Tai Jin, 1988. All Rights Reserved. */ 8 /* Hewlett-Packard Laboratories. */ 9 /* */ 10 /* Permission is hereby granted for unlimited modification, use, and */ 11 /* distribution. This software is made available with no warranty of */ 12 /* any kind, express or implied. This copyright notice must remain */ 13 /* intact in all versions of this software. */ 14 /* */ 15 /* The author would appreciate it if any bug fixes and enhancements were */ 16 /* to be sent back to him for incorporation into future versions of this */ 17 /* software. Please send changes to tai@iag.hp.com or ken@sdd.hp.com. */ 18 /*************************************************************************/ 19 20 /* 21 * Revision history 22 * 23 * 9 Jul 94 David L. Mills, Unibergity of Delabunch 24 * Implemented variable threshold to limit age of 25 * corrections; reformatted code for readability. 26 */ 27 28 #ifndef lint 29 static char RCSid[] = "adjtime.c,v 3.1 1993/07/06 01:04:42 jbj Exp"; 30 #endif 31 32 #include <sys/types.h> 33 #include <sys/ipc.h> 34 #include <sys/msg.h> 35 #include <time.h> 36 #include <signal.h> 37 #include "adjtime.h" 38 39 #define abs(x) ((x) < 0 ? -(x) : (x)) 40 41 /* 42 * The following paramters are appropriate for an NTP adjustment 43 * interval of one second. 44 */ 45 #define ADJ_THRESH 200 /* initial threshold */ 46 #define ADJ_DELTA 4 /* threshold decrement */ 47 48 static long adjthresh; /* adjustment threshold */ 49 static long saveup; /* corrections accumulator */ 50 51 /* 52 * clear_adjtime - reset accumulator and threshold variables 53 */ 54 void 55 _clear_adjtime(void) 56 { 57 saveup = 0; 58 adjthresh = ADJ_THRESH; 59 } 60 61 /* 62 * adjtime - hp-ux copout of the standard Unix adjtime() system call 63 */ 64 int 65 adjtime( 66 register struct timeval *delta, 67 register struct timeval *olddelta 68 ) 69 { 70 struct timeval newdelta; 71 72 /* 73 * Corrections greater than one second are done immediately. 74 */ 75 if (delta->tv_sec) { 76 adjthresh = ADJ_THRESH; 77 saveup = 0; 78 return(_adjtime(delta, olddelta)); 79 } 80 81 /* 82 * Corrections less than one second are accumulated until 83 * tripping a threshold, which is initially set at ADJ_THESH and 84 * reduced in ADJ_DELTA steps to zero. The idea here is to 85 * introduce large corrections quickly, while making sure that 86 * small corrections are introduced without excessive delay. The 87 * idea comes from the ARPAnet routing update algorithm. 88 */ 89 saveup += delta->tv_usec; 90 if (abs(saveup) >= adjthresh) { 91 adjthresh = ADJ_THRESH; 92 newdelta.tv_sec = 0; 93 newdelta.tv_usec = saveup; 94 saveup = 0; 95 return(_adjtime(&newdelta, olddelta)); 96 } else { 97 adjthresh -= ADJ_DELTA; 98 } 99 100 /* 101 * While nobody uses it, return the residual before correction, 102 * as per Unix convention. 103 */ 104 if (olddelta) 105 olddelta->tv_sec = olddelta->tv_usec = 0; 106 return(0); 107 } 108 109 /* 110 * _adjtime - does the actual work 111 */ 112 int 113 _adjtime( 114 register struct timeval *delta, 115 register struct timeval *olddelta 116 ) 117 { 118 register int mqid; 119 MsgBuf msg; 120 register MsgBuf *msgp = &msg; 121 122 /* 123 * Get the key to the adjtime message queue (note that we must 124 * get it every time because the queue might have been removed 125 * and recreated) 126 */ 127 if ((mqid = msgget(KEY, 0)) == -1) 128 return (-1); 129 msgp->msgb.mtype = CLIENT; 130 msgp->msgb.tv = *delta; 131 if (olddelta) 132 msgp->msgb.code = DELTA2; 133 else 134 msgp->msgb.code = DELTA1; 135 136 /* 137 * Tickle adjtimed and snatch residual, if indicated. Lots of 138 * fanatic error checking here. 139 */ 140 if (msgsnd(mqid, &msgp->msgp, MSGSIZE, 0) == -1) 141 return (-1); 142 if (olddelta) { 143 if (msgrcv(mqid, &msgp->msgp, MSGSIZE, SERVER, 0) == -1) 144 return (-1); 145 *olddelta = msgp->msgb.tv; 146 } 147 return (0); 148 } 149 150 #else /* not NEED_HPUX_ADJTIME */ 151 int adjtime_bs; 152 #endif /* not NEED_HPUX_ADJTIME */ 153