mirror of
https://github.com/barrucadu/dejafu.git
synced 2024-12-18 19:11:37 +03:00
Simpler detection of deadlock in Fixed
This commit is contained in:
parent
2a33b4a017
commit
5f85be3574
@ -33,7 +33,7 @@ module Control.Monad.Conc.Fixed
|
|||||||
import Prelude hiding (take)
|
import Prelude hiding (take)
|
||||||
|
|
||||||
import Control.Applicative (Applicative(..), (<$>))
|
import Control.Applicative (Applicative(..), (<$>))
|
||||||
import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, takeMVar, tryTakeMVar)
|
import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, takeMVar)
|
||||||
import Control.Monad.Cont (Cont, cont, runCont)
|
import Control.Monad.Cont (Cont, cont, runCont)
|
||||||
import Data.Map (Map)
|
import Data.Map (Map)
|
||||||
import Data.Maybe (fromJust, fromMaybe, isNothing, isJust)
|
import Data.Maybe (fromJust, fromMaybe, isNothing, isJust)
|
||||||
@ -220,25 +220,22 @@ data Block = WaitFull ThreadId | WaitEmpty ThreadId deriving Eq
|
|||||||
-- A thread is represented as a tuple of (next action, is blocked).
|
-- A thread is represented as a tuple of (next action, is blocked).
|
||||||
runThreads :: ThreadId -> Scheduler s -> s -> Map ThreadId (Action, Bool) -> MVar (Maybe a) -> IO s
|
runThreads :: ThreadId -> Scheduler s -> s -> Map ThreadId (Action, Bool) -> MVar (Maybe a) -> IO s
|
||||||
runThreads last sched s threads mvar
|
runThreads last sched s threads mvar
|
||||||
| M.null threads = return s
|
| isTerminated = return s
|
||||||
| M.null runnable = do
|
| isDeadlocked = putMVar mvar Nothing >> return s
|
||||||
-- If we're here, it's possible the main thread has terminated
|
|
||||||
-- successfully, in which case we DON'T have a deadlock.
|
|
||||||
val <- fromMaybe Nothing <$> tryTakeMVar mvar
|
|
||||||
putMVar mvar val
|
|
||||||
return s
|
|
||||||
|
|
||||||
| isBlocked = putStrLn "Attempted to run a blocked thread, assuming deadlock." >> putMVar mvar Nothing >> return s
|
| isBlocked = putStrLn "Attempted to run a blocked thread, assuming deadlock." >> putMVar mvar Nothing >> return s
|
||||||
| isNothing thread = putStrLn "Attempted to run a nonexistant thread, assuming deadlock." >> putMVar mvar Nothing >> return s
|
| isNonexistant = putStrLn "Attempted to run a nonexistant thread, assuming deadlock." >> putMVar mvar Nothing >> return s
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
threads <- runThread (fst $ fromJust thread, chosen) threads
|
threads' <- runThread (fst $ fromJust thread, chosen) threads
|
||||||
runThreads chosen sched s' threads mvar
|
runThreads chosen sched s' threads' mvar
|
||||||
|
|
||||||
where
|
where
|
||||||
(chosen, s') = if last == -1 then (0, s) else sched s last $ M.keys runnable
|
(chosen, s') = if last == -1 then (0, s) else sched s last $ M.keys runnable
|
||||||
runnable = M.filter (not . snd) threads
|
runnable = M.filter (not . snd) threads
|
||||||
thread = M.lookup chosen threads
|
thread = M.lookup chosen threads
|
||||||
isBlocked = snd . fromJust $ M.lookup chosen threads
|
isBlocked = snd . fromJust $ M.lookup chosen threads
|
||||||
|
isNonexistant = isNothing thread
|
||||||
|
isTerminated = 0 `notElem` M.keys threads
|
||||||
|
isDeadlocked = M.null runnable
|
||||||
|
|
||||||
-- | Run a single thread one step, by dispatching on the type of
|
-- | Run a single thread one step, by dispatching on the type of
|
||||||
-- 'Action'.
|
-- 'Action'.
|
||||||
|
Loading…
Reference in New Issue
Block a user