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-all mailing list