DragonflyBSD kernel clock improvements
dillon at apollo.backplane.com
Sat Jan 24 11:48:16 PST 2004
There are a couple of things going on here... it isn't all just fluff.
First, the basic problem is that nanosleep() (aka sleep() aka
usleep()) consistently sleeps for far longer then the requested time.
It isn't jitter. It's consistently too long. While it is true
that the spec allows for this, there isn't much of a point in having
a 'nanosleep' call (emphasis on 'nano') which produces wildly
varying results for small intervals. While I haven't completely
solved this issue yet (I have to completely rewrite the timer code
to fix it properly), it has been made far more consistent.
Second, the fractional compensation code for the 8254. The 8254 runs
at 1193182 Hz. If your 'hz' is set to 100, a fixed clock reload value
of 11931 looses significant precision. The higher your 'hz' setting,
the more precision is lost and the greater the error verses real time.
If you are using the 8254 as your wallclock, then you will see a
significant 'speed up' of the wall clock at higher hz settings.
hz will wind up being far higher then the true frequency you
requested. It isn't just jitter... it's a permanent error factor and
it can create significant problems if you are running ntpd.
So the fractional compensation code is designed to minimize this error.
The fractional compensation code is NOT the PLL.
Third, if you are not using the 8254 for your wallclock there will be
persistent drift between clocks based on the 8254's hz-based interface
(ticks) and clocks based on realtime. The PLL part of the fix simply
compensates for the 8254's constant drift relative to the wallclock
by occassionally adding one or subtracting one from the 8254's reload
This third part is not really necessary, but it was fun to do so I
did it. I like consistency and I hate sawtooth patterns.
More information about the freebsd-current