I think you're wrong, but feel free to double-check..
> /* .. relative to previous jiffy (32 bits is enough) */
> time_low -= (unsigned long) last_timer_cc;
> ??? We have two 64 bit quantities, and we are interested in the least
> ??? significant 32 bit. Currently just the "low longwords" are
> ??? subtracted, yielding a possible overflow (result in unsigned).
> ??? Usually you would need some carry processing.
Carry makes a difference only for the high 32 bits, and as we're going to
ignore the high bits in the result anyway, we don't care. Essentially,
what we're doing is a 64-bit subtract, and then extracting the low bits,
so the expression we're looking for is actually
(t2 - t1) mod 2^32
but that is mathematically equivalent to what we're doing:
((t2 mod 2^32) - (t1 mod 2^32)) mod 2^32
Remember, C defines unsigned integer arithmetic to work this way
(although the "32" part is implementation defined), so we're not even
depending on any special behaviour here - this is just how the addition
operator works in C.
I guess anybody who wants to be _really_ sure needs to take a course
in algebra, and think about what the operator "+" really means in different
circumstances.
Btw, linux depends on this property of unsigned arithmetic in C in other
places too - take a look at the "before()" and "after()" functions that
define the incomplete order of TCP sequence numbers in the same "modulus
2^32" mathematical world ;-)
> if (quotient >= 1000000/HZ)
> quotient = 1000000/HZ-1;
>
> ??? Is this the correction for the missed carry?
No, that's just correcting for the fact that the way we do calculations
we can't really depend on everything being exact: if we have lost a few
timer ticks along the way we should make sure that we don't let the
"correction factor" grow too large (otherwise we might end up with a
struct timeval that is not monotonically growing after the next timer
tick).
Linus