Hi,
Your method depends on HZ being 1024. It is ad-hoc. We might want this
because it happens so often, but I personally perfer a general solution.
Below is a code snippet that uses fixed-point arithmetic to calculate
tick much more accurately (10 bits behind the binary point). For 1
million microseconds in a second and 1024 ticks per second, that
yields exactly 0 error.
But if you happen to have 555 (*) ticks per second, it will be much
more accurate than the older algorithm (in fact one 40th of a
microsecond per second of systematic error is quite acceptable don't
you think? The old system yielded 110 microseconds of error per
second. ;-).
(*) The 555 is completely arbitrary. I just banged on my keyboard to
get an example number that doesn't divide evenly.
As the final code is slightly more complicated than the standard
time += tick;
you could make this code conditional on:
#if HZ * (1000000/HZ) != 1000000
/* #warning "HZ doesn't divide." */
#define USE_FP_TICK
#else
#define USE_SIMPLE_TICK
/* #warning "HZ DOES divide." */
#endif
/* Code snippet: */
#include <stdio.h>
#define HZ 1024
#define FP_SHIFT 10
#define FRAC_BITS 0x3ff
int main (int argc, char **argv)
{
long tick;
int residual, tick_of_the_day;
int i;
int time;
residual = time = 0;
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
tick = ((1000000 << FP_SHIFT) + HZ/2) / HZ;
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
for (i=0;i < HZ;i++) {
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
residual += tick;
tick_of_the_day = residual >> FP_SHIFT;
residual &= FRAC_BITS;
time += tick_of_the_day;
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
printf ("%d %d %d\n", time, tick_of_the_day, residual);
}
exit (0);
}
I'm willing to prepare a patch if Linus says he'll include it in the
kernel.
Roger.
P.S. Having had a look at the kernel code: A similar thing is being
done with time_adj. It could be initialized to 1000000 - HZ * tick.
That would make time move a little more jerky, but have the same
effect. (yeah, you also have to add this in every time an assignment
is made to this variable. I think this modifies the "bandwidth" of
adjustments to be asymetrical.)
-- If it's there and you can see it, it's REAL |___R.E.Wolff@BitWizard.nl | If it's there and you can't see it, it's TRANSPARENT | Tel: +31-15-2137555 | If it's not there and you can see it, it's VIRTUAL |__FAX:_+31-15-2138217 | If it's not there and you can't see it, it's GONE! -- Roy Wilks, 1983 |_____|- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu