-- Communicating Haskell Processes. -- Copyright (c) 2008, University of Kent. -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without -- modification, are permitted provided that the following conditions are -- met: -- -- * Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- * Redistributions in binary form must reproduce the above copyright -- notice, this list of conditions and the following disclaimer in the -- documentation and/or other materials provided with the distribution. -- * Neither the name of the University of Kent nor the names of its -- contributors may be used to endorse or promote products derived from -- this software without specific prior written permission. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- | A module containing a few miscellaneous items that can't go in Control.Concurrent.CHP.Base -- because they would form a cyclic module link. Not publicly visible. -- TODO rename this module. module Control.Concurrent.CHPSpec.CSP where import qualified Control.Exception as C import Control.Monad.Reader import Control.Monad.State import qualified Data.List as L import qualified Data.Map as Map import Data.Typeable import Control.Concurrent.CHPSpec.Base import Control.Concurrent.CHPSpec.Enroll import Control.Concurrent.CHPSpec.Spec {- -- | Synchronises on the given barrier. You must be enrolled on a barrier in order -- to synchronise on it. Returns the new phase, following the synchronisation. syncBarrierWith :: (Unique -> (Unique -> Integer) -> String -> [RecordedIndivEvent Unique]) -> (Int -> STM ()) -> Enrolled PhasedBarrier phase -> CHP phase syncBarrierWith recE storeN (Enrolled (Barrier (e,tv, fph))) = buildOnEventPoison (wrapIndiv recE) e (EventActions incPhase (return ())) (NoPoison <$> (atomically $ readTVar tv)) where incPhase :: Map.Map Unique Int -> STM () incPhase m = do readTVar tv >>= writeTVar tv . fph maybe (return ()) storeN $ Map.lookup (Event.getEventUnique e) m -} data PhasedBarrier phase = Barrier EventId deriving (Eq, Typeable) instance Enrollable PhasedBarrier phase where enroll b f = f $ Enrolled b resign _ m = m bottomPrefix :: String bottomPrefix = "__CHP.bottom__" fakeCommIn :: Integer -> CHP a fakeCommIn n = addSpecT1 $ do st <- get put $ st { chpNextBottom = succ $ chpNextBottom st } return (error $ bottomPrefix ++ show (chpNextBottom st) ,Sync $ Right (n, DirInput, chpNextBottom st) ) fakeCommOut :: Integer -> a -> CHP () fakeCommOut n x = addSpecT1 $ do possErr <- lift $ C.try $ C.evaluate x case possErr of Left (C.ErrorCall s) | bottomPrefix `L.isPrefixOf` s -> return ((), Sync $ Right (n, DirOutput, read $ L.drop (L.length bottomPrefix) s)) -- Wasn't one of our bottoms, we can't know anything about it, hope this will work in FDR: _ -> return ((), Sync $ Left n) fakeCommBarr :: Integer -> CHP a fakeCommBarr n = addSpecT1 $ return (undefined, Sync $ Left n) -- TODO this method will give a different channel each time, but at the moment -- we treat it as if it will always act the same, so for example with recursive -- processes (such as the sieve), it won't reflect the behaviour correctly newEvent :: StateT CHPState IO EventId newEvent = do st <- get let n = toInteger $ Map.size $ chpEventMap st put $ st { chpEventMap = Map.insert n "" $ chpEventMap st } return n labelEvent :: EventId -> String -> StateT CHPState IO () labelEvent n s = modify $ \st -> st { chpEventMap = Map.insert n s $ chpEventMap st } newtype Shared c a = Shared (c a)