Ticket #1589: Thread.hs

File Thread.hs, 2.1 KB (added by guest, 5 years ago)
Line 
1{-# OPTIONS_GHC -O2 #-}
2import IO
3import System.Environment
4import System.CPUTime
5import Text.Printf
6import Control.Monad
7import Control.Concurrent
8import Control.Concurrent.MVar
9
10type Msg = (Int, String)
11
12nthreadsDefault :: Int
13nthreadsDefault = 10000
14
15npumpDefault :: Int
16npumpDefault = 100
17
18main :: IO ()
19main = do
20    hSetBuffering stdout NoBuffering
21    args <- getArgs
22    let (nthreads, npump) =
23            case args of
24            [] -> (nthreadsDefault, npumpDefault)
25            [arg] -> (read arg, npumpDefault)
26            [arg1,arg2] -> (read arg1, read arg2)
27            _ -> error "Use 0, 1, or 2 arguments\n"
28    printf "Creating pipeline with %d processes in it.\n" nthreads
29    t1s <- getCPUTimeDouble
30    s <- newEmptyMVar
31    e <- createMany nthreads s
32    t1e <- getCPUTimeDouble
33    printf "Pumping a single message through the pipeline.\n"
34    t2s <- getCPUTimeDouble
35    pump 1 s e "Hello, World!"
36    t2e <- getCPUTimeDouble
37    printf "Pumping a %d messages through the pipeline.\n" npump
38    t3s <- getCPUTimeDouble
39    pump npump s e "x"
40    t3e <- getCPUTimeDouble
41    let ct = t1e - t1s
42        p1 = t2e - t2s
43        p2 = t3e - t3s
44        n = fromIntegral nthreads * 1e-6
45        p = fromIntegral npump
46    printf "       n   create    pump1    pump2 create/n  pump1/n  pump2/n\n"
47    printf "                s        s        s       us       us       us\n"
48    printf "%8d %8.3f %8.3f %8.3f %8.2f %8.2f %8.2f\n" nthreads ct p1 p2 (ct/n) (p1/n) (p2/n/p)
49
50pump :: Int -> MVar Msg -> MVar Msg -> String -> IO ()
51pump n s e t = do
52    forkIO $ replicateM_ n $ putMVar s (0, t)
53    replicateM_ n $ do
54        msg <- takeMVar e
55        when (t /= snd msg) $
56            error "Distorted message"
57
58createMany :: Int -> MVar Msg -> IO (MVar Msg)
59createMany 0 v = return v
60createMany n v = do
61    o <- newEmptyMVar
62    forkIO $ copy v o
63    createMany (n-1) o
64
65copy :: MVar Msg -> MVar Msg -> IO ()
66copy i o = do
67    (n, v) <- takeMVar i
68    let n' = n+1
69    seq n' (putMVar o (n', v))
70    copy i o
71
72getCPUTimeDouble :: IO Double
73getCPUTimeDouble = do
74    t <- getCPUTime
75    return $ fromInteger t * 1e-12