]>
git.saurik.com Git - apple/network_cmds.git/blob - timed.tproj/timed.tproj/networkdelta.c
0556bbe80a88a861fd167e64bd30ee387e9f94ba
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright (c) 1985, 1993
26 * The Regents of the University of California. All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 static char sccsid
[] = "@(#)networkdelta.c 8.3 (Berkeley) 4/27/95";
62 #ident "$Revision: 1.1 $"
67 static long median
__P((double, float *, long *, long *, unsigned int));
70 * Compute a corrected date.
71 * Compute the median of the reasonable differences. First compute
72 * the median of all authorized differences, and then compute the
73 * median of all differences that are reasonably close to the first
76 * This differs from the original BSD implementation, which looked for
77 * the largest group of machines with essentially the same date.
78 * That assumed that machines with bad clocks would be uniformly
79 * distributed. Unfortunately, in real life networks, the distribution
80 * of machines is not uniform among models of machines, and the
81 * distribution of errors in clocks tends to be quite consistent
82 * for a given model. In other words, all model VI Supre Servres
83 * from GoFast Inc. tend to have about the same error.
84 * The original BSD implementation would chose the clock of the
85 * most common model, and discard all others.
87 * Therefore, get best we can do is to try to average over all
88 * of the machines in the network, while discarding "obviously"
96 long lodelta
, hidelta
;
104 * compute the median of the good values
109 *xp
= 0; /* account for ourself */
110 for (htp
= self
.l_fwd
; htp
!= &self
; htp
= htp
->l_fwd
) {
112 && htp
->noanswer
== 0
113 && htp
->delta
!= HOSTDOWN
) {
121 * If we are the only trusted time keeper, then do not change our
122 * clock. There may be another time keeping service active.
127 /* get average of trusted values */
131 fprintf(fd
, "median of %d values starting at %ld is about ",
133 /* get median of all trusted values, using average as initial guess */
135 med
= median(med
, &eps
, &x
[0], xp
+1, VALID_RANGE
);
137 /* Compute the median of all good values.
138 * Good values are those of all clocks, including untrusted clocks,
140 * - trusted and somewhat close to the median of the
142 * - trusted or untrusted and very close to the median of the
145 hidelta
= med
+ GOOD_RANGE
;
146 lodelta
= med
- GOOD_RANGE
;
147 higood
= med
+ VGOOD_RANGE
;
148 logood
= med
- VGOOD_RANGE
;
152 if (htp
->noanswer
== 0
153 && htp
->delta
>= lodelta
154 && htp
->delta
<= hidelta
156 || (htp
->delta
>= logood
157 && htp
->delta
<= higood
))) {
160 } while (&self
!= (htp
= htp
->l_fwd
));
164 fprintf(fd
, "nothing close to median %ld\n", med
);
170 fprintf(fd
, "only value near median is %ld\n", x
[0]);
175 fprintf(fd
, "median of %d values starting at %ld is ",
177 return median(med
, &eps
, &x
[0], xp
, 1);
182 * compute the median of an array of signed integers, using the idea
183 * in <<Numerical Recipes>>.
186 median(a0
, eps_ptr
, x
, xlim
, gnuf
)
187 double a0
; /* initial guess for the median */
188 float *eps_ptr
; /* spacing near the median */
189 long *x
, *xlim
; /* the data */
190 unsigned int gnuf
; /* good enough estimate */
194 float ap
= LONG_MAX
; /* bounds on the median */
195 float am
= -LONG_MAX
;
197 int npts
; /* # of points above & below guess */
198 float xp
; /* closet point above the guess */
199 float xm
; /* closet point below the guess */
201 float dum
, sum
, sumx
;
203 #define AMP 1.5 /* smoothing constants */
213 for (pass
= 1; ; pass
++) { /* loop over the data */
220 for (xptr
= x
; xptr
!= xlim
; xptr
++) {
224 if (dum
!= 0.0) { /* avoid dividing by 0 */
235 dum
= 1.0/(eps
+ dum
);
241 if (ap
-am
< gnuf
|| sum
== 0) {
245 " early out balance=%d\n",
246 (long)a
, pass
, npts
);
247 return a
; /* guess was good enough */
250 aa
= (sumx
/sum
-a
)*AMP
;
251 if (npts
>= 2) { /* guess was too low */
253 aa
= xp
+ max(0.0, aa
);
257 } else if (npts
<= -2) { /* guess was two high */
259 aa
= xm
+ min(0.0, aa
);
269 fprintf(fd
, "%ld in %d passes;"
270 " force out balance=%d\n",
271 (long)a
, pass
, npts
);
274 eps
= AFAC
*abs(aa
- a
);
279 if (((x
- xlim
) % 2) != 0) { /* even number of points? */
280 if (npts
== 0) /* yes, return an average */
287 } else if (npts
!= 0) { /* odd number of points */
295 fprintf(fd
, "%ld in %d passes\n", (long)a
, pass
);