TSC, power management, and program correctness

The RDTSC instruction to read the Pentium Time Stamp Counter (internal cycle counter of the Pentium and greater Intel CPUs, all compatibles, and some 486-class CPUs from other manufacturers such as the 5×86) is a syscall-free way for userspace programs on Intel platforms to do timing. However, the system CPU can be slowed or halted by things like cpufreq, APM BIOS, or ACPI power methods, and this causes the TSC count to slow as well. After a power management event, the TSC will be an incorrect reflection of real time to the program and the program will malfunction.

The correct way to deal with this is to create a thread that opens /dev/apm_bios and /var/run/acpid.socket if they exist, and when a power management event is detected from either source, recalibrate the program's TSC timing based on gettimeofday again.

CPUFreq can be dealt with by polling /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq and watching for any change there. Also, on recent kernels, when cpufreq is in effect, /proc/cpuinfo will reflect the current CPU speed, so it can also be used to detect CPU speed changes.

TSC is handy for timing in user programs because it is so cheap, but for correct program behavior it can be a hazard. As long as any event that could cause a CPU frequency change is accounted for, it can still be useful on modern systems.

Leave a Reply