diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index e613eb6f794b..92175b8ff0cb 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -53,8 +53,6 @@ #include #include #include -#include -#include #include #include #include @@ -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 d4038477e115..aee3eaa390b6 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) diff --git a/sys/sys/timetc.h b/sys/sys/timetc.h index efee90743ba2..5b212fe5c26f 100644 --- a/sys/sys/timetc.h +++ b/sys/sys/timetc.h @@ -95,7 +95,6 @@ extern struct timecounter *volatile timecounter; void tc_init(struct timecounter *tc); void tc_setclock(struct timespec *ts); -void tc_windup(void); #endif /* !_KERNEL */ #endif /* !_SYS_TIMETC_H_ */