diff options
Diffstat (limited to 'src/Parallel.hs')
| -rw-r--r-- | src/Parallel.hs | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/Parallel.hs b/src/Parallel.hs new file mode 100644 index 0000000..cc6eb22 --- /dev/null +++ b/src/Parallel.hs @@ -0,0 +1,30 @@ +module Parallel where + +import Control.Concurrent +import Control.Monad (replicateM_) +import Data.IORef + + +-- | Does not return results in-order. +parallelForM :: [a] -> (a -> IO b) -> IO [b] +parallelForM inputList action = do + nthread <- getNumCapabilities + + listref <- newIORef inputList + outref <- newIORef [] + donechan <- newChan + replicateM_ nthread $ forkIO $ + let loop = do + mitem <- atomicModifyIORef' listref (\case l@[] -> (l, Nothing) + item : l -> (l, Just item)) + case mitem of + Just item -> do + res <- action item + atomicModifyIORef' outref (\l -> (res : l, ())) + loop + Nothing -> do + writeChan donechan () + in loop + + replicateM_ nthread $ readChan donechan + reverse <$> readIORef outref |
