diff options
author | phk <phk@FreeBSD.org> | 2002-04-26 12:37:36 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2002-04-26 12:37:36 +0000 |
commit | 04257819a4d326980d051f445ae317d8cd16374b (patch) | |
tree | 4e6b9f61f280b54de6b94c7eece10edcfaea8477 /sys/kern | |
parent | c9e55ed3c8a1963b73b29b8b053a687385d658f6 (diff) | |
download | FreeBSD-src-04257819a4d326980d051f445ae317d8cd16374b.zip FreeBSD-src-04257819a4d326980d051f445ae317d8cd16374b.tar.gz |
Move the winding of timecounters out of hardclock and into a normal
timeout loop.
Limit the rate at which we wind the timecounters to approx 1000 Hz.
This limits the precision of the get{bin,nano,micro}[up]time(9)
functions to roughly a millisecond.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_clock.c | 3 | ||||
-rw-r--r-- | sys/kern/kern_tc.c | 40 |
2 files changed, 39 insertions, 4 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index e613eb6..92175b8 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -53,8 +53,6 @@ #include <sys/resourcevar.h> #include <sys/signalvar.h> #include <sys/smp.h> -#include <sys/timetc.h> -#include <sys/timepps.h> #include <vm/vm.h> #include <vm/pmap.h> #include <vm/vm_map.h> @@ -218,7 +216,6 @@ hardclock(frame) if (stathz == 0) statclock(frame); - tc_windup(); #ifdef DEVICE_POLLING hardclock_device_poll(); /* this is very short and quick */ #endif /* DEVICE_POLLING */ diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index d403847..aee3eaa 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -50,6 +50,8 @@ TC_STATS(ngetbintime); TC_STATS(ngetnanotime); TC_STATS(ngetmicrotime); #undef TC_STATS +static void tc_windup(void); + /* * Implement a dummy timecounter which we can use until we get a real one * in the air. This allows the console and other early stuff to use @@ -332,7 +334,7 @@ switch_timecounter(struct timecounter *newtc) splx(s); } -void +static void tc_windup(void) { struct timecounter *tc, *tco; @@ -547,3 +549,39 @@ pps_event(struct pps_state *pps, struct timecounter *tc, unsigned count, int eve } #endif } + +/*- + * Timecounters need to be updated every so often to prevent the hardware + * counter from overflowing. Updating also recalculates the cached values + * used by the get*() family of functions, so their precision depends on + * the update frequency. + * Don't update faster than approx once per millisecond, if people want + * better timestamps they should use the non-"get" functions. + */ + +static int tc_tick; +SYSCTL_INT(_kern_timecounter, OID_AUTO, tick, CTLFLAG_RD, &tick, 0, ""); + +static void +tc_ticktock(void *dummy) +{ + + tc_windup(); + timeout(tc_ticktock, NULL, tc_tick); +} + +static void +inittimecounter(void *dummy) +{ + u_int p; + + if (hz > 1000) + tc_tick = (hz + 500) / 1000; + else + tc_tick = 1; + p = (tc_tick * 1000000) / hz; + printf("Timecounters tick every %d.%03u msec\n", p / 1000, p % 1000); + tc_ticktock(NULL); +} + +SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_FIRST, inittimecounter, NULL) |