Re: RFC: 'more signals' patch, 2.1.33

Richard Henderson (richard@stommel.tamu.edu)
Tue, 15 Apr 1997 14:46:29 -0500 (CDT)


> - make action[] is a single indirection sparse array, NULL means a { 0,
> 0, 0, 0 } sigaction element. Allocation via SLAB cache, thus no latency
> problems. [lmbench agrees with me ;)]

Good plan.

> now where the thing becomes ugly:
>
> - big assumption: signal #32 is abused as an 'extended' bit. Thus no need
> to push the new signal code down to the assembly level and deep into
> kernel drivers. 'extended signals' can only be sent between processes,
> the first 31 signals serve as 'kernel-internal fast signals'

This, I think, is not a good idea. While POSIX likely has nothing
against reserving numbers -- or even weird definitions of sigset_t --
it does still require changes at all levels and is somewhat non-intuitive.
In addition, for .1b we want to be able to handle _lots_ of signals;
glibc currently has provision for 1024, I think.

But I don't think it will be necessary to diddle with entry.S. ;-)

We will, pretty much by definition, require a new set of syscalls to
handle the new signals. I suggest we do it in such a way that the
kernel and libc are somewhat disconnected about the number of signals.

What about the following:

-- For speed reasons, I think we need to have the number of signals
handled by the kernel be a constant. But an arbitrary constant
that can be trivially changed at compile time.

This lets us continue to use the SLAB as Ingo indicated and lets
gcc do a bit of simple loop unrolling.

-- Arrange for the system call to indicate the size of the signal
set. This decouples libc from the kernel in this respect. It
will be a more difficult job decoupling libc and the application,
but I think this can be done as well.

Thus you wind up with syscalls like:

sys_xsigprocmask(int how, u_long *set, u_long *oset, int setsize)
sys_xsigaction(int sig, sigaction *new, sigaction *old, int setsize)

where `setsize' is the size of the signal set in bits or words or
whatever. Note that the input and output sa_mask are the same size
in user space, which seems like a resonable restriction. Leave it
up to the port to decide how they are going to interpret the order
of the bits across words.

If an application uses a sigset larger than the kernel was built
to handle, the high bits are ignored. We should provide some
method to allow the application to query the kernel's limit so that
it may abort if it _really_ needs that many.

A slightly more difficult situation is what to do with sigsets
smaller than the kernel's, at least if we do manage to decouple
libc from other libraries from the application. Consider the
common idiom:

struct sigaction new, old;

new = ...
sigaction(SIGFOO, &new, &old);
...
sigaction(SIGFOO, &old, NULL);

which assumes that things are restored intact. But if this bit were
in a library and the application was using a larger sigset, then
the top bits will be lost.

Of course, things may very well be fucked anyway if the libarary
have different ideas on what should be done with that signal. *shrug*

Thoughts?

r~