Deconflate lifting and creating new CVars in Fixed

This commit is contained in:
Michael Walker 2015-01-12 00:08:53 +00:00
parent 9745357817
commit 9aee30ac57
3 changed files with 20 additions and 6 deletions

View File

@ -106,9 +106,9 @@ fork (C ma) = C $ cont $ \c -> AFork (runCont ma $ const AStop) $ c ()
-- | Create a new empty 'CVar'.
newEmptyCVar :: Conc t (CVar t a)
newEmptyCVar = liftIO $ do
ioref <- newIORef (Nothing, [])
return $ V ioref
newEmptyCVar = C $ cont lifted where
lifted c = ANew $ c <$> newEmptyCVar'
newEmptyCVar' = V <$> newIORef (Nothing, [])
-- | Block on a 'CVar' until it is empty, then write to it.
putCVar :: CVar t a -> a -> Conc t ()

View File

@ -50,6 +50,7 @@ data Action n r =
| forall a. AGet (R r a) (a -> Action n r)
| forall a. ATake (R r a) (a -> Action n r)
| forall a. ATryTake (R r a) (Maybe a -> Action n r)
| ANew (n (Action n r))
| ALift (n (Action n r))
| AStop
@ -76,6 +77,8 @@ type Trace = [(ThreadId, ThreadAction)]
data ThreadAction =
Fork ThreadId
-- ^ Start a new thread.
| New
-- ^ Create a new 'CVar'.
| Put [ThreadId]
-- ^ Put into a 'CVar', possibly waking up some threads.
| BlockedPut
@ -169,6 +172,7 @@ stepThread (ATryPut ref a c) = stepTryPut ref a c
stepThread (AGet ref c) = stepGet ref c
stepThread (ATake ref c) = stepTake ref c
stepThread (ATryTake ref c) = stepTryTake ref c
stepThread (ANew na) = stepNew na
stepThread (ALift na) = stepLift na
stepThread AStop = stepStop
@ -250,6 +254,16 @@ stepTryTake ref c fixed i threads = do
return (goto (c val) i threads', TryTake True woken)
Nothing -> return (goto (c Nothing) i threads, TryTake False [])
-- | Create a new @CVar@. This is exactly the same as lifting a value,
-- except by separating the two we can (a) produce a more useful
-- trace, and (b) make smarter pre-emption decisions.
stepNew :: (Monad (c t), Monad n)
=> n (Action n r)
-> Fixed c n r t -> ThreadId -> Threads n r -> n (Threads n r, ThreadAction)
stepNew na _ i threads = do
a <- na
return (goto a i threads, New)
-- | Lift an action from the underlying monad into the @Conc@
-- computation.
stepLift :: (Monad (c t), Monad n)

View File

@ -102,9 +102,9 @@ fork (C ma) = C $ cont $ \c -> AFork (runCont ma $ const AStop) $ c ()
-- | Create a new empty 'CVar'.
newEmptyCVar :: Conc t (CVar t a)
newEmptyCVar = liftST $ do
stref <- newSTRef (Nothing, [])
return $ V stref
newEmptyCVar = C $ cont lifted where
lifted c = ANew $ c <$> newEmptyCVar'
newEmptyCVar' = V <$> newSTRef (Nothing, [])
-- | Block on a 'CVar' until it is empty, then write to it.
putCVar :: CVar t a -> a -> Conc t ()