This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Add CRef type, primops, and functions for homework 1

  • Loading branch information...
barrucadu committed Oct 15, 2017
1 parent 6816068 commit 2070bdfaf5174fc14f6835d8410988cf111a854a
Showing with 28 additions and 5 deletions.
  1. +28 −5 Test/MiniFu.hs
@@ -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
@@ -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))
@@ -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

0 comments on commit 2070bdf

Please sign in to comment.