diff options
author | Patrick Palka <patrick@parcs.ath.cx> | 2013-09-21 13:27:13 -0400 |
---|---|---|
committer | Patrick Palka <patrick@parcs.ath.cx> | 2013-09-23 09:05:16 -0400 |
commit | 84dff71075b915938e2457f5bff2d127eac3b3cc (patch) | |
tree | 58dcfc031ee73dd07162aa0a6d61e8f9358ed50d /includes/stg | |
parent | 93a04b49326a03dd3154e619a3c5564d50768727 (diff) | |
download | haskell-84dff71075b915938e2457f5bff2d127eac3b3cc.tar.gz |
Fix the definition of cas() on x86 (#8219)
*p is both read and written to by the cmpxchg instruction, and therefore
should be given the '+' constraint modifier.
(In GCC's extended ASM language, '+' means that the operand is both read
and written to whereas '=' means that it is only written to.)
Otherwise, the compiler is allowed to rewrite something like
SpinLock lock;
initSpinLock(&lock); /* sets lock = 1 */
ACQUIRE_SPIN_LOCK(&lock);
into
SpinLock lock;
ACQUIRE_SPIN_LOCK(&lock);
because according to the asm statement, the previous value of 'lock' is
not important.
Diffstat (limited to 'includes/stg')
-rw-r--r-- | includes/stg/SMP.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h index 07ea522328..471e8f9f51 100644 --- a/includes/stg/SMP.h +++ b/includes/stg/SMP.h @@ -173,7 +173,7 @@ cas(StgVolatilePtr p, StgWord o, StgWord n) #if i386_HOST_ARCH || x86_64_HOST_ARCH __asm__ __volatile__ ( "lock\ncmpxchg %3,%1" - :"=a"(o), "=m" (*(volatile unsigned int *)p) + :"=a"(o), "+m" (*(volatile unsigned int *)p) :"0" (o), "r" (n)); return o; #elif powerpc_HOST_ARCH |