Good afternoon Haskellers,<br><br>So I'm trying to understand how STM works, and wrote a quick 'eating philosophers' example to see if I understood how it's supposed to work.<br>The problem is that while it executes, it doesn't appear to *do* anything.
<br><br>Did I completely write things wrongheadedly or am I being bitten by something more subtle?<br><br>Thanks.<br><br>import Control.Concurrent.STM<br>import Control.Concurrent<br>import Data.Array<br>import System.Random
<br><br>think :: IO ()<br>think = do<br> ms <- randomRIO (20,1000)<br> threadDelay ms<br><br>data Philosopher = Philosopher {left::Bool,right::Bool,neighbors::(Int,Int)}<br> deriving Show<br><br>makeInitPhilosopher a = Philosopher {left=False,right=False,neighbors=a}
<br> <br><br>initPhilosophers = listArray (0,4) <br> (map makeInitPhilosopher [(1,4),(2,0),(3,1),(4,2),(0,3)])<br><br>main = do<br> z <- atomically $ newTVar initPhilosophers
<br> mapM_ (\x -> forkIO (loop x z 0 10000)) [0,1,2,3,4]<br><br>loop n tps c l | c > l = (atomically (readTVar tps)) >>= (\x -> print x)<br> | otherwise = do<br> think
<br> atomically $ eat n tps<br> loop n tps (c+1) l<br><br>eat :: Int -> TVar (Array Int Philosopher) -> STM ()<br>eat n tps = do<br>
takeLeft n tps<br> takeRight n tps<br> releaseLeft n tps<br> releaseRight n tps<br><br>takeLeft :: Int -> TVar (Array Int Philosopher) -> STM ()<br>takeLeft n tps = do<br> ps <- readTVar tps<br> let p = ps ! n
<br> if right (ps ! (fst $ neighbors p)) == False<br> then (writeTVar tps $ ps // [(n,p{left=True})])<br> else retry<br><br>takeRight :: Int -> TVar (Array Int Philosopher) -> STM ()<br>takeRight n tps = do
<br> ps <- readTVar tps<br> let p = ps ! n<br> if left (ps ! (snd $ neighbors p)) == False<br> then (writeTVar tps $ ps // [(n,p{right=True})])<br> else retry<br><br>releaseLeft n tps = do<br> ps <- readTVar tps
<br> let p = ps ! n<br> writeTVar tps $ ps // [(n,p{left=False})]<br> <br>releaseRight n tps = do<br> ps <- readTVar tps<br> let p = ps ! n<br> writeTVar tps $ ps // [(n,p{right=False})]<br>