[commit: ghc] atomics: add casArray# primop, similar to casMutVar# but for array elements (3ca7ecb)
git at git.haskell.org
git at git.haskell.org
Wed Aug 21 14:04:51 CEST 2013
Repository : ssh://git@git.haskell.org/ghc
On branch : atomics
Link : http://ghc.haskell.org/trac/ghc/changeset/3ca7ecb57eefc43b4347e22ad2fd7a4962d84020/ghc
>---------------------------------------------------------------
commit 3ca7ecb57eefc43b4347e22ad2fd7a4962d84020
Author: Ryan Newton <rrnewton at gmail.com>
Date: Thu Mar 29 00:32:03 2012 -0400
add casArray# primop, similar to casMutVar# but for array elements
>---------------------------------------------------------------
3ca7ecb57eefc43b4347e22ad2fd7a4962d84020
compiler/prelude/primops.txt.pp | 8 ++++++++
includes/stg/MiscClosures.h | 1 +
rts/Linker.c | 1 +
rts/PrimOps.cmm | 27 +++++++++++++++++++++++++++
4 files changed, 37 insertions(+)
diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
index e275b23..6e25d65 100644
--- a/compiler/prelude/primops.txt.pp
+++ b/compiler/prelude/primops.txt.pp
@@ -794,6 +794,14 @@ primop ThawArrayOp "thawArray#" GenPrimOp
has_side_effects = True
code_size = { primOpCodeSizeForeignCall + 4 }
+primop CasArrayOp "casArray#" GenPrimOp
+ MutableArray# s a -> Int# -> a -> a -> State# s -> (# State# s, Int#, a #)
+ {Unsafe, machine-level atomic compare and swap on an element within an Array.}
+ with
+ out_of_line = True
+ has_side_effects = True
+
+
------------------------------------------------------------------------
section "Byte Arrays"
{Operations on {\tt ByteArray\#}. A {\tt ByteArray\#} is a just a region of
diff --git a/includes/stg/MiscClosures.h b/includes/stg/MiscClosures.h
index b0ed03b..de5d322 100644
--- a/includes/stg/MiscClosures.h
+++ b/includes/stg/MiscClosures.h
@@ -364,6 +364,7 @@ RTS_FUN_DECL(stg_word64ToIntegerzh);
#endif
RTS_FUN_DECL(stg_unsafeThawArrayzh);
+RTS_FUN_DECL(stg_casArrayzh);
RTS_FUN_DECL(stg_newByteArrayzh);
RTS_FUN_DECL(stg_newPinnedByteArrayzh);
RTS_FUN_DECL(stg_newAlignedPinnedByteArrayzh);
diff --git a/rts/Linker.c b/rts/Linker.c
index 0c7dfd2..1cb9b1f 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1144,6 +1144,7 @@ typedef struct _RtsSymbolVal {
SymI_HasProto(stg_labelThreadzh) \
SymI_HasProto(stg_newArrayzh) \
SymI_HasProto(stg_newArrayArrayzh) \
+ SymI_HasProto(stg_casArrayzh) \
SymI_HasProto(stg_newBCOzh) \
SymI_HasProto(stg_newByteArrayzh) \
SymI_HasProto_redirect(newCAF, newDynCAF) \
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index ced15ee..3bf5f37 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -206,6 +206,33 @@ stg_unsafeThawArrayzh ( gcptr arr )
}
}
+stg_casArrayzh
+/* MutableArray# s a -> Int# -> a -> a -> State# s -> (# State# s, Int#, a #) */
+{
+ W_ arr, p, ind, old, new, h, len;
+ arr = R1; // anything else?
+ ind = R2;
+ old = R3;
+ new = R4;
+
+ p = arr + SIZEOF_StgMutArrPtrs + WDS(ind);
+ (h) = foreign "C" cas(p, old, new) [];
+
+ if (h != old) {
+ // Failure, return what was there instead of 'old':
+ RET_NP(1,h);
+ } else {
+ // Compare and Swap Succeeded:
+ if (GET_INFO(arr) == stg_MUT_ARR_PTRS_CLEAN_info) {
+ SET_HDR(arr, stg_MUT_ARR_PTRS_DIRTY_info, CCCS);
+ len = StgMutArrPtrs_ptrs(arr);
+ // The write barrier. We must write a byte into the mark table:
+ I8[arr + SIZEOF_StgMutArrPtrs + WDS(len) + (ind >> MUT_ARR_PTRS_CARD_BITS )] = 1;
+ }
+ RET_NP(0,h);
+ }
+}
+
stg_newArrayArrayzh ( W_ n /* words */ )
{
W_ words, size;
More information about the ghc-commits
mailing list