summaryrefslogtreecommitdiff
path: root/src/Parallel.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Parallel.hs')
-rw-r--r--src/Parallel.hs30
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