[plug] Scheduling and Blocking Explained

Brad Campbell brad at seme.com.au
Thu May 18 16:39:27 WST 2000


Right, For those that may be interested.. here goes..

1st, Chaning the HZ value is Legit. It is different on different
archs, and is an arbitary value chosen by the kernel developer
on that arch. ie i386 is 100, Alpha is 1024.
Some of the low latency audio guys change it to 1000 to get a 
snappier system response.

The interrupt handler for the serial port is divided into 2 parts
The Top Half and the Bottom Half.
The top half runs immediately the UART interrupts, and this
schedules the bottom half to run.
The bottom half is the bit that wakes up any processes blocking
on this file descriptor, and the bottom half only runs on a 
clock tic (10ms) in standard i386 Linux.

This means, that my program goes to sleep, and waits 8ms for
the bottom half to be scheduled, run, and wake my process up.

The bottom half handlers are run by return_from_sys_call
which gets called every clock tic(10ms) or when a process
blocks on a system call.
The problem is my process runs for 3xuSec, then blocks, where
the bottom half does not get scehduled for another 1.9xmSec.
Therefore, the only way to solve my problem is to increase the HZ
value in the kernel. Which as I said above, is a perfectly Legit
fix :p)
Just means a total kernel re-compile including modules.
Not really a hassle.

Thanks for all your ideas, and patience. I now understand a lot
more about the scheduling workings of the kernel than I did before.

========================================================================

In regard to the request for explanation on Blocking IO.. I'll have
a stab at it.

A blocking IO call will not return until either all the data is sent,
or at least 1 byte is recieved. So I can send 4 bytes to a file
descriptor (Coz all unix IO is by file descriptors) and my program
will block until all that data is transmitted. Blocking in this case
means the program is put to sleep, and the kernel is told to wake it
up only when all the data is has to send has been sent.
A blocking read call will put the process to sleep until there is at
least 1 byte to be read on the file the process blocked on.

This removes the need for a program to "Poll" for data and waste cpu
time.

Non blocking IO is just the opposite.
You do a write() and your program jams that data in to the drivers buffer
and plods along happily.
If you do a read() and there is no data waiting, the read() will usually
return an -EAGAIN instead of valid data, letting you know there was nothing
waiting.
This is where select() comes in handy, as you can look at multiple File
descriptors at once, and select will retun if any of them have data waiting
or any of them are ready to be written to, or any of them return an exception,
or any combination of the above. It also has a timeout value so you can return
from the call and run periodic timer type of routines while there is no IO 
happening.

Clear as Mud ?

The reason I used select in my program rather than blocking IO and multiple
threads or watchdog programs, is it's a hell of a lot simpler to do. And I'm
not yet familiar with spawning threads, so I multiplex my IO.
For what I do, it's plenty fast enough, and simple to write.


-- 
Brad....
"The ultimate result is that some innovations that would
truly benefit consumers never occur for the sole reason
that they do not conincide with Microsoft's self-interest"
- Judge Thomas Penfield Jackson
         /"\
         \ /     ASCII RIBBON CAMPAIGN
          X      AGAINST HTML MAIL
         / \



More information about the plug mailing list