TSC(9) Kernel Developer's Manual (x86) TSC(9)

NAME

tscTime Stamp Counter

SYNOPSIS

#include <x86/x86/tsc.h>

uint64_t
rdtsc(void);

void
tsc_tc_init(void);

void
tsc_sync_ap(struct cpu_info *ci);

void
tsc_sync_bp(struct cpu_info *ci);

void
tsc_sync_drift(int64_t drift);

DESCRIPTION

The time stamp counter (TSC) is a hardware counter found in all contemporary x86 processors. The counter is implemented as a 64-bit model-specific register (MSR) that is incremented at every clock cycle. The RDTSC (“read time stamp counter”) register has been present since the original Pentium.

Already because of the access method, TSC has traditionally provided a low-overhead and high-resolution way to obtain CPU timing information. Recently, however, this reliability has been undermined by such factors as system sleep states, CPU “hotplugging”, “hibernation”, and CPU frequency scaling.

These potential new sources of unreliability are easily understandable when one recalls that the counter measures cycles and not “time”. Comparing the cycle counts only makes sense when the clock frequency is stable; to convert the cycle counts to time units, a general equation would be: “seconds = cycles / frequency in Hz”. The use of TSC as a source of high-resolution timing can be thus discouraged. But the basic premise is still guaranteed: TSC is a monotonically increasing counter.

FUNCTIONS

rdtsc()
The rdtsc() function returns the value read from RDTSC.
tsc_tc_init()
The tsc_tc_init() function initializes the TSC as a timecounter(9). The function is called early in the boot process when the processors attach.
tsc_sync_ap(ci)
The tsc_sync_ap() function synchronizes the counter for the boot processor (BP). The supplied ci must refer to the BP itself. The tsc interface takes internally care of such issues as out-of-order execution, where instructions are not necessarily performed in the order of execution, possibly causing a misleading cycle count.
tsc_sync_bp(ci)
The tsc_sync_bp() function synchronize the counter for the application processor ci. Interrupts must be off at machine-level when the function is called.

It is necessary to call both tsc_sync_ap() and tsc_sync_bp() during the boot, but additional synchronization may be required also during runtime. As an example, the TSC needs to be synchronized for all processors when the system resumes from an acpi(4) sleep state.

tsc_sync_drift(drift)
Finally, the tsc_sync_drift() function records drift, measured in clock cycles. This is called when the APs attach.

SEE ALSO

gettimeofday(2), hpet(4), hz(9), rdmsr(9), timecounter(9)
October 25, 2011 NetBSD 6.1