diff options
Diffstat (limited to 'clock/adjtime.patch')
-rw-r--r-- | clock/adjtime.patch | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/clock/adjtime.patch b/clock/adjtime.patch new file mode 100644 index 000000000..81d0430fd --- /dev/null +++ b/clock/adjtime.patch @@ -0,0 +1,302 @@ +From ao112@rgfn.epcc.edu Fri Mar 19 06:27:26 1999 +Received: from rgfn.epcc.edu (rgfn.epcc.edu [208.136.234.19]) by hera.cwi.nl with ESMTP + id GAA27711 for <Andries.Brouwer@cwi.nl>; Fri, 19 Mar 1999 06:27:23 +0100 (MET) +Received: (from ao112@localhost) + by rgfn.epcc.edu (8.8.8/8.8.8) id WAA16797; + Thu, 18 Mar 1999 22:27:19 -0700 (MST) +Date: Thu, 18 Mar 1999 22:27:19 -0700 (MST) +Message-Id: <199903190527.WAA16797@rgfn.epcc.edu> +From: ao112@rgfn.epcc.edu (James P. Rutledge) +To: Andries.Brouwer@cwi.nl +Subject: Re: hwclock patch for drift_factor calculation improvement +Reply-To: ao112@rgfn.epcc.edu +Status: R + + + +> +>Could you perhaps make your patch relative to +>util-linux-2.9n (found in ftp.cwi.nl/pub/aeb/util-linux/util-linux-2.9n.tar.gz) +>? +> +>(The hwclock stuff has changed quite a bit since 2.9g.) +> +>Andries +> + +Andries; + +Per your request, the patch has been modified for util-linux version +2.9n, from the version for 2.9g. + +The program "hwclock" (version 2.4c) could give more accurate +values for the drift factor that it places in the file "/etc/adjtime". + +A patch to improve the accuracy is included. + +I have incorporated some error sources which were not compensated +for into the drift factor calculation (performed when the "--set" +or the "--systohc" option is used) to make it more accurate. +In particular, the sync delay between the desired set time and the +start of the hardware clock second, and the expected drift since the +last hardware clock adjustment are now accounted for in the drift +factor calculation. + +With this patch, if at any time an adjust operation is attempted and +the hardware clock is found to be not valid, then the calibration +and adjustment time is set to zero to insure that if the hardware +clock should coincidentally return to validity, a calibration is not +done with bad history data (hardware clock info bad) and an adjust is +not attempted on bad (but now passing validity test) hardware clock +data. (With this patch, a previous calibration time of zero causes +the calibration time to initialize with the current time, when the +hardware clock is set, but no change is made to the drift factor, +so in effect, an initial calibration is started over while the previous +drift factor is retained.) + +Also, the behavior in the case of an initially missing "/etc/adjtime" +file or such a file produced by the predecessor "clock" program has +been slightly improved as follows: + + With this patch, if the file exists but was produced by "clock" + and, thus, is given a zero calibration time, the drift factor is + not updated upon the first calibration by "hwclock", but is left alone + and is only changed by subsequent calibrations. + + With this patch, if the file does not exist and, thus, is given + a zero calibration time, the drift factor is set to zero upon the + first calibration by "hwclock" and is then changed, as appropriate, by + subsequent calibrations. + + Also, with this patch, an "--adjust" operation against a non-existent + "/etc/adjtime" file or one which has zero as the last adjustment + time will not change the hardware clock setting. + +A context diff for a patch to the file "hwclock.c" in the directory +"util-linux-2.9n/clock" is appended. +To use the patch, "cd" to the directory "util-linux-2.9n/clock". +Run "patch < bug-report", where "bug-report" is the file name of +this mail message, to get new file "hwclock.c" which contains the proposed +new version. This patch is, of course, submitted per the GPL and the +appropriate "NO WARRANTY OF ANY KIND" and "USE AT YOUR OWN RISK" +disclaimers apply. + +Note that the patch presumptuously changes the "hwclock.c" version +number from 2.4c to 2.4c1 in "hwclock.c". + +Jim + +------------------ Patch file follows ---------------------------- +*** hwclock.c Thu Mar 18 22:04:01 1999 +--- new-hwclock.c Thu Mar 18 22:03:18 1999 +*************** +*** 76,86 **** + + #include "clock.h" + #include "../version.h" + + #define MYNAME "hwclock" +! #define VERSION "2.4c" + + char *progname = MYNAME; + + /* The struct that holds our hardware access routines */ + struct clock_ops *ur; +--- 76,86 ---- + + #include "clock.h" + #include "../version.h" + + #define MYNAME "hwclock" +! #define VERSION "2.4c1" + + char *progname = MYNAME; + + /* The struct that holds our hardware access routines */ + struct clock_ops *ur; +*************** +*** 581,601 **** + + + static void + adjust_drift_factor(struct adjtime *adjtime_p, + const time_t nowtime, +! const bool hclock_valid, const time_t hclocktime ) { + /*--------------------------------------------------------------------------- + Update the drift factor in <*adjtime_p> to reflect the fact that the + Hardware Clock was calibrated to <nowtime> and before that was set + to <hclocktime>. + +- We assume that the user has been doing regular drift adjustments +- using the drift factor in the adjtime file, so if <nowtime> and +- <clocktime> are different, that means the adjustment factor isn't +- quite right. +- + We record in the adjtime file the time at which we last calibrated + the clock so we can compute the drift rate each time we calibrate. + + EXCEPT: if <hclock_valid> is false, assume Hardware Clock was not set + before to anything meaningful and regular adjustments have not been +--- 581,598 ---- + + + static void + adjust_drift_factor(struct adjtime *adjtime_p, + const time_t nowtime, +! const bool hclock_valid, +! const time_t hclocktime, +! const float sync_delay ) { + /*--------------------------------------------------------------------------- + Update the drift factor in <*adjtime_p> to reflect the fact that the + Hardware Clock was calibrated to <nowtime> and before that was set + to <hclocktime>. + + We record in the adjtime file the time at which we last calibrated + the clock so we can compute the drift rate each time we calibrate. + + EXCEPT: if <hclock_valid> is false, assume Hardware Clock was not set + before to anything meaningful and regular adjustments have not been +*************** +*** 604,629 **** + ----------------------------------------------------------------------------*/ + if (!hclock_valid) { + if (debug) + printf("Not adjusting drift factor because the Hardware Clock " + "previously contained garbage.\n"); + } else if ((hclocktime - adjtime_p->last_calib_time) < 23 * 60 * 60) { + if (debug) + printf("Not adjusting drift factor because it has been less than a " + "day since the last calibration.\n"); + } else { +! const float factor_adjust = +! ((float) (nowtime - hclocktime) +! / (hclocktime - adjtime_p->last_calib_time)) +! * 24 * 60 * 60; + + if (debug) +! printf("Clock drifted %d seconds in the past %d seconds " + "in spite of a drift factor of %f seconds/day.\n" + "Adjusting drift factor by %f seconds/day\n", +! (int) (nowtime - hclocktime), +! (int) (hclocktime - adjtime_p->last_calib_time), + adjtime_p->drift_factor, + factor_adjust ); + + adjtime_p->drift_factor += factor_adjust; + } +--- 601,642 ---- + ----------------------------------------------------------------------------*/ + if (!hclock_valid) { + if (debug) + printf("Not adjusting drift factor because the Hardware Clock " + "previously contained garbage.\n"); ++ } else if (adjtime_p->last_calib_time == 0) { ++ if (debug) ++ printf("Not adjusting drift factor because last calibration " ++ "time is zero,\nso history is bad and calibration startover " ++ "is necessary.\n"); + } else if ((hclocktime - adjtime_p->last_calib_time) < 23 * 60 * 60) { + if (debug) + printf("Not adjusting drift factor because it has been less than a " + "day since the last calibration.\n"); + } else { +! const float sec_per_day = 24.0 * 60.0 * 60.0; +! float atime_per_htime; /* adjusted time units per hardware time unit */ +! float adj_days; /* days since last adjustment (in hardware clock time) */ +! float cal_days; /* days since last calibration (in hardware clock time) */ +! float exp_drift; /* expected drift (sec) since last adjustment */ +! float unc_drift; /* uncorrected drift (sec) since last calibration */ +! float factor_adjust; /* amount to add to previous drift factor */ +! atime_per_htime = 1.0 + adjtime_p->drift_factor / sec_per_day; +! adj_days = (float)(hclocktime - adjtime_p->last_adj_time) / sec_per_day; +! exp_drift = adj_days * adjtime_p->drift_factor + adjtime_p->not_adjusted; +! unc_drift = (float)(nowtime - hclocktime) + sync_delay - exp_drift; +! cal_days = ((float)(adjtime_p->last_adj_time - adjtime_p->last_calib_time) +! + adjtime_p->not_adjusted) / (sec_per_day * atime_per_htime) +! + adj_days; +! factor_adjust = unc_drift / cal_days; + + if (debug) +! printf("Clock drifted %.1f seconds in the past %d seconds " + "in spite of a drift factor of %f seconds/day.\n" + "Adjusting drift factor by %f seconds/day\n", +! unc_drift, +! (int) (nowtime - adjtime_p->last_calib_time), + adjtime_p->drift_factor, + factor_adjust ); + + adjtime_p->drift_factor += factor_adjust; + } +*************** +*** 764,773 **** +--- 777,794 ---- + + ----------------------------------------------------------------------------*/ + if (!hclock_valid) { + fprintf(stderr, "The Hardware Clock does not contain a valid time, " + "so we cannot adjust it.\n"); ++ adjtime_p->last_calib_time = 0; /* calibration startover is required */ ++ adjtime_p->last_adj_time = 0; ++ adjtime_p->not_adjusted = 0; ++ adjtime_p->dirty = TRUE; ++ } else if (adjtime_p->last_adj_time == 0) { ++ if (debug) ++ printf("Not setting clock because last adjustment time is zero, " ++ "so history is bad."); + } else { + int adjustment; + /* Number of seconds we must insert in the Hardware Clock */ + float retro; + /* Fraction of second we have to remove from clock after inserting +*************** +*** 878,888 **** + time_diff(read_time, startup_time)); + *retcode_p = 0; + } else if (set) { + set_hardware_clock_exact(set_time, startup_time, + universal, testing); +! adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime); + *retcode_p = 0; + } else if (adjust) { + do_adjustment(&adjtime, hclock_valid, hclocktime, + read_time, universal, testing); + *retcode_p = 0; +--- 899,910 ---- + time_diff(read_time, startup_time)); + *retcode_p = 0; + } else if (set) { + set_hardware_clock_exact(set_time, startup_time, + universal, testing); +! adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime, +! time_diff(read_time, startup_time)); + *retcode_p = 0; + } else if (adjust) { + do_adjustment(&adjtime, hclock_valid, hclocktime, + read_time, universal, testing); + *retcode_p = 0; +*************** +*** 898,908 **** + + set_hardware_clock_exact((time_t) reftime.tv_sec, reftime, + universal, testing); + *retcode_p = 0; + adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid, +! hclocktime); + } else if (hctosys) { + rc = set_system_clock(hclock_valid, hclocktime, testing); + if (rc != 0) { + printf("Unable to set system clock.\n"); + *retcode_p = 1; +--- 920,930 ---- + + set_hardware_clock_exact((time_t) reftime.tv_sec, reftime, + universal, testing); + *retcode_p = 0; + adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid, +! hclocktime, (float)(read_time.tv_usec / 1E6)); + } else if (hctosys) { + rc = set_system_clock(hclock_valid, hclocktime, testing); + if (rc != 0) { + printf("Unable to set system clock.\n"); + *retcode_p = 1; + |