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