Timer-Wrap

Richard B. Johnson (root@chaos.analogic.com)
Fri, 10 Oct 1997 11:15:40 -0400 (EDT)


Several days ago, I presented the following suggestion. For some
reason, it never got into linux-kernel. I think it is too important
for a "software filter" to reject.

On Wed, 8 Oct 1997, Ingo Molnar wrote:

>
> On Wed, 8 Oct 1997, Finn Arne Gangstad wrote:
>
> > Using a signed comparison means you rule out half the possible timeout
> > values. [...]
>
> we need this 'negative timeouts' range, to detect 'PAST' timeouts. Ie.:
>
> -0x7fffffff .... PAST() ..... NOW()==0 ..... FUTURE() ..... +0x7fffffff
>
> timeouts are not only used in timers, they are also hand-used in _many_
> places, see the schedule() example in my previous mail.
>
> and we are talking about _timeouts_, which are usually in the range of
> milliseconds and seconds. Now we limit them to ~200 days on 32 bit CPUs,
> bummer. Having the above split is not a RL limitation, and is the fastest
> thing assembly-wise, especially on RISC CPUs.
>
> -- mingo
>

To solve a similar problem within another Operating System, I used
the following method:

Kernel system call "add_timer()". This sets a pointer to a longword
that the timer ISR will decrement to zero, but not below. This was
written in 'C' and simply maintained an array of pointers. The
actual timer code, operated in the context of an interrupt. It
looked like this:

Intel: destination <----> source
mov esi, offset _timers ; Point to list of pointers
; set/maintained by 'C' code
do_timers:
mov ebx,dword ptr [esi] ; Get user's pointer
lea esi, [esi+4] ; Ready next
or ebx,ebx ; End of list?
jz end_of_list ; yes
sub dword ptr [ebx],1 ; Bump timer
adc dword ptr [ebx],0 ; But not below zero
jmp short do_timers ; Continue
end_of_list:

Kernel system call "del_timer()". This removed the above timer from
the list of timers. This was written in 'C'.

int demo()
{
volatile unsigned long tim;
tim = TIME_TO_WAIT;
add_timer(&tim);
while(tim)
{
if(!check_something())
schedule();
else
break;
}
del_timer(&tim);
if(tim)
was_ok();
else
did_timeout();
}

del_timer() stole time from the caller to reorder the list of pointers
so the very first NULL pointer meant the end of the list. I found that
on a system that maintained a complex state-machine, with timers being
used to detect exceptions practically everywhere (a CAT Scanner), there
were seldom more than 3 timers in simultaneous use. The ISR overhead
was therefore very low.

The advantage is that there can never be a "timer-wrap". You can time-out
up to about 200 days which should work for everything except Adaptec
Controllers <grin>.

Cheers,
DJ
Richard B. Johnson
Analogic Corporation
Penguin : Linux version 2.1.55 on an i586 machine (66.15 BogoMips).
Warning : It's hard to stay on the trailing edge of technology.
Linux : Engineering tool
Spam : sync@localhost, daemon@loghost