Re: clone() and CLONE_PID

David Wragg (dpw@doc.ic.ac.uk)
10 Sep 1999 00:44:57 +0000


The Lost Wizard <lost@l-w.net> writes:
> On 9 Sep 1999, David Wragg wrote:
> > POSIX is just an API; it doesn't tell you how to design a
> > kernel. Generally Linux directly implements POSIX features because
> > that is simpler, but for POSIX threads it's worth stepping back and
> > asking what it really needs from the kernel. My opinion is that doesn't
> > include pid sharing and tids.
>
> It is my understanding that signals cannot be guaranteed to work
> according to the POSIX threads specification without the CLONE_PID option.

You have this the wrong way round. The CLONE_PID option is one
approach to implementing signals according to the POSIX threads
spec. But it is not the only approach, and since it would require a
separate notion of thread id to be added to the kernel, it might not
be the simplest approach (as far as the kernel is concerned).

> Please don't say this can be done reliably in userspace; it takes a severe
> performance hit for signal handling and adds several levels of complexity
> to any pthreads library that uses clone.

I agree that signal delivery should happen completely within the
kernel for the reasons you give.

But consider implementing the POSIX signal semantics on top of
CLONE_PID. The obvious way is:

for_all_tasks_with_pid(p, pid)
if (!sigismember(&p->blocked, sig)) {
deliver signal;
return;
}

put signal on some per-process pending set;

This is simple, but takes O(Nthreads), because we have to go through
all threads with the particular pid. But there is another approach,
which is hardly any more complicated, and takes O(log Nthreads) for
signal delivery; this approach doesn't care about the pids at all, and
so can be implemented as easily with or without CLONE_PID. I'm not
going to describe the details here, but my point is that "literal"
implementations of POSIX are not automatically best in any sense; you
have to consider the alternatives carefully first.

> The way I understand it (and it
> has been a while since I read anything on the subject) is that certain
> fatal signals are supposed to be received by all threads/affect all
> threads no matter which thread receives it. I believe this includes at
> least one signal that cannot be handled. So how do you propogate this
> signal reliably to all other threads in the process?

There is a important distinction between "received by all threads" and
"affect all threads". There is nothing in POSIX.1 (that I can find,
at least) to state that any signal should be sent to all threads
within a process. Section 3.3.12 says

Signals generated for the process shall be delivered to or accepted
by exactly one of those threads within the process.

and that appears to apply to all signals equally. Section 3.3.12 goes
on to say

When a signal is delivered to a thread, if the action of that
signal specifies termination, stop, or continue, the entire process
shall be terminated, stopped, or continued, respectively.

So there is no need to propogate the signal, we just have to make sure
that all the threads get terminated (though there are subtleties
involved even in that).

On the other hand I suspect that handling stop and continue signals
robustly will need help from the kernel.

David Wragg

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/