Re: gettimeofday nanoseconds patch (makes it possible for theposix-timer functions to return higher accuracy)

From: Christoph Lameter
Date: Thu Jul 15 2004 - 12:06:24 EST


On Thu, 15 Jul 2004, john stultz wrote:

> > The old code only insured that the interpolated offset in nanoseconds
> > after a timer tick never goes backward. Negative corrections to xtime
> > could also result in time going backward since the offset is
> > always added to xtime. Both the old and the new code use the logic in
> > time_interpolator_update (invoked when xtime is advanced) to compensate
> > for this situation.
>
> However it seems this compensation also negates NTPs adjustment. There
> is nothing that scales the time_interpolator_update's output.
>
> A quick example:
> So lets say tick length is 1000us. At time zero we call gettimeofday(),
> it returns xtime + time_interpolator_update(), both return zero. 999us
> later at time two, the same thing happens and we return (0 + 999). A
> usec later at time three, the timer interrupt is called and xtime is
> incremented 1000us, and time_interpolator decrements 1000us. Thus a call
> to gettimeofday would return (1000 + 0). Immediately following, adjtimex
> is called, setting the tick length to 900us. Then 999 usecs later at
> time four, we return (1000 + 999). The next usec at time five, the timer
> interrupt goes off and increments xtime by 900, and decrements the
> time_interpolator by 900. Thus a call to gettimeofday() would return
> (1900 + 100). So rather returning the proper NTP adjusted time of 1900,
> 2000 is being returned as if the NTP adjustment never occured.

The above omits some details but is basically correct. Note that the
time_interpolator gradually brings time back into sync with xtime because
it looses a few nanoseconds (depending on the clock) each tick. At
some point the correction asked for by the timer tick will be greater than the
offset and at that time the offset is set to zero. Then a resync has
occurred.

> Now, you cannot have time going backwards, so the solution is to cap the
> output of time_interpolator_update() by insuring that during an NTP
> adjusted tick, we do not return more then the NTP adjusted tick length
> added to the base offset we calculated at the last timer interrupt.

> Thus at time four above(and during the 99 usecs before it) we would
> return (1000 + 900) instead of (1000+999).

Having time stand still is an awkward solution: Time may stand
still even longer if the tick is delayed and then time suddenly jumps
ahead when the tick finally occurs.

The existing implementation slowly compensates and is the best solution
IMHO.

> And again, the ia64 code isn't my specialty, so if I'm just being daft,
> please let me know.

What I described was coded by others. I just hope that I have explained it
accurately.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/