summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
Diffstat (limited to 'includes')
-rw-r--r--includes/stg/MiscClosures.h1
-rw-r--r--includes/stg/SMP.h32
2 files changed, 29 insertions, 4 deletions
diff --git a/includes/stg/MiscClosures.h b/includes/stg/MiscClosures.h
index ee973e46a9..876f39a02c 100644
--- a/includes/stg/MiscClosures.h
+++ b/includes/stg/MiscClosures.h
@@ -369,6 +369,7 @@ RTS_FUN_DECL(stg_newByteArrayzh);
RTS_FUN_DECL(stg_newPinnedByteArrayzh);
RTS_FUN_DECL(stg_newAlignedPinnedByteArrayzh);
RTS_FUN_DECL(stg_casIntArrayzh);
+RTS_FUN_DECL(stg_fetchAddIntArrayzh);
RTS_FUN_DECL(stg_newArrayzh);
RTS_FUN_DECL(stg_newArrayArrayzh);
diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h
index bfd6bbcfab..bdcaf55d3e 100644
--- a/includes/stg/SMP.h
+++ b/includes/stg/SMP.h
@@ -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);