summaryrefslogtreecommitdiff
path: root/rts/PrimOps.cmm
diff options
context:
space:
mode:
authorRyan Newton <rrnewton@gmail.com>2012-03-29 00:32:03 -0400
committerRyan Newton <rrnewton@gmail.com>2013-08-21 00:02:29 -0400
commit3ca7ecb57eefc43b4347e22ad2fd7a4962d84020 (patch)
tree7c1251734372615ba791bf355eca6aa4beecdebc /rts/PrimOps.cmm
parent82bbc3864ff608879cffbe0d2a4a2f8cb4ef4604 (diff)
downloadhaskell-3ca7ecb57eefc43b4347e22ad2fd7a4962d84020.tar.gz
add casArray# primop, similar to casMutVar# but for array elements
Diffstat (limited to 'rts/PrimOps.cmm')
-rw-r--r--rts/PrimOps.cmm27
1 files changed, 27 insertions, 0 deletions
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index ced15eec99..3bf5f37a00 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;