cvs commit: src/sys/kern kern_thr.c syscalls.master src/sys/sys
Robert Watson
rwatson at FreeBSD.org
Sun Aug 19 09:24:32 PDT 2007
On Sun, 19 Aug 2007, Kris Moore wrote:
> That being said, most of the technical details are a bit over my head, but I
> will add my $0.02 to this. Whatever the solution, there needs to be a
> working solution in the end. If there's a better, more portable way to do
> this, then by all means lets get it done. If nobody can or will write this
> solution, then lets not just drop the original patch. A fix is greatly
> needed either way, so I hope this is added in the very near future.
Let me provide a bit more background for those who are just joining the
conversation, as it has been going on since around March. (You can find
fragments on the freebsd-threads list, etc).
The underlying requirement here is for Wine to be able to suspend threads of
the emulation process -- this is not a requirement I have any specific insight
into, so can't justify it, but it seems a fairly reasonable thing to want to
do.
In Linux, suspending threads in a remote process is easy, because threads are
processes, so signals can be delivered directly to specific threads in a
target process using kill(2). This same functionality is available in Mac OS
X via thread/task ports, and possibly in Solaris via procfs (I agree with
Dan's reading that the _lwp_kill(2) system call in Solaris doesn't look like
it can target remote process threads, but the debugging interfaces certainly
can, and Wine is full of debugging interface use).
As a more portable solution, sigqueue(2) can be used -- this is a POSIX
realtime signaling interface that, among other things, allows a data value to
be passed to the receiveing process. This would allow a proxy thread in the
emulated process to "receive" the signal and then forward the signal to a
specific thread within the same process. However, sigqueue(2) is available
only in FreeBSD 7.x, and has been determined to be sufficiently complex to not
be MFC'able.
This leaves FreeBSD 6.x, which neither implement the richer signalling
service, nor direct signal delivery to target threads. An obvious quick
solution here is to add a system call to provide equivilent functionality to
that in Linux, Mac OS X, Solaris, etc -- allow direct delivery of a signal to
a specific target thread in a remote process. thr_kill2() does this in the
expectedly straight forward way, but specific to libthr, as only libthr offers
a 1:1 threading model in which the kernel is sufficiently aware of threads as
to offer a useful way to signal them.
You can imagine other schemes for forwarding signals to threads in a remote
process that are only marginally more complicated than using sigqueue, such as
having a proxy listening on an IPC pipe or the like. I can't really comment
on the impact to Wine code of doing this.
BTW, Wine already has to know a lot about the internals of operating systems
and processes in order to do what it does -- how to lay out address spaces,
using the ptrace interfaces to control and manage threads, etc. So I'm not
sure I buy that we should expect Wine to conform to portable interfaces, or
that portable interfaces should be able to express what Wine needs: it is
doing something pretty inherrently non-portable. However, it could be that we
could avoid introducing more non-portable interfaces through more Wine
rewriting.
Robert N M Watson
Computer Laboratory
University of Cambridge
More information about the cvs-src
mailing list