mirrored from https://gitlab.haskell.org/ghc/ghc.git
-
Notifications
You must be signed in to change notification settings - Fork 703
/
sieve-lwc.hs
46 lines (41 loc) · 1.64 KB
/
sieve-lwc.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import Control.Monad
import LwConc.Substrate
import ConcurrentList
import MVarList
import System.Environment
import Data.IORef
initSched = do
newSched
n <- getNumCapabilities
replicateM_ (n-1) newCapability
-- Map over [2..] (2 until infinity), putting the value in mOut. The putting operation will block until
-- mOut is empty. mOut will become empty when some other thread executes takeMVar (getting its value).
generate :: MVar Int -> IO ()
generate mOut = mapM_ (putMVar mOut) [2..]
-- Take a value from mIn, divide it by a prime, if the remainder is not 0, put the value in mOut.
primeFilter :: MVar Int -> MVar Int -> Int -> IO ()
primeFilter mIn mOut prime = do
forever $ do
i <- takeMVar mIn
when (i `mod` prime /= 0) (putMVar mOut i)
-- Take the first commandline argument and call it numArg.
-- Create a new mVar and call it mIn and spawn a thread that runs generate on mIn.
-- Read numArg as an integer value, and run newEmptyMVar that amount of times,
-- calling the result out.
-- Fold over the elements of out, with the function linkFilter, having mIn as the first value.
main = do
initSched
numArg:_ <- getArgs
mIn <- newEmptyMVar
forkIO $ generate mIn
out <- replicateM (read numArg) newEmptyMVar
foldM_ linkFilter mIn out
-- Take a value from mIn, and call it prime. Then show that prime. Make a new thread that
-- runs primeFilter with mIn, mOut and the prime. When this function is used as a fold
-- function, mOut becomes the mIn of the next iteration.
linkFilter :: MVar Int -> MVar Int -> IO (MVar Int)
linkFilter mIn mOut = do
prime <- takeMVar mIn
putStrLn $ show prime
forkIO $ primeFilter mIn mOut prime
return mOut