Perhaps a question mark is more appropriate in the title.  It is a code review I am seeking, not one on offer ;-).<br><br><div class="gmail_quote">On Thu, Mar 29, 2012 at 12:56 AM, Ryan Newton <span dir="ltr">&lt;<a href="mailto:rrnewton@gmail.com">rrnewton@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi all,<br><br>In preparation for students working on concurrent data structures GSOC(s), I wanted to make sure they could count on CAS for array elements as well as IORefs.  The following patch represents my first attempt:<br>


<br>     <a href="https://github.com/rrnewton/ghc/commit/18ed460be111b47a759486677960093d71eef386" target="_blank">https://github.com/rrnewton/ghc/commit/18ed460be111b47a759486677960093d71eef386</a><br><br>It passes a simple test [Appendix 2 below], but I am very unsure as to whether the GC write barrier is correct.  Could someone do a code-review on the following few lines of CMM:<br>


 <br><font face="&#39;courier new&#39;, monospace">       if (GET_INFO(arr) == stg_MUT_ARR_PTRS_CLEAN_info) {<br>           SET_HDR(arr, stg_MUT_ARR_PTRS_DIRTY_info, CCCS);<br>           len = StgMutArrPtrs_ptrs(arr);<br>


           // The write barrier.  We must write a byte into the mark table:<br>           I8[arr + SIZEOF_StgMutArrPtrs + WDS(len) + (ind &gt;&gt; MUT_ARR_PTRS_CARD_BITS )] = 1;<br>        }<br></font><br>Thanks,<br>   -Ryan<br>


<br>-- Appendix 1: First draft code CMM definition for casArray#<br>-------------------------------------------------------------------<br>stg_casArrayzh<br>/* MutableArray# s a -&gt; Int# -&gt; a -&gt; a -&gt; State# s -&gt; (# State# s, Int#, a #) */<br>


{<br>    W_ arr, p, ind, old, new, h, len;<br>    arr = R1; // anything else?<br>    ind = R2;<br>    old = R3;<br>    new = R4;<br><br>    p = arr + SIZEOF_StgMutArrPtrs + WDS(ind);<br>    (h) = foreign &quot;C&quot; cas(p, old, new) [];<br>


    <br>    if (h != old) {<br>        // Failure, return what was there instead of &#39;old&#39;:<br>        RET_NP(1,h);<br>    } else {<br>        // Compare and Swap Succeeded:<br>        if (GET_INFO(arr) == stg_MUT_ARR_PTRS_CLEAN_info) {<br>


           SET_HDR(arr, stg_MUT_ARR_PTRS_DIRTY_info, CCCS);<br>           len = StgMutArrPtrs_ptrs(arr);<br>           // The write barrier.  We must write a byte into the mark table:<br>           I8[arr + SIZEOF_StgMutArrPtrs + WDS(len) + (ind &gt;&gt; MUT_ARR_PTRS_CARD_BITS )] = 1;<br>


        }<br>        RET_NP(0,h);<br>    }<br>}<br><br>-- Appendix 2:  Simple test file; when run it should print:<br>-------------------------------------------------------------------<br>-- Perform a CAS within a MutableArray#<br>


--   1st try should succeed: (True,33)<br>-- 2nd should fail: (False,44)<br>-- Printing array:<br>--   33  33  33  44  33<br>-- Done.<br>-------------------------------------------------------------------<br>{-# Language MagicHash, UnboxedTuples  #-}<br>


<br>import <a href="http://GHC.IO" target="_blank">GHC.IO</a><br>import GHC.IORef<br>import <a href="http://GHC.ST" target="_blank">GHC.ST</a><br>import GHC.STRef<br>import GHC.Prim<br>import GHC.Base<br>import Data.Primitive.Array<br>

import Control.Monad<br>
<br>------------------------------------------------------------------------<br><br>-- -- | Write a value to the array at the given index:<br>casArrayST :: MutableArray s a -&gt; Int -&gt; a -&gt; a -&gt; ST s (Bool, a)<br>


casArrayST (MutableArray arr#) (I# i#) old new = ST$ \s1# -&gt;<br>  case casArray# arr# i# old new s1# of <br>    (# s2#, x#, res #) -&gt; (# s2#, (x# ==# 0#, res) #)<br><br>------------------------------------------------------------------------<br>


{-# NOINLINE mynum #-}<br>mynum :: Int<br>mynum = 33<br><br>main = do <br>  putStrLn &quot;Perform a CAS within a MutableArray#&quot;<br>  arr &lt;- newArray 5 mynum<br><br>  res  &lt;- stToIO$ casArrayST arr 3 mynum 44<br>


  res2 &lt;- stToIO$ casArrayST arr 3 mynum 44<br>  putStrLn$ &quot;  1st try should succeed: &quot;++show res<br>  putStrLn$ &quot;2nd should fail: &quot;++show res2<br><br>  putStrLn &quot;Printing array:&quot;<br>  forM_ [0..4] $ \ i -&gt; do<br>


    x &lt;- readArray arr i <br>    putStr (&quot;  &quot;++show x)<br>  putStrLn &quot;&quot;<br>  putStrLn &quot;Done.&quot;<br><br>
</blockquote></div><br>