packages feed

rcu-0: examples/ListInt.hs

import Control.Concurrent.MVar (takeMVar)
import Control.Concurrent.RCU
import Control.Monad (forM, forM_, replicateM)
import Data.List (group, intercalate)
import Prelude hiding (read)

data List s a = Nil | Cons a (SRef s (List s a))

snapshot :: Int -> List s Int -> ReadingRCU s Int
snapshot acc Nil         = return acc
snapshot acc (Cons x rn) = snapshot (x + acc) =<< readSRef rn

reader :: Int -> Int -> SRef s (List s Int) -> ReadingRCU s Int
reader 0 acc _    = return acc
reader n acc head = do
  acc' <- snapshot acc =<< readSRef head
  reader (n - 1) acc' head

deleteMiddle :: SRef s (List s a) -> WritingRCU s ()
deleteMiddle rl = do
  Cons a rn <- readSRef rl
  Cons _ rm <- readSRef rn
  writeSRef rl $ Cons a rm 

testList :: RCU s (SRef s (List s Int))
testList = do
  tail <- newSRef Nil
  c1   <- newSRef $ Cons (- 1) tail
  c2   <- newSRef $ Cons 1     c1
  newSRef $ Cons 1 c2

main :: IO ()
main = do 
  outs <- runRCU $ do
    -- initialize list
    head <- testList
    -- spawn 8 readers, each records 100000 snapshots of the list
    rts <- replicateM 8 $ forking $ reading $ reader 100000 0 head
    -- spawn a writer to delete the middle node
    wt  <- forking $ writing $ deleteMiddle head
    
    -- wait for the readers to finish and print snapshots
    outs <- forM rts $ \rt -> do 
      v <- joining rt
      return $ show (rcuThreadId rt) ++ ": " ++ show v
    -- wait for the writer to finish
    joining wt
    return outs
  forM_ outs putStrLn