{-# LANGUAGE FlexibleContexts #-}
module Simulation.Aivika.Trans.Resource.Base
(
FCFSResource,
LCFSResource,
SIROResource,
PriorityResource,
Resource,
newFCFSResource,
newFCFSResourceWithMaxCount,
newLCFSResource,
newLCFSResourceWithMaxCount,
newSIROResource,
newSIROResourceWithMaxCount,
newPriorityResource,
newPriorityResourceWithMaxCount,
newResource,
newResourceWithMaxCount,
resourceStrategy,
resourceMaxCount,
resourceCount,
requestResource,
requestResourceWithPriority,
tryRequestResourceWithinEvent,
releaseResource,
releaseResourceWithinEvent,
usingResource,
usingResourceWithPriority,
incResourceCount,
decResourceCount) where
import Control.Monad
import Control.Monad.Trans
import Control.Exception
import Simulation.Aivika.Trans.Exception
import Simulation.Aivika.Trans.Ref.Base
import Simulation.Aivika.Trans.DES
import Simulation.Aivika.Trans.Internal.Specs
import Simulation.Aivika.Trans.Internal.Simulation
import Simulation.Aivika.Trans.Internal.Event
import Simulation.Aivika.Trans.Internal.Cont
import Simulation.Aivika.Trans.Internal.Process
import Simulation.Aivika.Trans.QueueStrategy
type FCFSResource m = Resource m FCFS
type LCFSResource m = Resource m LCFS
type SIROResource m = Resource m SIRO
type PriorityResource m = Resource m StaticPriorities
data Resource m s =
Resource { forall (m :: * -> *) s. Resource m s -> s
resourceStrategy :: s,
forall (m :: * -> *) s. Resource m s -> Maybe Int
resourceMaxCount :: Maybe Int,
forall (m :: * -> *) s. Resource m s -> Ref m Int
resourceCountRef :: Ref m Int,
forall (m :: * -> *) s.
Resource m s -> StrategyQueue m s (FrozenCont m ())
resourceWaitList :: StrategyQueue m s (FrozenCont m ()) }
newFCFSResource :: MonadDES m
=> Int
-> Simulation m (FCFSResource m)
{-# INLINABLE newFCFSResource #-}
newFCFSResource :: forall (m :: * -> *).
MonadDES m =>
Int -> Simulation m (FCFSResource m)
newFCFSResource = forall (m :: * -> *) s.
(MonadDES m, QueueStrategy m s) =>
s -> Int -> Simulation m (Resource m s)
newResource FCFS
FCFS
newFCFSResourceWithMaxCount :: MonadDES m
=> Int
-> Maybe Int
-> Simulation m (FCFSResource m)
{-# INLINABLE newFCFSResourceWithMaxCount #-}
newFCFSResourceWithMaxCount :: forall (m :: * -> *).
MonadDES m =>
Int -> Maybe Int -> Simulation m (FCFSResource m)
newFCFSResourceWithMaxCount = forall (m :: * -> *) s.
(MonadDES m, QueueStrategy m s) =>
s -> Int -> Maybe Int -> Simulation m (Resource m s)
newResourceWithMaxCount FCFS
FCFS
newLCFSResource :: MonadDES m
=> Int
-> Simulation m (LCFSResource m)
{-# INLINABLE newLCFSResource #-}
newLCFSResource :: forall (m :: * -> *).
MonadDES m =>
Int -> Simulation m (LCFSResource m)
newLCFSResource = forall (m :: * -> *) s.
(MonadDES m, QueueStrategy m s) =>
s -> Int -> Simulation m (Resource m s)
newResource LCFS
LCFS
newLCFSResourceWithMaxCount :: MonadDES m
=> Int
-> Maybe Int
-> Simulation m (LCFSResource m)
{-# INLINABLE newLCFSResourceWithMaxCount #-}
newLCFSResourceWithMaxCount :: forall (m :: * -> *).
MonadDES m =>
Int -> Maybe Int -> Simulation m (LCFSResource m)
newLCFSResourceWithMaxCount = forall (m :: * -> *) s.
(MonadDES m, QueueStrategy m s) =>
s -> Int -> Maybe Int -> Simulation m (Resource m s)
newResourceWithMaxCount LCFS
LCFS
newSIROResource :: (MonadDES m, QueueStrategy m SIRO)
=> Int
-> Simulation m (SIROResource m)
{-# INLINABLE newSIROResource #-}
newSIROResource :: forall (m :: * -> *).
(MonadDES m, QueueStrategy m SIRO) =>
Int -> Simulation m (SIROResource m)
newSIROResource = forall (m :: * -> *) s.
(MonadDES m, QueueStrategy m s) =>
s -> Int -> Simulation m (Resource m s)
newResource SIRO
SIRO
newSIROResourceWithMaxCount :: (MonadDES m, QueueStrategy m SIRO)
=> Int
-> Maybe Int
-> Simulation m (SIROResource m)
{-# INLINABLE newSIROResourceWithMaxCount #-}
newSIROResourceWithMaxCount :: forall (m :: * -> *).
(MonadDES m, QueueStrategy m SIRO) =>
Int -> Maybe Int -> Simulation m (SIROResource m)
newSIROResourceWithMaxCount = forall (m :: * -> *) s.
(MonadDES m, QueueStrategy m s) =>
s -> Int -> Maybe Int -> Simulation m (Resource m s)
newResourceWithMaxCount SIRO
SIRO
newPriorityResource :: (MonadDES m, QueueStrategy m StaticPriorities)
=> Int
-> Simulation m (PriorityResource m)
{-# INLINABLE newPriorityResource #-}
newPriorityResource :: forall (m :: * -> *).
(MonadDES m, QueueStrategy m StaticPriorities) =>
Int -> Simulation m (PriorityResource m)
newPriorityResource = forall (m :: * -> *) s.
(MonadDES m, QueueStrategy m s) =>
s -> Int -> Simulation m (Resource m s)
newResource StaticPriorities
StaticPriorities
newPriorityResourceWithMaxCount :: (MonadDES m, QueueStrategy m StaticPriorities)
=> Int
-> Maybe Int
-> Simulation m (PriorityResource m)
{-# INLINABLE newPriorityResourceWithMaxCount #-}
newPriorityResourceWithMaxCount :: forall (m :: * -> *).
(MonadDES m, QueueStrategy m StaticPriorities) =>
Int -> Maybe Int -> Simulation m (PriorityResource m)
newPriorityResourceWithMaxCount = forall (m :: * -> *) s.
(MonadDES m, QueueStrategy m s) =>
s -> Int -> Maybe Int -> Simulation m (Resource m s)
newResourceWithMaxCount StaticPriorities
StaticPriorities
newResource :: (MonadDES m, QueueStrategy m s)
=> s
-> Int
-> Simulation m (Resource m s)
{-# INLINABLE newResource #-}
newResource :: forall (m :: * -> *) s.
(MonadDES m, QueueStrategy m s) =>
s -> Int -> Simulation m (Resource m s)
newResource s
s Int
count =
forall (m :: * -> *) a. (Run m -> m a) -> Simulation m a
Simulation forall a b. (a -> b) -> a -> b
$ \Run m
r ->
do forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
count forall a. Ord a => a -> a -> Bool
< Int
0) forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) e a.
(MonadException m, Exception e) =>
e -> m a
throwComp forall a b. (a -> b) -> a -> b
$
String -> SimulationRetry
SimulationRetry forall a b. (a -> b) -> a -> b
$
String
"The resource count cannot be negative: " forall a. [a] -> [a] -> [a]
++
String
"newResource."
Ref m Int
countRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef Int
count
StrategyQueue m s (FrozenCont m ())
waitList <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
QueueStrategy m s =>
s -> Simulation m (StrategyQueue m s a)
newStrategyQueue s
s
forall (m :: * -> *) a. Monad m => a -> m a
return Resource { resourceStrategy :: s
resourceStrategy = s
s,
resourceMaxCount :: Maybe Int
resourceMaxCount = forall a. a -> Maybe a
Just Int
count,
resourceCountRef :: Ref m Int
resourceCountRef = Ref m Int
countRef,
resourceWaitList :: StrategyQueue m s (FrozenCont m ())
resourceWaitList = StrategyQueue m s (FrozenCont m ())
waitList }
newResourceWithMaxCount :: (MonadDES m, QueueStrategy m s)
=> s
-> Int
-> Maybe Int
-> Simulation m (Resource m s)
{-# INLINABLE newResourceWithMaxCount #-}
newResourceWithMaxCount :: forall (m :: * -> *) s.
(MonadDES m, QueueStrategy m s) =>
s -> Int -> Maybe Int -> Simulation m (Resource m s)
newResourceWithMaxCount s
s Int
count Maybe Int
maxCount =
forall (m :: * -> *) a. (Run m -> m a) -> Simulation m a
Simulation forall a b. (a -> b) -> a -> b
$ \Run m
r ->
do forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
count forall a. Ord a => a -> a -> Bool
< Int
0) forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) e a.
(MonadException m, Exception e) =>
e -> m a
throwComp forall a b. (a -> b) -> a -> b
$
String -> SimulationRetry
SimulationRetry forall a b. (a -> b) -> a -> b
$
String
"The resource count cannot be negative: " forall a. [a] -> [a] -> [a]
++
String
"newResourceWithMaxCount."
case Maybe Int
maxCount of
Just Int
maxCount | Int
count forall a. Ord a => a -> a -> Bool
> Int
maxCount ->
forall (m :: * -> *) e a.
(MonadException m, Exception e) =>
e -> m a
throwComp forall a b. (a -> b) -> a -> b
$
String -> SimulationRetry
SimulationRetry forall a b. (a -> b) -> a -> b
$
String
"The resource count cannot be greater than " forall a. [a] -> [a] -> [a]
++
String
"its maximum value: newResourceWithMaxCount."
Maybe Int
_ ->
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Ref m Int
countRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
newRef Int
count
StrategyQueue m s (FrozenCont m ())
waitList <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
QueueStrategy m s =>
s -> Simulation m (StrategyQueue m s a)
newStrategyQueue s
s
forall (m :: * -> *) a. Monad m => a -> m a
return Resource { resourceStrategy :: s
resourceStrategy = s
s,
resourceMaxCount :: Maybe Int
resourceMaxCount = Maybe Int
maxCount,
resourceCountRef :: Ref m Int
resourceCountRef = Ref m Int
countRef,
resourceWaitList :: StrategyQueue m s (FrozenCont m ())
resourceWaitList = StrategyQueue m s (FrozenCont m ())
waitList }
resourceCount :: MonadDES m => Resource m s -> Event m Int
{-# INLINABLE resourceCount #-}
resourceCount :: forall (m :: * -> *) s. MonadDES m => Resource m s -> Event m Int
resourceCount Resource m s
r =
forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) s. Resource m s -> Ref m Int
resourceCountRef Resource m s
r)
requestResource :: (MonadDES m, EnqueueStrategy m s)
=> Resource m s
-> Process m ()
{-# INLINABLE requestResource #-}
requestResource :: forall (m :: * -> *) s.
(MonadDES m, EnqueueStrategy m s) =>
Resource m s -> Process m ()
requestResource Resource m s
r =
forall (m :: * -> *) a. (ProcessId m -> Cont m a) -> Process m a
Process forall a b. (a -> b) -> a -> b
$ \ProcessId m
pid ->
forall (m :: * -> *) a. (ContParams m a -> Event m ()) -> Cont m a
Cont forall a b. (a -> b) -> a -> b
$ \ContParams m ()
c ->
forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
do Int
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) s. Resource m s -> Ref m Int
resourceCountRef Resource m s
r)
if Int
a forall a. Eq a => a -> a -> Bool
== Int
0
then do FrozenCont m ()
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m () -> Event m (FrozenCont m a)
freezeContReentering ContParams m ()
c () forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. ContParams m a -> Cont m a -> Event m ()
invokeCont ContParams m ()
c forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. ProcessId m -> Process m a -> Cont m a
invokeProcess ProcessId m
pid forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) s.
(MonadDES m, EnqueueStrategy m s) =>
Resource m s -> Process m ()
requestResource Resource m s
r
forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) s a.
EnqueueStrategy m s =>
StrategyQueue m s a -> a -> Event m ()
strategyEnqueue (forall (m :: * -> *) s.
Resource m s -> StrategyQueue m s (FrozenCont m ())
resourceWaitList Resource m s
r) FrozenCont m ()
c
else do let a' :: Int
a' = Int
a forall a. Num a => a -> a -> a
- Int
1
Int
a' seq :: forall a b. a -> b -> b
`seq` forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) s. Resource m s -> Ref m Int
resourceCountRef Resource m s
r) Int
a'
forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m ()
resumeCont ContParams m ()
c ()
requestResourceWithPriority :: (MonadDES m, PriorityQueueStrategy m s p)
=> Resource m s
-> p
-> Process m ()
{-# INLINABLE requestResourceWithPriority #-}
requestResourceWithPriority :: forall (m :: * -> *) s p.
(MonadDES m, PriorityQueueStrategy m s p) =>
Resource m s -> p -> Process m ()
requestResourceWithPriority Resource m s
r p
priority =
forall (m :: * -> *) a. (ProcessId m -> Cont m a) -> Process m a
Process forall a b. (a -> b) -> a -> b
$ \ProcessId m
pid ->
forall (m :: * -> *) a. (ContParams m a -> Event m ()) -> Cont m a
Cont forall a b. (a -> b) -> a -> b
$ \ContParams m ()
c ->
forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
do Int
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) s. Resource m s -> Ref m Int
resourceCountRef Resource m s
r)
if Int
a forall a. Eq a => a -> a -> Bool
== Int
0
then do FrozenCont m ()
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m () -> Event m (FrozenCont m a)
freezeContReentering ContParams m ()
c () forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. ContParams m a -> Cont m a -> Event m ()
invokeCont ContParams m ()
c forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. ProcessId m -> Process m a -> Cont m a
invokeProcess ProcessId m
pid forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) s p.
(MonadDES m, PriorityQueueStrategy m s p) =>
Resource m s -> p -> Process m ()
requestResourceWithPriority Resource m s
r p
priority
forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) s p a.
PriorityQueueStrategy m s p =>
StrategyQueue m s a -> p -> a -> Event m ()
strategyEnqueueWithPriority (forall (m :: * -> *) s.
Resource m s -> StrategyQueue m s (FrozenCont m ())
resourceWaitList Resource m s
r) p
priority FrozenCont m ()
c
else do let a' :: Int
a' = Int
a forall a. Num a => a -> a -> a
- Int
1
Int
a' seq :: forall a b. a -> b -> b
`seq` forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) s. Resource m s -> Ref m Int
resourceCountRef Resource m s
r) Int
a'
forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m ()
resumeCont ContParams m ()
c ()
releaseResource :: (MonadDES m, DequeueStrategy m s)
=> Resource m s
-> Process m ()
{-# INLINABLE releaseResource #-}
releaseResource :: forall (m :: * -> *) s.
(MonadDES m, DequeueStrategy m s) =>
Resource m s -> Process m ()
releaseResource Resource m s
r =
forall (m :: * -> *) a. (ProcessId m -> Cont m a) -> Process m a
Process forall a b. (a -> b) -> a -> b
$ \ProcessId m
_ ->
forall (m :: * -> *) a. (ContParams m a -> Event m ()) -> Cont m a
Cont forall a b. (a -> b) -> a -> b
$ \ContParams m ()
c ->
forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
do forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s.
(MonadDES m, DequeueStrategy m s) =>
Resource m s -> Event m ()
releaseResourceWithinEvent Resource m s
r
forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m ()
resumeCont ContParams m ()
c ()
releaseResourceWithinEvent :: (MonadDES m, DequeueStrategy m s)
=> Resource m s
-> Event m ()
{-# INLINABLE releaseResourceWithinEvent #-}
releaseResourceWithinEvent :: forall (m :: * -> *) s.
(MonadDES m, DequeueStrategy m s) =>
Resource m s -> Event m ()
releaseResourceWithinEvent Resource m s
r =
forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
do Int
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) s. Resource m s -> Ref m Int
resourceCountRef Resource m s
r)
let a' :: Int
a' = Int
a forall a. Num a => a -> a -> a
+ Int
1
case forall (m :: * -> *) s. Resource m s -> Maybe Int
resourceMaxCount Resource m s
r of
Just Int
maxCount | Int
a' forall a. Ord a => a -> a -> Bool
> Int
maxCount ->
forall (m :: * -> *) e a.
(MonadException m, Exception e) =>
e -> m a
throwComp forall a b. (a -> b) -> a -> b
$
String -> SimulationRetry
SimulationRetry forall a b. (a -> b) -> a -> b
$
String
"The resource count cannot be greater than " forall a. [a] -> [a] -> [a]
++
String
"its maximum value: releaseResourceWithinEvent."
Maybe Int
_ ->
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Bool
f <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) s a.
QueueStrategy m s =>
StrategyQueue m s a -> Event m Bool
strategyQueueNull (forall (m :: * -> *) s.
Resource m s -> StrategyQueue m s (FrozenCont m ())
resourceWaitList Resource m s
r)
if Bool
f
then Int
a' seq :: forall a b. a -> b -> b
`seq` forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) s. Resource m s -> Ref m Int
resourceCountRef Resource m s
r) Int
a'
else do FrozenCont m ()
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) s a.
DequeueStrategy m s =>
StrategyQueue m s a -> Event m a
strategyDequeue (forall (m :: * -> *) s.
Resource m s -> StrategyQueue m s (FrozenCont m ())
resourceWaitList Resource m s
r)
Maybe (ContParams m ())
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
FrozenCont m a -> Event m (Maybe (ContParams m a))
unfreezeCont FrozenCont m ()
c
case Maybe (ContParams m ())
c of
Maybe (ContParams m ())
Nothing ->
forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s.
(MonadDES m, DequeueStrategy m s) =>
Resource m s -> Event m ()
releaseResourceWithinEvent Resource m s
r
Just ContParams m ()
c ->
forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
EventQueueing m =>
Double -> Event m () -> Event m ()
enqueueEvent (forall (m :: * -> *). Point m -> Double
pointTime Point m
p) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m ()
resumeCont ContParams m ()
c ()
tryRequestResourceWithinEvent :: MonadDES m
=> Resource m s
-> Event m Bool
{-# INLINABLE tryRequestResourceWithinEvent #-}
tryRequestResourceWithinEvent :: forall (m :: * -> *) s. MonadDES m => Resource m s -> Event m Bool
tryRequestResourceWithinEvent Resource m s
r =
forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
do Int
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
readRef (forall (m :: * -> *) s. Resource m s -> Ref m Int
resourceCountRef Resource m s
r)
if Int
a forall a. Eq a => a -> a -> Bool
== Int
0
then forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
else do let a' :: Int
a' = Int
a forall a. Num a => a -> a -> a
- Int
1
Int
a' seq :: forall a b. a -> b -> b
`seq` forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) s. Resource m s -> Ref m Int
resourceCountRef Resource m s
r) Int
a'
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
usingResource :: (MonadDES m, EnqueueStrategy m s)
=> Resource m s
-> Process m a
-> Process m a
{-# INLINABLE usingResource #-}
usingResource :: forall (m :: * -> *) s a.
(MonadDES m, EnqueueStrategy m s) =>
Resource m s -> Process m a -> Process m a
usingResource Resource m s
r Process m a
m =
do forall (m :: * -> *) s.
(MonadDES m, EnqueueStrategy m s) =>
Resource m s -> Process m ()
requestResource Resource m s
r
forall (m :: * -> *) a b.
MonadDES m =>
Process m a -> Process m b -> Process m a
finallyProcess Process m a
m forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s.
(MonadDES m, DequeueStrategy m s) =>
Resource m s -> Process m ()
releaseResource Resource m s
r
usingResourceWithPriority :: (MonadDES m, PriorityQueueStrategy m s p)
=> Resource m s
-> p
-> Process m a
-> Process m a
{-# INLINABLE usingResourceWithPriority #-}
usingResourceWithPriority :: forall (m :: * -> *) s p a.
(MonadDES m, PriorityQueueStrategy m s p) =>
Resource m s -> p -> Process m a -> Process m a
usingResourceWithPriority Resource m s
r p
priority Process m a
m =
do forall (m :: * -> *) s p.
(MonadDES m, PriorityQueueStrategy m s p) =>
Resource m s -> p -> Process m ()
requestResourceWithPriority Resource m s
r p
priority
forall (m :: * -> *) a b.
MonadDES m =>
Process m a -> Process m b -> Process m a
finallyProcess Process m a
m forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s.
(MonadDES m, DequeueStrategy m s) =>
Resource m s -> Process m ()
releaseResource Resource m s
r
incResourceCount :: (MonadDES m, DequeueStrategy m s)
=> Resource m s
-> Int
-> Event m ()
{-# INLINABLE incResourceCount #-}
incResourceCount :: forall (m :: * -> *) s.
(MonadDES m, DequeueStrategy m s) =>
Resource m s -> Int -> Event m ()
incResourceCount Resource m s
r Int
n
| Int
n forall a. Ord a => a -> a -> Bool
< Int
0 = forall (m :: * -> *) e a.
(MonadException m, Exception e) =>
e -> Event m a
throwEvent forall a b. (a -> b) -> a -> b
$ String -> SimulationRetry
SimulationRetry String
"The increment cannot be negative: incResourceCount"
| Int
n forall a. Eq a => a -> a -> Bool
== Int
0 = forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise =
do forall (m :: * -> *) s.
(MonadDES m, DequeueStrategy m s) =>
Resource m s -> Event m ()
releaseResourceWithinEvent Resource m s
r
forall (m :: * -> *) s.
(MonadDES m, DequeueStrategy m s) =>
Resource m s -> Int -> Event m ()
incResourceCount Resource m s
r (Int
n forall a. Num a => a -> a -> a
- Int
1)
decResourceCount :: (MonadDES m, EnqueueStrategy m s)
=> Resource m s
-> Int
-> Process m ()
{-# INLINABLE decResourceCount #-}
decResourceCount :: forall (m :: * -> *) s.
(MonadDES m, EnqueueStrategy m s) =>
Resource m s -> Int -> Process m ()
decResourceCount Resource m s
r Int
n
| Int
n forall a. Ord a => a -> a -> Bool
< Int
0 = forall (m :: * -> *) e a.
(MonadDES m, Exception e) =>
e -> Process m a
throwProcess forall a b. (a -> b) -> a -> b
$ String -> SimulationRetry
SimulationRetry String
"The decrement cannot be negative: decResourceCount"
| Int
n forall a. Eq a => a -> a -> Bool
== Int
0 = forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise =
do forall (m :: * -> *) s.
(MonadDES m, EnqueueStrategy m s) =>
Resource m s -> Process m ()
requestResource Resource m s
r
forall (m :: * -> *) s.
(MonadDES m, EnqueueStrategy m s) =>
Resource m s -> Int -> Process m ()
decResourceCount Resource m s
r (Int
n forall a. Num a => a -> a -> a
- Int
1)