Messages in this thread | | | Subject | Re: clone() and CLONE_PID | From | David Wragg <> | Date | 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/
| |