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