[parisc-linux] [PATCH] timer_interrupt and gettimeoffset.
Carlos O'Donell
carlos at systemhalted.org
Sun Sep 3 14:30:22 MDT 2006
On 9/3/06, Grant Grundler <grundler at parisc-linux.org> wrote:
> I'll rework my code later today to try to match the discussion so far.
Original code:
58 now = mfctl(16);
60 next_tick = cpu_data[cpu].it_value;
70 nticks = 0;
71 while((next_tick - now) < halftick) {
72 next_tick += clocktick;
73 nticks++;
74 }
75 mtctl(next_tick, 16);
76 cpu_data[cpu].it_value = next_tick;
1. Let us assume a 32-bit CPU with a 32-bit counter and a 32-bit
trigger register.
2. Assume that it_value is *near* the signed long boundary (0x7fffff)
3. The counter and trigger match, raising an interrupt.
4. During the interrupt delivery cr16 wraps into negative signed long,
but only a little bit.
Let us say cr16 is ~(0x7fffffff + 50)
5. The value "next_tick - now" is equivalent to:
"next_tick - (-now)" since now is negative.
"next_tick + now"
6. The signed long math wraps, and the solution is a small negative
number, or small positive number, in this case it is +48.
7. The while loop adds clockticks until we are positive and bigger
than halftick. Adding 1 clocktick.
The signed math works correctly as an approximation (off by 2) and I
do admit I find no fault in the math, but it is still confusing.
However, as James points out, if the *real* cr16 gets ahead of the
newly set it_value, by delaying this function due to other interrupts,
then we will have to wait for a full wrap to have it trigger another
timer interrupt.
Cheers,
Carlos.
More information about the parisc-linux
mailing list