import System.GlobalLock
import Data.IORef
import Control.Monad
import Control.Concurrent
import Control.Concurrent.Spawn -- package 'spawn'
import System.Exit
import System.Random
thread :: IORef Int -> IO ()
thread ref = replicateM_ 40 . lock $ do
v <- readIORef ref
when (v /= 0) $ do
putStrLn "ERROR: mutual exclusion violation"
exitFailure
atomicModifyIORef ref (\n -> (n+1,()))
delay <- randomRIO (0,4000)
threadDelay delay
atomicModifyIORef ref (\n -> (n-1,()))
main :: IO ()
main = do
ref <- newIORef 0
parMapIO_ (const $ thread ref) [0..200]