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.
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.