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