import GHC.Conc.Sync import Control.Monad import System.Environment test n = do dog <- newTVarIO False cat <- newTVarIO False let unset = do d <- readTVar dog c <- readTVar cat if (d || c) then retry else return () setDog = unset >> writeTVar dog True setCat = unset >> writeTVar cat True reset = do d <- readTVar dog c <- readTVar cat guard (d || c) writeTVar dog False writeTVar cat False replicateM_ n (do forkIO (atomically setDog) forkIO (atomically setCat) atomically reset atomically reset) main = do [n] <- getArgs test (read n :: Int)