module Test.DejaFu.Deterministic.Schedule
( Scheduler
, ThreadId
, NonEmpty(..)
, randomSched
, roundRobinSched
, randomSchedNP
, roundRobinSchedNP
, makeNP
, toList
) where
import Data.List.Extra
import System.Random (RandomGen, randomR)
import Test.DejaFu.Deterministic.Internal
randomSched :: RandomGen g => Scheduler g
randomSched g _ threads = (threads' !! choice, g') where
(choice, g') = randomR (0, length threads' 1) g
threads' = map fst $ toList threads
randomSchedNP :: RandomGen g => Scheduler g
randomSchedNP = makeNP randomSched
roundRobinSched :: Scheduler ()
roundRobinSched _ Nothing _ = (0, ())
roundRobinSched _ (Just (prior, _)) threads
| prior >= maximum threads' = (minimum threads', ())
| otherwise = (minimum $ filter (>prior) threads', ())
where
threads' = map fst $ toList threads
roundRobinSchedNP :: Scheduler ()
roundRobinSchedNP = makeNP roundRobinSched
makeNP :: Scheduler s -> Scheduler s
makeNP sched = newsched where
newsched s p@(Just (prior, _)) threads
| prior `elem` map fst (toList threads) = (prior, s)
| otherwise = sched s p threads
newsched s Nothing threads = sched s Nothing threads