{-# LANGUAGE BangPatterns #-} module ManyQueue where import Control.Concurrent import Control.Monad import Conf newtype MQueue a = MQueue [MVar a] newMQueue size = do lst <- replicateM size newEmptyMVar return (MQueue (cycle lst)) writeMQueue :: (MQueue a) -> a -> IO (MQueue a) writeMQueue (MQueue (x:xs)) el = do putMVar x el return (MQueue xs) readMQueue :: (MQueue a) -> IO (MQueue a, a) readMQueue (MQueue (x:xs)) = do el <- takeMVar x return ((MQueue xs), el) elements :: [Int] elements = [0] ++ [1 .. iTERATIONS] -- workaround -- elements = [0 .. iTERATIONS] -- heap overflow testManyQueue'1P1C = do print "Test.ManyQueue.testManyQueue'1P1C" finished <- newEmptyMVar mq <- newMQueue bufferSize let writer _ 0 = putMVar finished () writer q x = do q' <- writeMQueue q x writer q' (x-1) writer' _ [] = putMVar finished () writer' q (x:xs) = do q' <- writeMQueue q x writer' q' xs reader _ !acc 0 = print acc >> putMVar finished () reader q !acc n = do (q', x) <- readMQueue q reader q' (acc+x) (n-1) --forkIO $ writer mq iTERATIONS forkIO $ writer' mq elements forkIO $ reader mq 0 iTERATIONS takeMVar finished takeMVar finished testManyQueue'1P3C = do print "Test.ManyQueue.testManyQueue'1P3C" let tCount = 3 finished <- newEmptyMVar mqs <- replicateM tCount (newMQueue bufferSize) let writer _ [] = putMVar finished () writer qs (x:xs) = do qs' <- mapM (\q -> writeMQueue q x) qs writer qs' xs reader _ !acc 0 = print acc >> putMVar finished () reader q !acc n = do (q', x) <- readMQueue q reader q' (acc+x) (n-1) forkIO $ writer mqs elements mapM_ (\ mq -> forkIO $ reader mq 0 iTERATIONS) mqs replicateM (tCount+1) (takeMVar finished) return ()