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.