@@ -0,0 +1,57 @@
1+module WorkStealing where
4+import Control.Distributed.Process
5+import Control.Distributed.Process.Closure
7+fib :: Integer -> Integer
10+ go (!a, !b) !n | n == 0 = a
11+ | otherwise = go (b, a + b) (n - 1)
13+slave :: ProcessId -> Process ()
19+ -- Ask the queue for work
24+ [ match $ \(pid, n) -> return $ Just (pid, n)
25+ , match $ \() -> return Nothing
28+ -- If there is work, do it and repeat; otherwise, exit
30+ Just (pid, n) -> send pid (fib n) >> go us
35+master :: Integer -> [NodeId] -> Process Integer
39+ workQueue <- spawnLocal $ do
40+ -- As long as there is work, return the next Fib to compute
41+ forM_ [1 .. n] $ \m -> do
45+ -- After that, just report that the work is done
50+ -- Start processes on the slaves that compute Fibonacci numbers
51+ forM_ slaves $ flip spawn ($(mkClosure 'slave) workQueue)
53+ -- Wait for the result
54+ partials <- replicateM (fromInteger n) (expect :: Process Integer)
56+ -- And return the sum
57+ return (sum partials)