p A timecounter is a binary counter which has two properties: l -bullet -offset indent t it runs at a fixed, known frequency; and t it has sufficient bits to not roll over in less than approximately max(2 msec,
f 2/ Em HZ seconds) (the value 2 here is really 1 + delta, for some indeterminate value of delta). .El
p The interface between the hardware which implements a timecounter and the machine-independent code which uses this to keep track of time is a .Va timecounter structure: d -literal -offset indent struct timecounter { timecounter_get_t *tc_get_timecount; timecounter_pps_t *tc_poll_pps; u_int tc_counter_mask; uint64_t tc_frequency; const char *tc_name; int tc_quality; void *tc_priv; struct timecounter *tc_next; } .Ed
p The fields of the .Va timecounter structure are described below. l -tag -width indent t Fn "u_int (*tc_get_timecount)" "struct timecounter *" This function reads the counter. It is not required to mask any unimplemented bits out, as long as they are constant. t Fn "void (*tc_poll_pps)" "struct timecounter *" This function is optional and can be set to .Dv NULL . It will be called whenever the timecounter is rewound, and is intended to check for PPS events. Normal hardware does not need it but timecounters which latch PPS in hardware do. t Va tc_counter_mask This mask should mask off any unimplemented bits. t Va tc_frequency Frequency of the counter in Hz. t Va tc_name Name of the timecounter. Can be any NUL-terminated string. t Va tc_quality Used to determine if this timecounter is better than another timecounter - higher means better. Negative means .Dq only use at explicit request . t Va tc_priv Pointer to the timecounter's private parts. t Va tc_next For internal use. .El
p To register a new timecounter, the hardware device driver should fill a .Va timecounter structure with appropriate values and call the .Fn tc_init function, giving a pointer to the structure as a .Fa tc parameter. .Sh TIMESTAMP FORMAT The timestamp format used in the machine independent timecounter implementation is a .Va bintime structure: d -literal -offset indent struct bintime { time_t sec; uint64_t frac; } .Ed
p The .Va sec field records the number of seconds as well as the .Va tv_sec field in the traditional x .Va timeval and .Va timespec structures, described in .Xr timeval 3 .
p The .Va frac field records fractional seconds represented in a fully 64 bit integer, i.e. it goes all the way from .Li 0 through .Li 0xFFFFFFFFFFFFFFFF per each second. The effective resolution of the .Va frac value depends on a frequency of the machine dependent timecounter source.
p The .Va bintime format is a binary number, not a pseudo-decimal number, so it can be used as a simple binary counter without expensive 64 bit arithmetic. .Sh CODE REFERENCES The timecounter framework is implemented in the file
a sys/kern/kern_tc.c . The .Va bintime structure and related functions are defined in the file n sys/time.h . .Sh SEE ALSO .Xr clock_settime 2 , .Xr ntp_adjtime 2 , .Xr settimeofday 2 , .Xr bintime 9 , .Xr bintime_add 9 , .Xr binuptime 9 , .Xr hz 9 , .Xr time_second 9 .Rs .%A Poul-Henning Kamp .%T "Timecounters: Efficient and precise timekeeping in SMP kernels" .%J "Proceedings of EuroBSDCon 2002, Amsterdam" .%D 15-17 November, 2002 .%U http://phk.freebsd.dk/pubs/timecounter.pdf .Re .Sh HISTORY The timecounter interface first appeared in .Fx , and was ported to .Nx 4.0 by Frank Kardel and Simon Burge.