5 #ifdef NEED_HPUX_ADJTIME
6 /*************************************************************************/
7 /* (c) Copyright Tai Jin, 1988. All Rights Reserved. */
8 /* Hewlett-Packard Laboratories. */
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. */
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 /*************************************************************************/
23 * 9 Jul 94 David L. Mills, Unibergity of Delabunch
24 * Implemented variable threshold to limit age of
25 * corrections; reformatted code for readability.
29 static char RCSid[] = "adjtime.c,v 3.1 1993/07/06 01:04:42 jbj Exp";
32 #include <sys/types.h>
39 #define abs(x) ((x) < 0 ? -(x) : (x))
42 * The following paramters are appropriate for an NTP adjustment
43 * interval of one second.
45 #define ADJ_THRESH 200 /* initial threshold */
46 #define ADJ_DELTA 4 /* threshold decrement */
48 static long adjthresh; /* adjustment threshold */
49 static long saveup; /* corrections accumulator */
52 * clear_adjtime - reset accumulator and threshold variables
58 adjthresh = ADJ_THRESH;
62 * adjtime - hp-ux copout of the standard Unix adjtime() system call
66 register struct timeval *delta,
67 register struct timeval *olddelta
70 struct timeval newdelta;
73 * Corrections greater than one second are done immediately.
76 adjthresh = ADJ_THRESH;
78 return(_adjtime(delta, olddelta));
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.
89 saveup += delta->tv_usec;
90 if (abs(saveup) >= adjthresh) {
91 adjthresh = ADJ_THRESH;
93 newdelta.tv_usec = saveup;
95 return(_adjtime(&newdelta, olddelta));
97 adjthresh -= ADJ_DELTA;
101 * While nobody uses it, return the residual before correction,
102 * as per Unix convention.
105 olddelta->tv_sec = olddelta->tv_usec = 0;
110 * _adjtime - does the actual work
114 register struct timeval *delta,
115 register struct timeval *olddelta
120 register MsgBuf *msgp = &msg;
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
127 if ((mqid = msgget(KEY, 0)) == -1)
129 msgp->msgb.mtype = CLIENT;
130 msgp->msgb.tv = *delta;
132 msgp->msgb.code = DELTA2;
134 msgp->msgb.code = DELTA1;
137 * Tickle adjtimed and snatch residual, if indicated. Lots of
138 * fanatic error checking here.
140 if (msgsnd(mqid, &msgp->msgp, MSGSIZE, 0) == -1)
143 if (msgrcv(mqid, &msgp->msgp, MSGSIZE, SERVER, 0) == -1)
145 *olddelta = msgp->msgb.tv;
150 #else /* not NEED_HPUX_ADJTIME */
152 #endif /* not NEED_HPUX_ADJTIME */