cleaning up pthreads implementation - ABI problem

Peter Hunnisett hunnise at yahoo.com
Wed Nov 21 08:28:09 CST 2001


Howdy, 
  I was just looking at cleaning up the pthreads
implementation but I don't think that it's possible to
have our pthreads implementation without providing
binary compatibility with the pthread implementation
we're hijacking. The reason is that the mutex and
rwlock objects are supposed to be opaque to the
programmer but in fact they are not opaque to the
compiler.

  According to the standard, one doesn't have to call
pthread_{mutex,rwlock}_init before using a
{mutex,rwlock} as would be required with a totally
opaque type. The standard allows for static
initialization of the mutex and rwlock using
PTHREAD_{MUTEX,RWLOCK}_INITIALIZER if you don't want
any special attributes.

  libc does just this with its rwlock for gettext's
global data. If you look at the ream of
FIXME:pthread_rwlock_{rd,un}lock that sometimes come
out starting wine you'll see that there's no call to
pthread_rwlock_init. Of course, this stuff is safe
because there's generally no writers wanting the
pthread_rwlock_wrlock.

  So our current pthreads mutex implementation works
in Linux by the skin of its teeth, becuase the first
field in the mutex is reserved and initialized to 0
(in both the static and pthread_mutex_init cases),
provided the version of LinuxThreads is new enough and
a pointer is the same size as an int. Now I assume
that this would mean it fails curiously for things
that don't use LinuxThreads. This would also seem to
mean, since we need binary compatibility, that things
could even fail if someone upgrades their libc :(

  BTW, our check is presently basically only on
__GLIBC__. Flavour me ignorant, and lazy, but I would
assume that this not a Linux only symbol. So in fact
the wine pthreads implementation might be already used
incorrectly.

  Reader/Writer locks can be made to work the same
way, as the mutex, since there are several fields
which are initialized to NULL and we can then
HeapAlloc our own structure off that field. We can
then come up with weird and wonderful exceptions for
the wonky cases that are sure to exist in some
implementation of pthreads.

  Can anyone see a nice way out of this that I'm
remaining ignorant to? I can't even think of a runtime
way of detecting if our implementation is going to
work. All in all I'm not too enthusiatic about the
potential maintenance nightmare that this may provide
but it would seem the only way is to have different
mutex and rwlock structures depending on the pthreads
implementation we're hijacking.


Some code if people are more interested in details:



More information about the wine-devel mailing list