]> git.ipfire.org Git - thirdparty/util-linux.git/blame - hwclock/adjtime.patch
Imported from util-linux-2.10s tarball.
[thirdparty/util-linux.git] / hwclock / adjtime.patch
CommitLineData
7eda085c
KZ
1From ao112@rgfn.epcc.edu Fri Mar 19 06:27:26 1999
2Received: 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)
4Received: (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)
7Date: Thu, 18 Mar 1999 22:27:19 -0700 (MST)
8Message-Id: <199903190527.WAA16797@rgfn.epcc.edu>
9From: ao112@rgfn.epcc.edu (James P. Rutledge)
10To: Andries.Brouwer@cwi.nl
11Subject: Re: hwclock patch for drift_factor calculation improvement
12Reply-To: ao112@rgfn.epcc.edu
13Status: 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
27Andries;
28
29Per your request, the patch has been modified for util-linux version
302.9n, from the version for 2.9g.
31
32The program "hwclock" (version 2.4c) could give more accurate
33values for the drift factor that it places in the file "/etc/adjtime".
34
35A patch to improve the accuracy is included.
36
37I have incorporated some error sources which were not compensated
38for into the drift factor calculation (performed when the "--set"
39or the "--systohc" option is used) to make it more accurate.
40In particular, the sync delay between the desired set time and the
41start of the hardware clock second, and the expected drift since the
42last hardware clock adjustment are now accounted for in the drift
43factor calculation.
44
45With this patch, if at any time an adjust operation is attempted and
46the hardware clock is found to be not valid, then the calibration
47and adjustment time is set to zero to insure that if the hardware
48clock should coincidentally return to validity, a calibration is not
49done with bad history data (hardware clock info bad) and an adjust is
50not attempted on bad (but now passing validity test) hardware clock
51data. (With this patch, a previous calibration time of zero causes
52the calibration time to initialize with the current time, when the
53hardware clock is set, but no change is made to the drift factor,
54so in effect, an initial calibration is started over while the previous
55drift factor is retained.)
56
57Also, the behavior in the case of an initially missing "/etc/adjtime"
58file or such a file produced by the predecessor "clock" program has
59been 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
75A context diff for a patch to the file "hwclock.c" in the directory
76"util-linux-2.9n/clock" is appended.
77To use the patch, "cd" to the directory "util-linux-2.9n/clock".
78Run "patch < bug-report", where "bug-report" is the file name of
79this mail message, to get new file "hwclock.c" which contains the proposed
80new version. This patch is, of course, submitted per the GPL and the
81appropriate "NO WARRANTY OF ANY KIND" and "USE AT YOUR OWN RISK"
82disclaimers apply.
83
84Note that the patch presumptuously changes the "hwclock.c" version
85number from 2.4c to 2.4c1 in "hwclock.c".
86
87Jim
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