Re: [RFC - 0/9] Generic timekeeping subsystem (v. B5)
From: Roman Zippel
Date: Tue Aug 23 2005 - 06:31:03 EST
Hi,
On Mon, 22 Aug 2005, john stultz wrote:
> The reason why we calculate the interval_length in the continuous
> timesource case is because we are not assuming anything about the
> frequency that the timekeeping_periodic_hook() is called.
The problem with your patch is that it doesn't allow making such
assumptions.
Anyway, it's rather simple, if you want to update the time asynchronously:
cycle_offset = get_cycles() - last_update;
while (cycle_offset >= update_cycles) {
cycle_offset -= update_cycles;
last_update += update_cycles;
// at init: system_update = update_cycles * mult;
system_time += system_update;
xtime += [tick_nsec, time_adj];
}
error = system_time - (xtime.tv_nsec << shift);
if (abs(error) > update_cycles/2) {
mult_adj = (error +- update_cycles/2) / update_cycles;
mult += mult_adj;
system_update += mult_adj * update_cycles;
system_time -= mult_adj * cycle_offset;
error -= mult_adj * cycle_offset;
}
if (xtime.tv_nsec + (error >> shift) > NSEC_PER_SEC) {
system_time -= NSEC_PER_SEC << shift;
second_overflow();
}
Since we usually don't have to adjust for the error all at once, it should
be possible to precalculate some of it in adjtimex/second_overflow and
turn mult_adj into a mult_adj_shift.
I didn't really check the math here in detail, so there should be enough
errors left :), but I hope it's enough to show the idea (especially how to
do it without mult/divide).
There are now variations of this possible, the initial cycle_offset can be
constant, this happens if it's regularly called from an interrupt (and
it's sufficient for UP systems). We could also completely ignore the
error, so that the core calculation of the above results in the familiar:
xtime += [tick_nsec, time_adj];
if (xtime.tv_nsec > NSEC_PER_SEC)
second_overflow();
Another variation would be useful for ppc64 (or maybe any 64bit arch, but
ppc64 has already the matching gettimeofday). In this case we don't use a
timespec based xtime and don't scale it to ns, but use 64bit values
instead scaled to seconds.
The last one may become a bit of a challenge to keep as much as possible
code common without abusing the preprocessor too much. In any case some
functions will differ completely anyway, especially gettimeofday will be
optimized differently depending on the arch/clock requirements, OTOH
introducing a common gettimeofday (that would even require a 64bit
divide) would be a huge mistake.
bye, Roman
-
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/