Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!seismo!gatech!hao!husc6!cmcl2!edler
From: edler@cmcl2.NYU.EDU (Jan Edler)
Newsgroups: comp.unix.wizards
Subject: signals like interrupts?
Message-ID: <17691@cmcl2.NYU.EDU>
Date: Mon, 13-Jul-87 14:07:48 EDT
Article-I.D.: cmcl2.17691
Posted: Mon Jul 13 14:07:48 1987
Date-Received: Tue, 14-Jul-87 06:10:42 EDT
Reply-To: edler@cmcl2.UUCP (Jan Edler)
Organization: New York University, Ultracomputer project
Lines: 76

Often the comment has been made that "Berkeley signals operate just
like hardware interrupts", or something like that.  I would like to
discuss two particular ways in which it isn't very true.  The problems
are poor handling of synchronous signals and queuing of signals.

It seems to me that signals should be considered to fall into one of
three categories, depending on whether they are sent
	- Synchronously, as a result of program execution
	  (e.g. SIGSEGV, SIGILL),
	- Asynchronously by the system, as a service to the user
	  (e.g. SIGALRM, SIGINT, SIGCHLD), or
	- Asynchronously by another process
	  (e.g. SIGTERM, SIGUSR1, SIGUSR2).
The problem (not Berkeley's; it goes all the way back to early UNIX) is
that the kernel tries to consider all signals in the same way.  Except
for the silent prohibition on ignoring or blocking SIGKILL and SIGSTOP,
you can ignore or block any signal.  You can also send any signal with
the kill system call.

On machines like the pdp11, vax, and 68000, one of the distinctions
between interrupts and exceptions is that the latter can't be blocked.
I believe that, in general, signals in the first category above should
not be ignorable or blockable.  I don't even know what the semantics
should BE when they are ignored!  The only counter-example I can think
of is a signal generated by an exception that can be reasonably
ignored, such as integer overflow on the vax.

Another characteristic of these machines is that peripherals don't
generate exceptions, so when you get a trap through the
illegal-memory-reference vector, you know that you really did get one,
and it wasn't caused by some peripheral board interrupting at the wrong
level or something like that.  I believe that signals of the first
category above (and probably those in the second category as well)
should not be sendable by kill() or killpg().  I know someone will say
"but I like to test my program's SIGSEGV handler by sending SIGSEGV
from the shell", but while this may be a convenience when debugging
relatively small programs I think it is a hindrance to construction of
reliable large systems.

Now let us consider queuing of signals.  It is true that none of the
machines listed above has specific hardware to queue interrupts, but if
the same kind of interrupt is pending from more than one device at the
same time they are effectively queued by the interrupt priority
mechanism.  These machines also have a handshaking protocol between the
sender of an interrupt (i.e. a device controller) and the receiver
(i.e. the cpu).  When a controller asserts a pending interrupt, it
remains asserted until taken by the cpu.  It is up to the controller to
handle the case where the interrupt has not been taken by the cpu
before the next interrupt needs to be sent.  The controller may lose a
second cause for interrupt, or it may just lose data instead, or it may
set a status bit of some kind indicating that an interrupt was lost, or
it may keep an internal count and assure that the proper number of
interrupts are taken by the cpu.  So the problem is dealt with only
indirectly by the architecture, by putting it off onto the device
controllers.  The result is that many controllers probably don't handle
it very well, although it is usually not a big problem given the nature
of the devices.

The point is that while it wouldn't be accurate to say that "interrupts
are queued" on these machines, it is also not true that they share the
problem faced by lost UNIX signals, because they have a priority system
and support a kind of handshaking between the sender and receiver that
is not really available to the UNIX programmer.  So the statement that
signals should be "just like interrupts" is not a very good argument
against queuing signals.

Incidentally, the main reason I want to queue signals is that I want to
use them for asynchronous I/O completions.  The fact that they also
come in handy for SIGCHLD and as a more general reliable ipc mechanism
is just fine.

Jan Edler
NYU Ultracomputer project
edler@nyu.edu
cmcl2!edler
(212) 998-3o nI