File: mvar-test.hs

package info (click to toggle)
haskell-strict-concurrency 0.2.4.1-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 84 kB
  • sloc: haskell: 230; sh: 28; makefile: 2
file content (54 lines) | stat: -rw-r--r-- 1,686 bytes parent folder | download | duplicates (3)
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
47
48
49
50
51
52
53
54

{- The Computer Language Shootout
   http://shootout.alioth.debian.org/
   Written by Tom Pledger, 13 Nov 2006. modified by Don Stewart -}

import Control.Concurrent (forkIO,yield)
#if defined(STRICT)
import Control.Concurrent.MVar.Strict
#else
import Control.Concurrent.MVar
#endif
import Control.Monad
import System

data Colour = Blue | Red | Yellow

complement a b = case (a,b) of
    (Red,Yellow)    -> Blue
    (Red,Blue)      -> Yellow
    (Red,Red)       -> Red
    (Yellow,Blue)   -> Red
    (Yellow,Red)    -> Blue
    (Yellow,Yellow) -> Yellow
    (Blue,Red)      -> Yellow
    (Blue,Yellow)   -> Red
    (Blue,Blue)     -> Blue

colors = [Blue, Red, Yellow]

data MP = MP !Int !(Maybe Colour) ![Int]

main = do n     <- getArgs >>= readIO . head
          waker <- newEmptyMVar
          mpv   <- newMVar $ MP n Nothing []

          let arrive c t = do
                MP q w d <- takeMVar mpv
                case w of
                    _ | q == 0 -> if length d /= 3 then putMVar mpv $ MP 0 w (t:d)
                                                   else print $ t + sum d

                    Nothing    -> do putMVar mpv $ MP q (Just c) d
                                     c' <- takeMVar waker
                                     arrive c' $! t+1

                    Just k     -> do let c' = complement k c
                                     -- this should cause a space leak:
                                     putMVar waker c'
                                     putMVar mpv $ MP (q-1) Nothing d
                                     arrive c' $! t+1

          mapM_ (forkIO . flip arrive 0) colors
          arrive Blue 0
          replicateM_ 3 yield