[OpenAFS-devel] pthreads, darwin, microsoft: untwisting the knot
Kyle Moffett
mrmacman_g4@mac.com
Thu, 26 May 2005 23:31:51 -0400
On May 26, 2005, at 23:04:05, Marcus Watts wrote:
> The fix: modify pthread_mutex_t to have a new field, "IsInitialized".
> [ It might be wise to include padding to some round boundary as
> well to
> make library versioning a bit simplier. ] Declare
> PTHREAD_MUTEX_INITIALIZER
> to put a 0 into this field. Modify
> pthread_mutex_init
> pthread_mutex_trylock
> pthread_mutex_lock
> pthread_mutex_unlock
> pthread_mutex_destroy
> to check this. Generally speaking, if it's not set, acquire a private
> mutex, and if it's still not set, call InitializeCriticalSection for
> the mutex.
Hmm, depending on the CPU's instruction reordering and data
dependency handling,
this could actually be kinda racy. Some compilers might (legitimately)
optimize the code to something like this (Except in real assembly :-D):
/* Check if it's initialized */
load r8, IsInitialized
test r8
bnz AlreadyInitialized
/* Lock a global mutex */
load r0, GlobalLockPtr
call mutex_lock
/* Recheck, except in a racy fashion */
test r8
bnz AlreadyInitializedUnlock
/* Initialize */
load r0, NewLockPtr
call mutex_init
/* Mark as initialized */
store #1, [r0]4
/* Unlock */
AlreadyInitializedUnlock:
load r0, GlobalLockPtr
call mutex_unlock
/* Lock the real mutex */
AlreadyInitialized:
load r0, NewLockPtr
call mutex_lock
Basically, I think the general rule of thumb is that you should not
check any
variable (non-atomic OR atomic), in a non-atomic way (IE: outside the
lock
that protects it). The mutex operations provide data ordering
guarantees,
such that read and write operations will not be moved across the
barrier, but
they do not necessarily provide cache-flush guarantees for all data,
because
that would be a severe performance penalty (They naturally provide
them for
the lock itself, but that's a different concept entirely).
Cheers,
Kyle Moffett
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCM/CS/IT/U d- s++: a18 C++++>$ UB/L/X/*++++(+)>$ P+++(++++)>$
L++++(+++) E W++(+) N+++(++) o? K? w--- O? M++ V? PS+() PE+(-) Y+
PGP+++ t+(+++) 5 X R? tv-(--) b++++(++) DI+ D+ G e->++++$ h!*()>++$
r !y?(-)
------END GEEK CODE BLOCK------