summaryrefslogtreecommitdiff
path: root/includes/stg
diff options
context:
space:
mode:
authorPatrick Palka <patrick@parcs.ath.cx>2013-09-21 13:27:13 -0400
committerPatrick Palka <patrick@parcs.ath.cx>2013-09-23 09:05:16 -0400
commit84dff71075b915938e2457f5bff2d127eac3b3cc (patch)
tree58dcfc031ee73dd07162aa0a6d61e8f9358ed50d /includes/stg
parent93a04b49326a03dd3154e619a3c5564d50768727 (diff)
downloadhaskell-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.h2
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