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.
This commit is contained in:
Poul-Henning Kamp 2002-04-26 12:37:36 +00:00
parent 739c041c5d
commit 9e1b5510c3
3 changed files with 39 additions and 5 deletions

View File

@ -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 */

View File

@ -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)

View File

@ -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_ */