summaryrefslogtreecommitdiff
path: root/includes/stg/SMP.h
diff options
context:
space:
mode:
authorPatrick Palka <patrick@parcs.ath.cx>2013-09-04 12:10:27 -0400
committerPatrick Palka <patrick@parcs.ath.cx>2013-09-04 12:10:27 -0400
commitd127a697192851ea6bf308525a8a8895da71b639 (patch)
tree895f8976273df8e96b7c52382529ca0dfee61a5a /includes/stg/SMP.h
parenta2e338f3ae5a101d333fb260ed58ec238106e88e (diff)
parent32ade417f7e82b6fbcb6f1c93871ba3141a8f5c8 (diff)
downloadhaskell-d127a697192851ea6bf308525a8a8895da71b639.tar.gz
Merge remote-tracking branch 'origin/master' into ghc-parmake-gsoc
Diffstat (limited to 'includes/stg/SMP.h')
-rw-r--r--includes/stg/SMP.h27
1 files changed, 16 insertions, 11 deletions
diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h
index 99c25fe355..07ea522328 100644
--- a/includes/stg/SMP.h
+++ b/includes/stg/SMP.h
@@ -52,13 +52,14 @@ EXTERN_INLINE StgWord xchg(StgPtr p, StgWord w);
EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n);
/*
- * Atomic increment
+ * Atomic addition by the provided quantity
*
- * atomic_inc(p) {
- * return ++(*p);
+ * atomic_inc(p, n) {
+ * return ((*p) += n);
* }
*/
-EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p);
+EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p, StgWord n);
+
/*
* Atomic decrement
@@ -236,22 +237,24 @@ cas(StgVolatilePtr p, StgWord o, StgWord n)
#endif
}
+// RRN: Generalized to arbitrary increments to enable fetch-and-add in
+// Haskell code (fetchAddIntArray#).
EXTERN_INLINE StgWord
-atomic_inc(StgVolatilePtr p)
+atomic_inc(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
@@ -393,12 +396,14 @@ cas(StgVolatilePtr p, StgWord o, StgWord n)
return result;
}
-INLINE_HEADER StgWord
-atomic_inc(StgVolatilePtr p)
+EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p, StgWord incr);
+EXTERN_INLINE StgWord
+atomic_inc(StgVolatilePtr p, StgWord incr)
{
- return ++(*p);
+ return ((*p) += incr);
}
+
INLINE_HEADER StgWord
atomic_dec(StgVolatilePtr p)
{