Re: nanosleep returning early

From: John Birrell <jb_at_cimlogic.com.au>
Date: Fri, 23 Jul 2004 07:12:09 +1000
On Fri, Jul 23, 2004 at 02:25:16AM +1000, Bruce Evans wrote:
> Now I think I know the reason.  The interval between clock interrupts
> is supposed to be 1/HZ seconds = `tick' microseconds, but it cannot
> be set nearly that precisely, and the imprecision of inversely
> proportional to HZ.  The i8254 counter has a default nominal frequency
> of 1193182 Hz.  Suppose that this is perfectly accurate.  Then to
> implement clock interrupts at HZ hz, we want to program the i8254's
> maximum count to 1193182/HZ in infinite precision, but counts must be
> integers so we must round.  The loss of precision is quite large for
> HZ = 1000: 1193182 / 1000.0 = 1193.182; rounding this (to nearest)
> gives 1193 and an error of 182 in 1193182 = 152 ppm.  Also, the extra
> tick added by tvtohz() is only 1000 uS long, so it only has a chance
> of about 152/1000 to compensate for the rounding error.  Finally, the
> explicit check that the interval has elapsed cannot compensate for
> errors larger than tc_tick/HZ because getnanouptime() is fuzzy.
> 
> Rounding 1193.182 to nearest happens to round down; thus clock ticks
> are shorter than `tick' microseconds, tvtohz()'s value is too small,
> and nanosleep() may return too early.  The loop limits the error to
> about 1 tick in this case.  The i8254 frequency may be calibrated or
> set using sysctl to a more (or less) accurate value.  Then the rounding
> may go the other way so that tvtohz()'s value is too large and nanoleep()
> may return too late.  The loop cannot limit the error in this case.
> The absolute error may be large for long sleeps.  E.g., 152 ppm over
> 1 day is 13 seconds.
> 
> tvtohz()'s value  may also be too large because the i8254 frequency
> is not known accurately.  It's nominal value is wrong by 10-100 Hz
> on my systems.  I minimize errors from this by calibrating all
> timecounters using a common clock.

Thanks for taking the trouble to explain this. 8-)

-- 
John Birrell
Received on Thu Jul 22 2004 - 19:12:11 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:02 UTC