HZ(9)

πŸ“¦
version 15.1 Β· 3 versions
, in freebsd 14.5, freebsd 15.1, nixpkgs unstable

πŸ’– HZ(9) β€” the system time model, explained by your favorite kernel bestie πŸ’–

okay so this is from the Kernel Developer's Manual and it's literally all about how time works inside FreeBSD. no cap, it's giving main character energy for the whole scheduler. let's get into it 🫢


✨ NAME ✨

hz, tick, stathz, profhz β€” the system time model, aka the four variables that keep your kernel's clock behaving. one of them (profhz) is lowkey deprecated, but we'll get there πŸ’…


🌸 SYNOPSIS 🌸

#include <sys/kernel.h>

extern int hz;
extern int tick;
extern int stathz;
extern int profhz; /* deprecated */

like, include the header and boom, these four extern int globals are yours to vibe with. (yes profhz has the sad little /* deprecated */ comment, we don't make the rules 😭)


πŸ¦‹ DESCRIPTION πŸ¦‹

FreeBSD uses periodic, one-shot, global or per-CPU timing hardware via eventtimers(9) to produce that traditional clock behavior you know and love. these clocks are the ones regulating periodic events in the system. iconic behavior fr fr ✨

the main clock updates the system's notion of time via timecounters(9) and paces periodic system processing as documented in hardclock(9). that routine may be called once every 1 / hz seconds β€” though ngl the call is omitted if no work is needed in the next tick and it has not been 0.5 seconds since the last call. efficiency slay πŸ’…

the stat clock, running at stathz, gathers statistics on the system and its processes. it computes values for getrusage(2) and the statistics displayed by ps(1) and top(1). so when you're staring at top like πŸ‘€ that's this clock doing its thing.

finally, a profiling clock may run at profhz to sample user program counter values for profiling purposes. but bestie… this profiling mechanism has been replaced by the more functional hwpmc(4) and may be removed in a future version of FreeBSD. so like, don't get too attached πŸ₯²

tick is the length of time in microseconds of one system tick. tiny but mighty.

these system variables are also available as struct clockinfo from sysctl(3) and kern.clockrate from sysctl(8). iykyk.

the current global and per-CPU CPU time usage is returned to the user in units of 1 / stathz ticks in the kern.cp_time and kern.cp_times sysctl MIBs.

the hz rate may be overridden by defining HZ in the kernel configuration file or by setting the kern.hz system tuneable via loader.conf(5). options, we love to see it 🌈

⚠️ the current default is 1000 Hz for a tick of 1 ms for real hardware. for virtual machine guests, the default is 100 Hz for a tick of 10 ms. only override the default value if you really know what you are doing. like, fr fr, don't just poke it because it looks fun πŸ™ˆ

and due to the adaptive nature of timeouts, changing this value has less effect than it had in the past. so it's not the chaos lever it used to be, but still β€” respect the defaults πŸ’œ


πŸŽ€ SEE ALSO πŸŽ€

go read them, they're all part of the lore πŸ“šβœ¨


🧚 IMPLEMENTATION NOTES 🧚

historically, both the stathz and profhz clocks have run off the same physical timer β€” running at the slower rate when no process is using the profile features, or at the higher rate when at least one process is using it. although the interface is deprecated by IEEE Std 1003.1-2008 (β€œPOSIX.1”) in favor of timer_settime(2), several programs still use setitimer(2) and ITIMER_PROF for a higher-resolution periodic interrupt than has been traditionally available. old habits, etc etc πŸ’€

historically, hardclock(9) has also been run off a separate interrupt, except on constrained platforms that lack enough periodic interrupt sources. FreeBSD uses eventtimers(9) to abstract these details away, though some old code may still harbor assumptions that are an imperfect fit to this abstraction. it's giving "legacy code has trust issues" 😭

timecounters(9) are limited to 32-bits and wrap after about a second, so we must update the time hands they maintain at least every half second to get the proper wrapping math. and in addition, kern.cp_times needs to be updated at least once a second so that the values displayed by top(1) update every second. the math is mathing but only if you feed it on schedule πŸ“


πŸ’« and that's the whole page bestie. no cap, you now understand the system time model better than half the people who read it. slay.

β€” from the Debian edition, dated July 1, 2021. mwah πŸ’‹

πŸ“¦ where this page comes from