From: nigel@gamble.uucp (Nigel Gamble)
Subject: Re: real time
Organization: Nigel Gamble, Consultant
Date: Sun, 3 Jan 1993 11:45:51 GMT

In <1993Jan3.054159.11008@umr.edu> quandt@cs.umr.edu (Brian Quandt) writes:
>What can anyone say about linux and real time support?  Same
>question applies to 386bsd.  I tend to believe that this concept
>would not be possible.  The reason being is that this (I believe)
>is a fundamental design change in how the kernal works.

Linux, in common with other traditional UN*X implementations will not
support real time applications.  Real time UN*X does need a fundamental
design change in the kernel, usually referred to as a `fully preemptible'
or `fully semaphored' kernel.  There are two main issues to consider:
interrupt handling and process context switching.

Real time processes tend to be interrupt driven; they spend most of
their time asleep, but when the external device they are controlling
sends an interrupt, it is essential that they can be woken up to
deal with the device within the designed time constraints of the
system, e.g. `within 100 microseconds'.  When the interrupt occurs,
the computer may be in the interrupt routine of some other device
with interrupts disabled.  The interrupt routine cannot even begin
to execute until interrupts are enabled again.  This has to be taken
into consideration in the design of every device driver in the system.
It is usual to have a design rule for interrupt handlers specifying the
maximum time that they are allowed to run with interrupts disabled.
This will typically be of the order of 100 microseconds.  If just one
device breaks this rule, you have not got a real time system.

When the interrupt routine gets to run, it needs to wake up the user
process and schedule it to run *now*.  The context of the currently
executing process (if of lower priority) is saved and the new process
is given the CPU.  So a context switch is forced, even if the current
process is executing in the kernel.  In Linux all that the interrupt routine
can do to wake up the new process is to mark it as runnable.  If the
currently running process is executing a system call in the kernel, the
new process must wait until the current process either completes the system
call, or voluntarily calls sleep() or shedule().  Otherwise kernel data
structures may be corrupted, since this is the way that they are protected
in a traditional kernel design.

A real time fully preemptible kernel design allows multiple processes
to be executing in kernel mode simultaneously.  On a uniprocessor this
means logically simultaneously, but on a multiprocessor system this
means *actually* simultaneously.  (It is interesting that the design
needed for a good real time system also gives you the basis for a good
multiprocessor system).  This is acheived by protecting the critical
regions of kernel code with kernel semaphores.  The critical regions
must be kept as short as possible; this is another design parameter.
Now the wake_up() call (which is implemented as a semaphore signal
operation) can actually cause a context switch to the new process
without waiting for the current process to decide to call sleep()
or schedule().  This, again, should typically take not more than
100 microseconds.

Assuming that the design rules are followed by the kernel *and all of
the device drivers*, you can predict the worst case time from the
initial interrupt through the interrupt handler, through the context
switch, to the first user level instruction of the new (assuming highest
priority) process, typically 300 microseconds.  If this worst case time
is good enough for your application, you have a real time system.
-- 
Nigel Gamble                                    gamble!nigel@uunet.UU.NET
Ft. Lauderdale, FL                              uunet!gamble!nigel
Newsgroups: comp.os.linux