Advertisement
Guest User

Untitled

a guest
Apr 26th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-# LANGUAGE BangPatterns #-}
  2.  
  3. import Text.Printf
  4. import System.Environment
  5. import Control.Monad
  6. import Control.Concurrent
  7. import Control.Concurrent.QSem
  8.  
  9. nTasksDefault = 10
  10. beginOffsetDefault = 15
  11.  
  12. parseArgs :: [String] -> (Int, Int)
  13. parseArgs [n, beg] = (read n, read beg)
  14. parseArgs       _  = (nTasksDefault, beginOffsetDefault)
  15.  
  16. fib x | x < 3 = 1
  17.       | otherwise = (fib $ x - 1) + (fib $ x - 2)
  18.  
  19. routine :: QSem -> (MVar Int, Int) -> IO ()
  20. routine outputMutex (resultMVar, x) = do
  21.     safeIOWithSem outputMutex $ printf "Thread id = %d start\n" x
  22.     let !result = fib x
  23.     putMVar resultMVar result
  24.     safeIOWithSem outputMutex $ printf "Thread id = %d end\n" x
  25.  
  26. safeIOWithSem :: QSem -> IO () -> IO ()
  27. safeIOWithSem m f = waitQSem m >> f >> signalQSem m
  28.  
  29. main :: IO ()
  30. main = do
  31.     args <- getArgs
  32.     let (nTasks, beginOffset) = parseArgs args
  33.     outputMutex <- newQSem 1
  34.     resultMVars <- replicateM nTasks newEmptyMVar
  35.     let tasks = zip resultMVars [beginOffset .. beginOffset + nTasks]
  36.    
  37.     safeIOWithSem outputMutex $ getNumCapabilities >>= printf "Processors = %d\n"
  38.     safeIOWithSem outputMutex $ putStrLn "Start"
  39.    
  40.     mapM_ (forkIO . routine outputMutex) tasks
  41.    
  42.     forM_ tasks $ \(m, x) -> do
  43.         r <- takeMVar m
  44.         safeIOWithSem outputMutex $ printf "Fib(%d) = %d\n" x r
  45.    
  46.     safeIOWithSem outputMutex $ putStrLn "End"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement