/crawl2/examples/mapfold/MapFold.hs
http://github.com/fortytools/holumbus · Haskell · 98 lines · 49 code · 17 blank · 32 comment · 0 complexity · b39525d58266272e7724baaadd36f66f MD5 · raw file
- -- ------------------------------------------------------------
- {- |
- Module : MapFold
- Copyright : Copyright (C) 2009 Uwe Schmidt
- License : MIT
- Maintainer : Uwe Schmidt (uwe@fh-wedel.de)
- Stability : experimental
- Portability: none portable
- Test program for Control.Concurrent.MapFold module
- -}
- -- ------------------------------------------------------------
- module MapFold
- where
- import Control.Concurrent
- import Control.Concurrent.MapFold
- import System.IO
- import System.IO.Unsafe
- import System.Random
- -- ------------------------------------------------------------
- main :: IO ()
- main = do
- mapM_ (runEx [1..10]) [1,2,5,10,20]
- runEx :: [Int] -> Int -> IO ()
- runEx xs n = do
- putStrLn $ "example run with " ++ show n ++ " processors and input " ++ show xs
- res <- run n xs
- putStrLn $ "result is " ++ res
- -- ------------------------------------------------------------
- --
- -- test case: take a list of numbers, in the map phase convert them into strings
- -- and in the fold phase build the expression for summing up the numbers.
- -- The trace output shows the sequence of the map and fold operations performed.
- -- The test runs show different results for different runs.
- --
- -- So in general the binary op
- -- applied during the fold phase must be associative and symmetric to deliver useful
- -- results (to make the result determinated).
- run :: Int -> [Int] -> IO String
- run processors = mapFold processors mapF foldF
- where
- mapF x = do
- logg $ "mapF: inp = " ++ show x
- randomDelay
- res <- return $ show x
- logg $ "mapF: res = " ++ show res
- return res
- foldF x y = do
- logg $ "foldF: inp = " ++ show (x,y)
- randomDelay
- res <- return $ "(" ++ x ++ "+" ++ y ++ ")"
- logg $ "foldF: res = " ++ show res
- return res
- -- ------------------------------------------------------------
- --
- -- simulate some compilcated computation
- -- by delaying the process a fraction of a second
- randomDelay :: IO ()
- randomDelay = mysec >>= threadDelay
- where
- mysec :: IO Int
- mysec = do
- r <- randomIO
- return $ (r :: Int) `mod` 1000000
- -- ------------------------------------------------------------
- --
- -- just for syncing log messages
- stdErrSem :: QSem
- stdErrSem = unsafePerformIO $ newQSem 1
- waitStderr, signalStderr :: IO ()
- waitStderr = waitQSem stdErrSem
- signalStderr = signalQSem stdErrSem
- logg :: String -> IO ()
- logg msg = do
- waitStderr
- tid <- myThreadId
- hPutStrLn stderr $ show tid ++ ": " ++ msg
- hFlush stderr
- signalStderr
- -- ------------------------------------------------------------