]> git.ipfire.org Git - thirdparty/util-linux.git/blob - hwclock/adjtime.patch
Imported from util-linux-2.10s tarball.
[thirdparty/util-linux.git] / hwclock / adjtime.patch
1 From ao112@rgfn.epcc.edu Fri Mar 19 06:27:26 1999
2 Received: from rgfn.epcc.edu (rgfn.epcc.edu [208.136.234.19]) by hera.cwi.nl with ESMTP
3 id GAA27711 for <Andries.Brouwer@cwi.nl>; Fri, 19 Mar 1999 06:27:23 +0100 (MET)
4 Received: (from ao112@localhost)
5 by rgfn.epcc.edu (8.8.8/8.8.8) id WAA16797;
6 Thu, 18 Mar 1999 22:27:19 -0700 (MST)
7 Date: Thu, 18 Mar 1999 22:27:19 -0700 (MST)
8 Message-Id: <199903190527.WAA16797@rgfn.epcc.edu>
9 From: ao112@rgfn.epcc.edu (James P. Rutledge)
10 To: Andries.Brouwer@cwi.nl
11 Subject: Re: hwclock patch for drift_factor calculation improvement
12 Reply-To: ao112@rgfn.epcc.edu
13 Status: R
14
15
16
17 >
18 >Could you perhaps make your patch relative to
19 >util-linux-2.9n (found in ftp.cwi.nl/pub/aeb/util-linux/util-linux-2.9n.tar.gz)
20 >?
21 >
22 >(The hwclock stuff has changed quite a bit since 2.9g.)
23 >
24 >Andries
25 >
26
27 Andries;
28
29 Per your request, the patch has been modified for util-linux version
30 2.9n, from the version for 2.9g.
31
32 The program "hwclock" (version 2.4c) could give more accurate
33 values for the drift factor that it places in the file "/etc/adjtime".
34
35 A patch to improve the accuracy is included.
36
37 I have incorporated some error sources which were not compensated
38 for into the drift factor calculation (performed when the "--set"
39 or the "--systohc" option is used) to make it more accurate.
40 In particular, the sync delay between the desired set time and the
41 start of the hardware clock second, and the expected drift since the
42 last hardware clock adjustment are now accounted for in the drift
43 factor calculation.
44
45 With this patch, if at any time an adjust operation is attempted and
46 the hardware clock is found to be not valid, then the calibration
47 and adjustment time is set to zero to insure that if the hardware
48 clock should coincidentally return to validity, a calibration is not
49 done with bad history data (hardware clock info bad) and an adjust is
50 not attempted on bad (but now passing validity test) hardware clock
51 data. (With this patch, a previous calibration time of zero causes
52 the calibration time to initialize with the current time, when the
53 hardware clock is set, but no change is made to the drift factor,
54 so in effect, an initial calibration is started over while the previous
55 drift factor is retained.)
56
57 Also, the behavior in the case of an initially missing "/etc/adjtime"
58 file or such a file produced by the predecessor "clock" program has
59 been slightly improved as follows:
60
61 With this patch, if the file exists but was produced by "clock"
62 and, thus, is given a zero calibration time, the drift factor is
63 not updated upon the first calibration by "hwclock", but is left alone
64 and is only changed by subsequent calibrations.
65
66 With this patch, if the file does not exist and, thus, is given
67 a zero calibration time, the drift factor is set to zero upon the
68 first calibration by "hwclock" and is then changed, as appropriate, by
69 subsequent calibrations.
70
71 Also, with this patch, an "--adjust" operation against a non-existent
72 "/etc/adjtime" file or one which has zero as the last adjustment
73 time will not change the hardware clock setting.
74
75 A context diff for a patch to the file "hwclock.c" in the directory
76 "util-linux-2.9n/clock" is appended.
77 To use the patch, "cd" to the directory "util-linux-2.9n/clock".
78 Run "patch < bug-report", where "bug-report" is the file name of
79 this mail message, to get new file "hwclock.c" which contains the proposed
80 new version. This patch is, of course, submitted per the GPL and the
81 appropriate "NO WARRANTY OF ANY KIND" and "USE AT YOUR OWN RISK"
82 disclaimers apply.
83
84 Note that the patch presumptuously changes the "hwclock.c" version
85 number from 2.4c to 2.4c1 in "hwclock.c".
86
87 Jim
88
89 ------------------ Patch file follows ----------------------------
90 *** hwclock.c Thu Mar 18 22:04:01 1999
91 --- new-hwclock.c Thu Mar 18 22:03:18 1999
92 ***************
93 *** 76,86 ****
94
95 #include "clock.h"
96 #include "../version.h"
97
98 #define MYNAME "hwclock"
99 ! #define VERSION "2.4c"
100
101 char *progname = MYNAME;
102
103 /* The struct that holds our hardware access routines */
104 struct clock_ops *ur;
105 --- 76,86 ----
106
107 #include "clock.h"
108 #include "../version.h"
109
110 #define MYNAME "hwclock"
111 ! #define VERSION "2.4c1"
112
113 char *progname = MYNAME;
114
115 /* The struct that holds our hardware access routines */
116 struct clock_ops *ur;
117 ***************
118 *** 581,601 ****
119
120
121 static void
122 adjust_drift_factor(struct adjtime *adjtime_p,
123 const time_t nowtime,
124 ! const bool hclock_valid, const time_t hclocktime ) {
125 /*---------------------------------------------------------------------------
126 Update the drift factor in <*adjtime_p> to reflect the fact that the
127 Hardware Clock was calibrated to <nowtime> and before that was set
128 to <hclocktime>.
129
130 - We assume that the user has been doing regular drift adjustments
131 - using the drift factor in the adjtime file, so if <nowtime> and
132 - <clocktime> are different, that means the adjustment factor isn't
133 - quite right.
134 -
135 We record in the adjtime file the time at which we last calibrated
136 the clock so we can compute the drift rate each time we calibrate.
137
138 EXCEPT: if <hclock_valid> is false, assume Hardware Clock was not set
139 before to anything meaningful and regular adjustments have not been
140 --- 581,598 ----
141
142
143 static void
144 adjust_drift_factor(struct adjtime *adjtime_p,
145 const time_t nowtime,
146 ! const bool hclock_valid,
147 ! const time_t hclocktime,
148 ! const float sync_delay ) {
149 /*---------------------------------------------------------------------------
150 Update the drift factor in <*adjtime_p> to reflect the fact that the
151 Hardware Clock was calibrated to <nowtime> and before that was set
152 to <hclocktime>.
153
154 We record in the adjtime file the time at which we last calibrated
155 the clock so we can compute the drift rate each time we calibrate.
156
157 EXCEPT: if <hclock_valid> is false, assume Hardware Clock was not set
158 before to anything meaningful and regular adjustments have not been
159 ***************
160 *** 604,629 ****
161 ----------------------------------------------------------------------------*/
162 if (!hclock_valid) {
163 if (debug)
164 printf("Not adjusting drift factor because the Hardware Clock "
165 "previously contained garbage.\n");
166 } else if ((hclocktime - adjtime_p->last_calib_time) < 23 * 60 * 60) {
167 if (debug)
168 printf("Not adjusting drift factor because it has been less than a "
169 "day since the last calibration.\n");
170 } else {
171 ! const float factor_adjust =
172 ! ((float) (nowtime - hclocktime)
173 ! / (hclocktime - adjtime_p->last_calib_time))
174 ! * 24 * 60 * 60;
175
176 if (debug)
177 ! printf("Clock drifted %d seconds in the past %d seconds "
178 "in spite of a drift factor of %f seconds/day.\n"
179 "Adjusting drift factor by %f seconds/day\n",
180 ! (int) (nowtime - hclocktime),
181 ! (int) (hclocktime - adjtime_p->last_calib_time),
182 adjtime_p->drift_factor,
183 factor_adjust );
184
185 adjtime_p->drift_factor += factor_adjust;
186 }
187 --- 601,642 ----
188 ----------------------------------------------------------------------------*/
189 if (!hclock_valid) {
190 if (debug)
191 printf("Not adjusting drift factor because the Hardware Clock "
192 "previously contained garbage.\n");
193 + } else if (adjtime_p->last_calib_time == 0) {
194 + if (debug)
195 + printf("Not adjusting drift factor because last calibration "
196 + "time is zero,\nso history is bad and calibration startover "
197 + "is necessary.\n");
198 } else if ((hclocktime - adjtime_p->last_calib_time) < 23 * 60 * 60) {
199 if (debug)
200 printf("Not adjusting drift factor because it has been less than a "
201 "day since the last calibration.\n");
202 } else {
203 ! const float sec_per_day = 24.0 * 60.0 * 60.0;
204 ! float atime_per_htime; /* adjusted time units per hardware time unit */
205 ! float adj_days; /* days since last adjustment (in hardware clock time) */
206 ! float cal_days; /* days since last calibration (in hardware clock time) */
207 ! float exp_drift; /* expected drift (sec) since last adjustment */
208 ! float unc_drift; /* uncorrected drift (sec) since last calibration */
209 ! float factor_adjust; /* amount to add to previous drift factor */
210 ! atime_per_htime = 1.0 + adjtime_p->drift_factor / sec_per_day;
211 ! adj_days = (float)(hclocktime - adjtime_p->last_adj_time) / sec_per_day;
212 ! exp_drift = adj_days * adjtime_p->drift_factor + adjtime_p->not_adjusted;
213 ! unc_drift = (float)(nowtime - hclocktime) + sync_delay - exp_drift;
214 ! cal_days = ((float)(adjtime_p->last_adj_time - adjtime_p->last_calib_time)
215 ! + adjtime_p->not_adjusted) / (sec_per_day * atime_per_htime)
216 ! + adj_days;
217 ! factor_adjust = unc_drift / cal_days;
218
219 if (debug)
220 ! printf("Clock drifted %.1f seconds in the past %d seconds "
221 "in spite of a drift factor of %f seconds/day.\n"
222 "Adjusting drift factor by %f seconds/day\n",
223 ! unc_drift,
224 ! (int) (nowtime - adjtime_p->last_calib_time),
225 adjtime_p->drift_factor,
226 factor_adjust );
227
228 adjtime_p->drift_factor += factor_adjust;
229 }
230 ***************
231 *** 764,773 ****
232 --- 777,794 ----
233
234 ----------------------------------------------------------------------------*/
235 if (!hclock_valid) {
236 fprintf(stderr, "The Hardware Clock does not contain a valid time, "
237 "so we cannot adjust it.\n");
238 + adjtime_p->last_calib_time = 0; /* calibration startover is required */
239 + adjtime_p->last_adj_time = 0;
240 + adjtime_p->not_adjusted = 0;
241 + adjtime_p->dirty = TRUE;
242 + } else if (adjtime_p->last_adj_time == 0) {
243 + if (debug)
244 + printf("Not setting clock because last adjustment time is zero, "
245 + "so history is bad.");
246 } else {
247 int adjustment;
248 /* Number of seconds we must insert in the Hardware Clock */
249 float retro;
250 /* Fraction of second we have to remove from clock after inserting
251 ***************
252 *** 878,888 ****
253 time_diff(read_time, startup_time));
254 *retcode_p = 0;
255 } else if (set) {
256 set_hardware_clock_exact(set_time, startup_time,
257 universal, testing);
258 ! adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime);
259 *retcode_p = 0;
260 } else if (adjust) {
261 do_adjustment(&adjtime, hclock_valid, hclocktime,
262 read_time, universal, testing);
263 *retcode_p = 0;
264 --- 899,910 ----
265 time_diff(read_time, startup_time));
266 *retcode_p = 0;
267 } else if (set) {
268 set_hardware_clock_exact(set_time, startup_time,
269 universal, testing);
270 ! adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime,
271 ! time_diff(read_time, startup_time));
272 *retcode_p = 0;
273 } else if (adjust) {
274 do_adjustment(&adjtime, hclock_valid, hclocktime,
275 read_time, universal, testing);
276 *retcode_p = 0;
277 ***************
278 *** 898,908 ****
279
280 set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,
281 universal, testing);
282 *retcode_p = 0;
283 adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,
284 ! hclocktime);
285 } else if (hctosys) {
286 rc = set_system_clock(hclock_valid, hclocktime, testing);
287 if (rc != 0) {
288 printf("Unable to set system clock.\n");
289 *retcode_p = 1;
290 --- 920,930 ----
291
292 set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,
293 universal, testing);
294 *retcode_p = 0;
295 adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,
296 ! hclocktime, (float)(read_time.tv_usec / 1E6));
297 } else if (hctosys) {
298 rc = set_system_clock(hclock_valid, hclocktime, testing);
299 if (rc != 0) {
300 printf("Unable to set system clock.\n");
301 *retcode_p = 1;
302