COMP[39]161 Concepts of Programming Languages
Semester 2, 2018

Code (Week 11)

import Control.Concurrent
import Control.Exception
import System.Random

data BST a = Leaf | Branch a (BST a) (BST a)
           deriving (Show)

insert :: (Ord a) => a -> BST a -> BST a
insert x Leaf = Branch x Leaf Leaf
insert x (Branch v l r) = if x <= v then
                            Branch v (insert x l) r
                          else
                            Branch v l (insert x r)

writeMVar :: MVar a -> a -> IO ()
writeMVar m x = takeMVar m >>= \_ -> putMVar m x

-- readMVar m = do x <- takeMVar m
--                 putMVar m x
--                 pure x

loiter time = randomRIO (1,time * 1000) >>= threadDelay

main = do
  log <- newEmptyMVar
  db  <- newMVar Leaf
  wl  <- newMVar ()
  let
    logger 0 = putStrLn "All readers finished"
    logger n = do
        takeMVar log >>= putStrLn
        logger (n-1)

  let reader name = do
        loiter 50
        x <- readMVar db
        putMVar log (name ++ " : " ++ show x)

  let writer num = do
        loiter 10
        takeMVar wl
        x <- readMVar db
        loiter 10
        let x' = insert num x
        evaluate x'
        writeMVar db x'
        putMVar wl ()

  forkIO $ writer 1
  forkIO $ writer 2
  forkIO $ writer 3
  forkIO $ writer 4
  forkIO $ writer 5
  forkIO $ reader "One  "
  forkIO $ reader "Two  "
  forkIO $ reader "Three"
  forkIO $ reader "Four "
  forkIO $ reader "Five "
  logger 5
  return ()

Might be worth compiling with -threaded to get the best results.

2018-11-16 Fri 19:37

Announcements RSS