Skip to content
This repository has been archived by the owner on Jul 5, 2018. It is now read-only.

Commit

Permalink
Add CRef type, primops, and functions for homework 1
Browse files Browse the repository at this point in the history
  • Loading branch information
barrucadu committed Oct 15, 2017
1 parent 6816068 commit 2070bdf
Showing 1 changed file with 28 additions and 5 deletions.
33 changes: 28 additions & 5 deletions Test/MiniFu.hs
Expand Up @@ -38,11 +38,15 @@ newtype MiniFu m a = MiniFu { runMiniFu :: K.Cont (PrimOp m) a }

-- | One of the basic actions that a @MonadConc@ can do.
data PrimOp m where
Fork :: MiniFu m () -> (ThreadId -> PrimOp m) -> PrimOp m
NewEmptyMVar :: (MVar m a -> PrimOp m) -> PrimOp m
PutMVar :: MVar m a -> a -> PrimOp m -> PrimOp m
TakeMVar :: MVar m a -> (a -> PrimOp m) -> PrimOp m
Stop :: m () -> PrimOp m
Fork :: MiniFu m () -> (ThreadId -> PrimOp m) -> PrimOp m
NewEmptyMVar :: (MVar m a -> PrimOp m) -> PrimOp m
PutMVar :: MVar m a -> a -> PrimOp m -> PrimOp m
TakeMVar :: MVar m a -> (a -> PrimOp m) -> PrimOp m
NewCRef :: a -> (CRef m a -> PrimOp m) -> PrimOp m
ReadCRef :: CRef m a -> (a -> PrimOp m) -> PrimOp m
WriteCRef :: CRef m a -> a -> PrimOp m -> PrimOp m
ModifyCRef :: CRef m a -> (a -> (a, b)) -> (b -> PrimOp m) -> PrimOp m
Stop :: m () -> PrimOp m

-- | @MVar@s have a unique ID too, used in thread blocking.
newtype MVarId = MVarId Int
Expand All @@ -55,6 +59,9 @@ data MVar m a = MVar
, mvarRef :: C.CRef m (Maybe a)
}

-- | A @CRef@ just delegates directly to the underlying monad.
newtype CRef m a = CRef { crefRef :: C.CRef m a }

-- | Fork a computation to happen concurrently.
fork :: MiniFu m () -> MiniFu m ThreadId
fork ma = MiniFu (K.cont (Fork ma))
Expand All @@ -75,6 +82,22 @@ putMVar v a = MiniFu (K.cont (\k -> PutMVar v a (k ())))
takeMVar :: MVar m a -> MiniFu m a
takeMVar v = MiniFu (K.cont (TakeMVar v))

-- | Create a new reference.
newCRef :: a -> MiniFu m (CRef m a)
newCRef a = MiniFu (K.cont (NewCRef a))

-- | Read the current value stored in a reference.
readCRef :: CRef m a -> MiniFu m a
readCRef r = MiniFu (K.cont (ReadCRef r))

-- | Write a new value into an @CRef@.
writeCRef :: CRef m a -> a -> MiniFu m ()
writeCRef r a = MiniFu (K.cont (\k -> WriteCRef r a (k ())))

-- | Atomically modify the value stored in a reference.
atomicModifyCRef :: CRef m a -> (a -> (a, b)) -> MiniFu m b
atomicModifyCRef r f = MiniFu (K.cont (ModifyCRef r f))

-------------------------------------------------------------------------------

-- | Execute a concurrent computation with a given scheduler, and
Expand Down

0 comments on commit 2070bdf

Please sign in to comment.