[commit: ghc] atomics: Add PrimOp fetchAddIntArray# plus supporting C function atomic_inc_by. (8750d54)
git at git.haskell.org
git at git.haskell.org
Wed Aug 21 14:04:56 CEST 2013
Repository : ssh://git@git.haskell.org/ghc
On branch : atomics
Link : http://ghc.haskell.org/trac/ghc/changeset/8750d549d4d7aca3e397de3e217b7cca9e1c1d43/ghc
>---------------------------------------------------------------
commit 8750d549d4d7aca3e397de3e217b7cca9e1c1d43
Author: Ryan Newton <rrnewton at gmail.com>
Date: Sat Aug 3 20:19:46 2013 -0400
Add PrimOp fetchAddIntArray# plus supporting C function atomic_inc_by.
>---------------------------------------------------------------
8750d549d4d7aca3e397de3e217b7cca9e1c1d43
compiler/prelude/primops.txt.pp | 7 +++++++
includes/stg/MiscClosures.h | 1 +
includes/stg/SMP.h | 32 ++++++++++++++++++++++++++++----
rts/Linker.c | 1 +
rts/PrimOps.cmm | 14 +++++++++++++-
5 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
index 6ee39c5..094c2f5 100644
--- a/compiler/prelude/primops.txt.pp
+++ b/compiler/prelude/primops.txt.pp
@@ -1125,6 +1125,13 @@ primop CasByteArrayOp_Int "casIntArray#" GenPrimOp
out_of_line = True
has_side_effects = True
+primop FetchAddByteArrayOp_Int "fetchAddIntArray#" GenPrimOp
+ MutableByteArray# s -> Int# -> Int# -> State# s -> (# State# s, Int# #)
+ {Machine-level word-sized fetch-and-add within a ByteArray.}
+ with
+ out_of_line = True
+ has_side_effects = True
+
------------------------------------------------------------------------
section "Arrays of arrays"
diff --git a/includes/stg/MiscClosures.h b/includes/stg/MiscClosures.h
index ee973e4..876f39a 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 bfd6bbc..bdcaf55 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);
diff --git a/rts/Linker.c b/rts/Linker.c
index 0a0996a..92194df 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1148,6 +1148,7 @@ typedef struct _RtsSymbolVal {
SymI_HasProto(stg_newBCOzh) \
SymI_HasProto(stg_newByteArrayzh) \
SymI_HasProto(stg_casIntArrayzh) \
+ SymI_HasProto(stg_fetchAddIntArrayzh) \
SymI_HasProto_redirect(newCAF, newDynCAF) \
SymI_HasProto(stg_newMVarzh) \
SymI_HasProto(stg_newMutVarzh) \
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index cc22d22..b7177ca 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -142,7 +142,6 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment )
stg_casIntArrayzh( gcptr arr, W_ ind, W_ old, W_ new )
/* MutableByteArray# s -> Int# -> Int# -> Int# -> State# s -> (# State# s, Int# #) */
{
- W_ len;
gcptr p,h;
p = arr + SIZEOF_StgArrWords + WDS(ind);
@@ -151,6 +150,19 @@ stg_casIntArrayzh( gcptr arr, W_ ind, W_ old, W_ new )
return(h);
}
+
+stg_fetchAddIntArrayzh( gcptr arr, W_ ind, W_ incr )
+/* MutableByteArray# s -> Int# -> Int# -> State# s -> (# State# s, Int# #) */
+{
+ gcptr p, h;
+
+ p = arr + SIZEOF_StgArrWords + WDS(ind);
+ (h) = ccall atomic_inc_by(p, incr);
+
+ return(h);
+}
+
+
stg_newArrayzh ( W_ n /* words */, gcptr init )
{
W_ words, size;
More information about the ghc-commits
mailing list