diff options
author | phk <phk@FreeBSD.org> | 2002-04-15 12:23:11 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2002-04-15 12:23:11 +0000 |
commit | b6bf4c07cfa2b20a71ec5c6e20bf929d299043c5 (patch) | |
tree | 733a8aba038268bb9bbfe0becf82c0d69fb2477b /sys/kern/kern_tc.c | |
parent | 3bc1e338fc199c90b88b05b395b5a427f9497a15 (diff) | |
download | FreeBSD-src-b6bf4c07cfa2b20a71ec5c6e20bf929d299043c5.zip FreeBSD-src-b6bf4c07cfa2b20a71ec5c6e20bf929d299043c5.tar.gz |
Improve the implementation of adjtime(2).
Apply the change as a continuous slew rather than as a series of
discrete steps and make it possible to adjust arbitraryly huge
amounts of time in either direction.
In practice this is done by hooking into the same once-per-second
loop as the NTP PLL and setting a suitable frequency offset deducting
the amount slewed from the remainder. If the remaining delta is
larger than 1 second we slew at 5000PPM (5msec/sec), for a delta
less than a second we slew at 500PPM (500usec/sec) and for the last
one second period we will slew at whatever rate (less than 500PPM)
it takes to eliminate the delta entirely.
The old implementation stepped the clock a number of microseconds
every HZ to acheive the same effect, using the same rates of change.
Eliminate the global variables tickadj, tickdelta and timedelta and
their various use and initializations.
This removes the most significant obstacle to running timecounter and
NTP housekeeping from a timeout rather than hardclock.
Diffstat (limited to 'sys/kern/kern_tc.c')
-rw-r--r-- | sys/kern/kern_tc.c | 23 |
1 files changed, 4 insertions, 19 deletions
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index e058e74..18e3ce3 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -238,11 +238,11 @@ tco_setscales(struct timecounter *tc) /* * We get nanoseconds with 32 bit binary fraction and want * 64 bit binary fraction: x = a * 2^32 / 10^9 = a * 4.294967296 - * The range is +/- 500PPM so we can only multiply by about 8500 - * without overflowing. The best suitable fraction is 4398/1024. - * Divide by 2 times 1024 to match the temporary lower precision. + * The range is +/- 5000PPM so we can only multiply by about 850 + * without overflowing. The best suitable fraction is 2199/512. + * Divide by 2 times 512 to match the temporary lower precision. */ - scale += (tc->tc_adjustment * 4398) / 2048; + scale += (tc->tc_adjustment / 1024) * 2199; scale /= tc->tc_tweak->tc_frequency; tc->tc_scale = scale * 2; } @@ -338,7 +338,6 @@ tc_windup(void) { struct timecounter *tc, *tco; struct bintime bt; - struct timeval tvt; unsigned ogen, delta; int i; @@ -362,20 +361,6 @@ tc_windup(void) */ if (tco->tc_poll_pps) tco->tc_poll_pps(tco); - if (timedelta != 0) { - tvt = boottime; - tvt.tv_usec += tickdelta; - if (tvt.tv_usec >= 1000000) { - tvt.tv_sec++; - tvt.tv_usec -= 1000000; - } else if (tvt.tv_usec < 0) { - tvt.tv_sec--; - tvt.tv_usec += 1000000; - } - boottime = tvt; - timeval2bintime(&boottime, &boottimebin); - timedelta -= tickdelta; - } for (i = tc->tc_offset.sec - tco->tc_offset.sec; i > 0; i--) { ntp_update_second(tc); /* XXX only needed if xntpd runs */ tco_setscales(tc); |