John Wehle <[EMAIL PROTECTED]> wrote:

> Wine uses _lwp_create on Solaris which has the following note:
> 
>      Applications  should  use  bound  threads  rather  than  the
>      _lwp_*()   functions   (see   thr_create(3T)).  Using   LWPs
>      directly is not advised because libraries are only  safe  to
>      use with threads, not LWPs.
> 
> Changing to thr_create allows wine to proceed further on Solaris x86
> (it now fails for other reasons).  I didn't remove the LWP stuff used
> on Solaris SPARC since that platform doesn't interest me, though probably
> all the LWP stuff should be converted to threads or pthreads.
> 
> Notes:
> 
>   1) Wine has a thread.h which conflicts with Solaris's thread.h.
>      I worked around this by using a absolute name in the sysdeps.c
>      include.  Unfortunately this makes makedepend unhappy.
> 
>   2) Solaris (in addition to many other platforms) supports pthreads.
>      This is probably a more portable answer which should replace the
>      ifdef linux / HAVE_RFORK / HAVE_THR_CREATE / HAVE__LWP_CREATE stuff.

Well, it was done that way for a purpose ;-)

The problem is that the higher-level thread libraries (typically pthreads)
tend to make certain assumptions about things application programs typically
do or don't do, and these are sometimes violated by Wine.

For example, the Linux pthreads implementation assumes that all thread 
stacks must have the same size, and must reside at positions determined
by the library.  Wine doesn't like this, as it has to satify Windows
applications' requests for variably sized thread stacks.  (OK, recent
versions of glibc also allow variably sized stacks, but only at a huge
performance penalty.)

The Solaris x86 pthreads implementation, last time I looked into it,
assumes that it is free to create selectors in the LDT without being
disturbed by the application.  This obviously breaks with Wine, as
Wine also thinks it can freely use the LDT without interference.
(Note that due to a kernel bug in Solaris, this problem can quite
reliably trigger kernel panics in certain circumstances :-/)

Due to this sort of problems, we decided to do it the other way around
and fall back to the most low-level interface to create threads on the
platforms we support, which are direct system calls without library
involvement.  This way, we are at least sure that the threading
library does not interfere with what Wine does.

Of course, this approach leads to a different problem: the system
libraries (libc etc.) typically rely on the system threading library
to provide for mutual exclusion primitives or other mechanisms to
make the library thread-safe.  On Linux, we've solved this problem
by providing *ourselves* (a subset of) the pthreads interface,
implemented *on top* of the Wine threading primitives, which gets
used by the system libraries instead of the system libpthread to
provide mutual exclusion.

>From the backtrace you posted it appears, unfortunately, that the
Solaris libc does not fall back to libpthread, but libthread.  As
we don't fake the libthread interface, the real libthread gets
used and breaks, of course.

I'm not quite sure how to solve this problem.  Just using pthreads
(or libthread, as you propose) opens up the problem of conflicting
LDT allocations again.  (Note that I'm not definite that libthread
also uses the LDT.  But as threads created by pthread_create and
thr_create can be used interchangeably, I'd be astonished if not.)

We might try the same hack as on Intel and implement a subset
of the libthread interface to satify the Solaris libc.  I'm not
sure whether this would be feasible either ...

B.t.w. this topic comes up regularly, but has never been satisfactorily
solved :-/   If you have any new ideas, they would most certainly
be welcome ...

Bye,
Ulrich


-- 
  Dr. Ulrich Weigand
  [EMAIL PROTECTED]

Reply via email to