NAME
timecounter
,
tc_init
—
machine-independent binary
timescale
SYNOPSIS
#include
<sys/timetc.h>
void
tc_init
(struct
timecounter *tc);
DESCRIPTION
The timecounter interface is a machine-independent implementation of a binary timescale using whatever hardware support is at hand for tracking time.
A timecounter is a binary counter which has two properties:
- it runs at a fixed, known frequency; and
- it has sufficient bits to not roll over in less than approximately max(2 msec, 2/HZ seconds) (the value 2 here is really 1 + delta, for some indeterminate value of delta).
The interface between the hardware which implements a timecounter and the machine-independent code which uses this to keep track of time is a timecounter structure:
struct timecounter { timecounter_get_t *tc_get_timecount; timecounter_pps_t *tc_poll_pps; u_int tc_counter_mask; u_int64_t tc_frequency; const char *tc_name; int tc_quality; void *tc_priv; struct timecounter *tc_next; }
The fields of the timecounter structure are described below.
- 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.
- void
(*tc_poll_pps)
(struct timecounter *) - This function is optional and can be set to
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. - tc_counter_mask
- This mask should mask off any unimplemented bits.
- tc_frequency
- Frequency of the counter in Hz.
- tc_name
- Name of the timecounter. Can be any NUL-terminated string.
- tc_quality
- Used to determine if this timecounter is better than another timecounter - higher means better. Negative means “only use at explicit request”.
- tc_priv
- Pointer to the timecounter's private parts.
- tc_next
- For internal use.
To register a new timecounter, the hardware device
driver should fill a timecounter structure with
appropriate values and call the
tc_init
()
function, giving a pointer to the structure as a tc
parameter.
TIMESTAMP FORMAT
The timestamp format used in the machine independent timecounter implementation is a bintime structure:
struct bintime { time_t sec; uint64_t frac; }
The sec field records the number of seconds as well as the tv_sec field in the traditional UNIX timeval and timespec structures, described in timeval(3).
The frac field records fractional seconds
represented in a fully 64 bit integer, i.e. it goes all the way from
0
through 0xFFFFFFFFFFFFFFFF
per each second. The effective resolution of the frac
value depends on a frequency of the machine dependent timecounter
source.
The 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 arithmetics.
CODE REFERENCES
The timecounter framework is implemented in the file
sys/kern/kern_tc.c. The
bintime structure and related functions are defined in
the file <sys/time.h>
.
SEE ALSO
clock_settime(2), ntp_adjtime(2), settimeofday(2), bintime(9), bintime_add(9), binuptime(9), hz(9), time_second(9)
Poul-Henning Kamp, Timecounters: Efficient and precise timekeeping in SMP kernels, Proceedings of EuroBSDCon 2002, Amsterdam, http://phk.freebsd.dk/pubs/timecounter.pdf, 15-17 November, 2002.
HISTORY
The timecounter interface first appeared in FreeBSD, and was ported to NetBSD 4.0 by Frank Kardel and Simon Burge.