cleaning up pthreads implementation - ABI problem

Ove Kaaven ovehk at ping.uio.no
Wed Nov 21 09:02:59 CST 2001


On Wed, 21 Nov 2001, Peter Hunnisett wrote:

>   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.

I know that...

> Now I assume that this would mean it fails curiously for things that
> don't use LinuxThreads.

Which of those things may be of concern?

> This would also seem to mean, since we need binary compatibility, that
> things could even fail if someone upgrades their libc :(

Doubtful, libc is typically backwards compatible.

>   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.

Well, use whatever definition suits you, if you have any other systems
with GNU libc that can run Wine.

>   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.

I don't expect Wine to run on *that* many flavors... "hijacking" pthreads
is probably only *really* necessary on x86, on other architectures Wine
may as well use the native pthreads, so that already limits us to the unix
variants that run on x86...

> rwlocks on the other hand are not so lucky as there's
> no unused bits:
> 
> >From glibc-2.2.4
> /* Read-write locks.  */
> typedef struct _pthread_rwlock_t
> {
>   struct _pthread_fastlock __rw_lock; /* Lock to
> guarantee mutual exclusion */
>   int __rw_readers;                   /* Number of
> readers */
>   _pthread_descr __rw_writer;         /* Identity of
> writer, or NULL if none */
>   _pthread_descr __rw_read_waiting;   /* Threads
> waiting for reading */
>   _pthread_descr __rw_write_waiting;  /* Threads
> waiting for writing */
>   int __rw_kind;                      /* Reader/Writer
> preference selection */
>   int __rw_pshared;                   /* Shared
> between processes or not */
> } pthread_rwlock_t;
> 
> # define PTHREAD_RWLOCK_INITIALIZER \
>   { __LOCK_INITIALIZER, 0, NULL, NULL, NULL,          
>     \
>     PTHREAD_RWLOCK_DEFAULT_NP, PTHREAD_PROCESS_PRIVATE
> }

Have you checked what __LOCK_INITIALIZER is?

#define __LT_SPINLOCK_INIT 0
#define __LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT }

So you can indeed use a copy of wine_mutex on top of a linuxthreads rwlock
too, since that overloaded pointer will still be initialized to 0 even if
the app used linuxthreads's PTHREAD_RWLOCK_INITIALIZER.





More information about the wine-devel mailing list