diff options
author | Ryan Newton <rrnewton@gmail.com> | 2012-03-29 00:32:03 -0400 |
---|---|---|
committer | Ryan Newton <rrnewton@gmail.com> | 2013-08-21 00:02:29 -0400 |
commit | 3ca7ecb57eefc43b4347e22ad2fd7a4962d84020 (patch) | |
tree | 7c1251734372615ba791bf355eca6aa4beecdebc /rts/PrimOps.cmm | |
parent | 82bbc3864ff608879cffbe0d2a4a2f8cb4ef4604 (diff) | |
download | haskell-3ca7ecb57eefc43b4347e22ad2fd7a4962d84020.tar.gz |
add casArray# primop, similar to casMutVar# but for array elements
Diffstat (limited to 'rts/PrimOps.cmm')
-rw-r--r-- | rts/PrimOps.cmm | 27 |
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; |