Fix the definition of cas() on x86 (#8219)
authorPatrick Palka <patrick@parcs.ath.cx>
Sat, 21 Sep 2013 17:27:13 +0000 (13:27 -0400)
committerPatrick Palka <patrick@parcs.ath.cx>
Mon, 23 Sep 2013 13:05:16 +0000 (09:05 -0400)
*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.

includes/stg/SMP.h

index 07ea522..471e8f9 100644 (file)
@@ -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