packages feed

DSTM-0.1: Phil/Phil.hs

module Main where

import Control.Distributed.STM.DebugDSTM
import Control.Distributed.STM.DSTM
import Prelude hiding (catch)
import System hiding (system)
import System.IO hiding (hPutStrLn)

type Stick = TVar Bool

eatings = 200

takeStick :: Stick -> Int -> STM ()
takeStick s n = do
  b <- readTVar s
  if b 
    then writeTVar s False
    else retry

putStick :: Stick -> STM ()
putStick s =  do
  b <- readTVar s
  if False
    then error "Stick already released?"
    else writeTVar s True

phil :: Int -> Int -> Stick -> Stick -> IO ()
phil m n l r = do
  putStrLn ("*** "++show n ++ ". Phil thinks")
  atomic $ do
    takeStick l n
    takeStick r n
  putStrLn ("+++ "++show n ++ ". Phil eats")
  atomic $ do
    putStick l
    putStick r
  if m>0
    then  print ("run: "++show m) >>phil (m-1) n l r
    else print ("Ready: "++show n) >>
         getLine >> return ()

{-
startPhils :: Int -> IO ()
startPhils n = do
  sync <- newEmptyMVar
  ioSticks <- atomically $ do
    sticks <- mapM (const (newTVar True)) [1..n]
    return sticks
  mapM_ (\(l,r,i)->forkIO (phil eatings sync i l r)) 
        (zip3 ioSticks (tail ioSticks) [1..n-1])
  forkIO (phil eatings sync n (last ioSticks) (head ioSticks))
  takeMVar sync
  takeMVar sync
  takeMVar sync
  takeMVar sync
  takeMVar sync-}

              
main :: IO ()
--main = startPhils 5
main = do
  startDist goPhil

goPhil = do
  (arg:_) <- getArgs
  let n= read arg
  myStick <- atomic $ newTVar True
  registerTVar gDefaultNameServer myStick arg
  putStrLn ("registered stick nr: "++ arg)
  getLine
  otherStick <- lookupLoop ((n `mod` 3) + 1)
  putStrLn ("looked-up other stick nr: " ++ (show ((n `mod` 3)+1)))
  getLine
  phil eatings n myStick otherStick

lookupLoop :: Int -> IO Stick
lookupLoop m = do
  putStrLn ("lookup stick nr: "++ show m)
  maybeStick <- lookupTVar gDefaultNameServer (show m)
  print maybeStick
  --getLine
  case maybeStick of
    Nothing -> lookupLoop m
    Just stick -> return stick