Subject: Re: device driver questions
To: None <brook@biology.nmsu.edu, jdolecek@netbsd.org>
From: Wolfgang Solfrank <ws@tools.de>
List: current-users
Date: 10/09/2001 13:17:30
Hi,

> The issue here is the minimum time quantum you can sleep in tsleep()
> is one tick.  The 'tick' time value quantum is machine-dependant
> and depends on HZ.  For example: i386 has HZ=100 commonly, i.e.
> one tick is 10ms. Alpha has HZ=1000, i.e. one tick is 1ms. Thus, tsleep()
> might not be too suitable if you'd need to poll a device and need
> to find out a condition happened as fast as possible. If you don't
> care about milisecond here and milisecond there, tsleep() is okay :)

Sorry, this is not correct.  tsleep() puts the process calling it to sleep,
and it is normally woken up by a call to wakeup() using the same value as
its first argument.  When the process is woken up, it gets rescheduled
with the priority given as the second argument to tsleep.  Now keep in
mind that the NetBSD kernel doesn't preempt any processes running kernel
code, but processes running kernel code always have higher priority than
processes running userland code.

Let's assume a typical case where the wakeup() is done in an interrupt
handler.  This leads us to the following possible scenarios:

1. The interrupt happened while a process was running in userland.
In this scenario, the return from interrupt will, before returing to
userland, detect that the woken up process is ready to run some kernel
code, and will switch to this other process.

2. The interrupt happened while some other process is running in the
kernel.  The wakeup puts the process woken up on the scheduler queue in
a place corresponding to its new priority.  Then the interrupted process
continues.  Under normal circumstances, the code run by it will soon
reach one of two points:

2a: It calls tsleep() itself.  Then the scheduler picks another process
from the queue of ready processes, hopefully the one previously woken up,
and puts it to run.

2b: It returns to userland.  As in 1. above, the code returning to userland
will detect that there is another process ready to run some kernel code,
again hopefully our woken up process, and will switch to it.

Under normal circumstances, the time a process is waiting after the
wakeup() and before it gets the cpu is much less than a clock tick.
The only exception is if some kernel code contains an excessively long
busy loop (which obviosuly shouldn't happen).  Even then, there is no
correlation between HZ and the time that busy loop is lasting (except
of course, if the loop is explicitly testing some tick related condition).

The only place where HZ comes into play with respect to tsleep() is the
timeout you can specify on the tsleep() call.  This timeout is indeed in
terms of 1/HZ seconds, but this comes into play only when nothing calls
wakeup() on the channel you are tsleep()ing on, and the process has to
recover from this situation somehow.

Hope it helps.

Ciao,
Wolfgang
-- 
ws@TooLs.DE     Wolfgang Solfrank, TooLs GmbH 	+49-228-985800