Add PrimOp fetchAddIntArray# plus supporting C function atomic_inc_by.
[ghc.git] / includes / stg / SMP.h
index bfd6bbc..bdcaf55 100644 (file)
@@ -61,6 +61,16 @@ EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n);
 EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p);
 
 /*
+ * Atomic addition by the provided quantity
+ *
+ * atomic_inc_by(p, n) {
+ *   return ((*p) += n);
+ * }
+ */
+EXTERN_INLINE StgWord atomic_inc_by(StgVolatilePtr p, StgWord n);
+
+
+/*
  * Atomic decrement
  *
  * atomic_dec(p) {
@@ -236,28 +246,35 @@ cas(StgVolatilePtr p, StgWord o, StgWord n)
 #endif
 }
 
+// RRN: Added to enable general fetch-and-add in Haskell code (fetchAddIntArray#).
 EXTERN_INLINE StgWord
-atomic_inc(StgVolatilePtr p)
+atomic_inc_by(StgVolatilePtr p, StgWord incr)
 {
 #if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH)
     StgWord r;
-    r = 1;
+    r = incr;
     __asm__ __volatile__ (
         "lock\nxadd %0,%1":
             "+r" (r), "+m" (*p):
     );
-    return r+1;
+    return r + incr;
 #else
     StgWord old, new;
     do {
         old = *p;
-        new = old + 1;
+        new = old + incr;
     } while (cas(p, old, new) != old);
     return new;
 #endif
 }
 
 EXTERN_INLINE StgWord
+atomic_inc(StgVolatilePtr p)
+{
+  return atomic_inc_by(p, 1);
+}
+
+EXTERN_INLINE StgWord
 atomic_dec(StgVolatilePtr p)
 {
 #if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH)
@@ -397,6 +414,13 @@ atomic_inc(StgVolatilePtr p)
 }
 
 INLINE_HEADER StgWord
+atomic_inc_by(StgVolatilePtr p, StgWord incr)
+{
+    return ((*p) += incr);
+}
+
+
+INLINE_HEADER StgWord
 atomic_dec(StgVolatilePtr p)
 {
     return --(*p);