-- |
-- Module     : Simulation.Aivika.Operation
-- Copyright  : Copyright (c) 2009-2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 8.0.1
--
-- It defines a stateless activity, some simplification of 'Server' and 'Activity'.
module Simulation.Aivika.Operation
       (-- * Operation
        Operation,
        newOperation,
        newPreemptibleOperation,
        -- * Processing
        operationProcess,
        -- * Operation Properties
        operationTotalUtilisationTime,
        operationTotalPreemptionTime,
        operationUtilisationTime,
        operationPreemptionTime,
        operationUtilisationFactor,
        operationPreemptionFactor,
        -- * Statistics Reset
        resetOperation,
        -- * Summary
        operationSummary,
        -- * Derived Signals for Properties
        operationTotalUtilisationTimeChanged,
        operationTotalUtilisationTimeChanged_,
        operationTotalPreemptionTimeChanged,
        operationTotalPreemptionTimeChanged_,
        operationUtilisationTimeChanged,
        operationUtilisationTimeChanged_,
        operationPreemptionTimeChanged,
        operationPreemptionTimeChanged_,
        operationUtilisationFactorChanged,
        operationUtilisationFactorChanged_,
        operationPreemptionFactorChanged,
        operationPreemptionFactorChanged_,
        -- * Basic Signals
        operationUtilising,
        operationUtilised,
        operationPreemptionBeginning,
        operationPreemptionEnding,
        -- * Overall Signal
        operationChanged_) where

import Data.IORef
import Data.Monoid

import Control.Monad
import Control.Monad.Trans

import Simulation.Aivika.Internal.Specs
import Simulation.Aivika.Simulation
import Simulation.Aivika.Dynamics
import Simulation.Aivika.Internal.Event
import Simulation.Aivika.Signal
import Simulation.Aivika.Cont
import Simulation.Aivika.Process
import Simulation.Aivika.Activity
import Simulation.Aivika.Server
import Simulation.Aivika.Statistics

-- | Like 'Server' it models an activity that takes @a@ and provides @b@.
-- But unlike the former this kind of activity has no state. Also it is destined
-- to be used within 'Process' computations.
data Operation a b =
  Operation { forall a b. Operation a b -> a -> Process b
operationInitProcess :: a -> Process b,
              -- ^ Provide @b@ by specified @a@.
              forall a b. Operation a b -> Bool
operationProcessPreemptible :: Bool,
              -- ^ Whether the process is preemptible.
              forall a b. Operation a b -> IORef Double
operationStartTimeRef :: IORef Double,
              -- ^ The start time of creating the operation.
              forall a b. Operation a b -> IORef Double
operationLastTimeRef :: IORef Double,
              -- ^ The last time of utilising the operation activity.
              forall a b. Operation a b -> IORef Double
operationTotalUtilisationTimeRef :: IORef Double,
              -- ^ The counted total time of utilising the activity.
              forall a b. Operation a b -> IORef Double
operationTotalPreemptionTimeRef :: IORef Double,
              -- ^ The counted total time when the activity was preempted. 
              forall a b. Operation a b -> IORef (SamplingStats Double)
operationUtilisationTimeRef :: IORef (SamplingStats Double),
              -- ^ The statistics for the utilisation time.
              forall a b. Operation a b -> IORef (SamplingStats Double)
operationPreemptionTimeRef :: IORef (SamplingStats Double),
              -- ^ The statistics for the time when the activity was preempted.
              forall a b. Operation a b -> SignalSource a
operationUtilisingSource :: SignalSource a,
              -- ^ A signal raised when starting to utilise the activity.
              forall a b. Operation a b -> SignalSource (a, b)
operationUtilisedSource :: SignalSource (a, b),
              -- ^ A signal raised when the activity has been utilised.
              forall a b. Operation a b -> SignalSource a
operationPreemptionBeginningSource :: SignalSource a,
              -- ^ A signal raised when the utilisation was preempted.
              forall a b. Operation a b -> SignalSource a
operationPreemptionEndingSource :: SignalSource a
              -- ^ A signal raised when the utilisation was proceeded after it had been preempted earlier.
           }

-- | Create a new operation that can provide output @b@ by input @a@.
--
-- By default, it is assumed that the activity utilisation cannot be preempted,
-- because the handling of possible task preemption is rather costly
-- operation.
newOperation :: (a -> Process b)
                -- ^ provide an output by the specified input
                -> Event (Operation a b)
newOperation :: forall a b. (a -> Process b) -> Event (Operation a b)
newOperation = Bool -> (a -> Process b) -> Event (Operation a b)
forall a b. Bool -> (a -> Process b) -> Event (Operation a b)
newPreemptibleOperation Bool
False

-- | Create a new operation that can provide output @b@ by input @a@.
newPreemptibleOperation :: Bool
                           -- ^ whether the activity can be preempted
                           -> (a -> Process b)
                           -- ^ provide an output by the specified input
                           -> Event (Operation a b)
newPreemptibleOperation :: forall a b. Bool -> (a -> Process b) -> Event (Operation a b)
newPreemptibleOperation Bool
preemptible a -> Process b
provide =
  do Double
t0 <- Dynamics Double -> Event Double
forall a. Dynamics a -> Event a
forall (m :: * -> *) a. DynamicsLift m => Dynamics a -> m a
liftDynamics Dynamics Double
time
     IORef Double
r' <- IO (IORef Double) -> Event (IORef Double)
forall a. IO a -> Event a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef Double) -> Event (IORef Double))
-> IO (IORef Double) -> Event (IORef Double)
forall a b. (a -> b) -> a -> b
$ Double -> IO (IORef Double)
forall a. a -> IO (IORef a)
newIORef Double
t0
     IORef Double
r0 <- IO (IORef Double) -> Event (IORef Double)
forall a. IO a -> Event a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef Double) -> Event (IORef Double))
-> IO (IORef Double) -> Event (IORef Double)
forall a b. (a -> b) -> a -> b
$ Double -> IO (IORef Double)
forall a. a -> IO (IORef a)
newIORef Double
t0
     IORef Double
r1 <- IO (IORef Double) -> Event (IORef Double)
forall a. IO a -> Event a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef Double) -> Event (IORef Double))
-> IO (IORef Double) -> Event (IORef Double)
forall a b. (a -> b) -> a -> b
$ Double -> IO (IORef Double)
forall a. a -> IO (IORef a)
newIORef Double
0
     IORef Double
r2 <- IO (IORef Double) -> Event (IORef Double)
forall a. IO a -> Event a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef Double) -> Event (IORef Double))
-> IO (IORef Double) -> Event (IORef Double)
forall a b. (a -> b) -> a -> b
$ Double -> IO (IORef Double)
forall a. a -> IO (IORef a)
newIORef Double
0
     IORef (SamplingStats Double)
r3 <- IO (IORef (SamplingStats Double))
-> Event (IORef (SamplingStats Double))
forall a. IO a -> Event a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (SamplingStats Double))
 -> Event (IORef (SamplingStats Double)))
-> IO (IORef (SamplingStats Double))
-> Event (IORef (SamplingStats Double))
forall a b. (a -> b) -> a -> b
$ SamplingStats Double -> IO (IORef (SamplingStats Double))
forall a. a -> IO (IORef a)
newIORef SamplingStats Double
forall a. SamplingData a => SamplingStats a
emptySamplingStats
     IORef (SamplingStats Double)
r4 <- IO (IORef (SamplingStats Double))
-> Event (IORef (SamplingStats Double))
forall a. IO a -> Event a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (SamplingStats Double))
 -> Event (IORef (SamplingStats Double)))
-> IO (IORef (SamplingStats Double))
-> Event (IORef (SamplingStats Double))
forall a b. (a -> b) -> a -> b
$ SamplingStats Double -> IO (IORef (SamplingStats Double))
forall a. a -> IO (IORef a)
newIORef SamplingStats Double
forall a. SamplingData a => SamplingStats a
emptySamplingStats
     SignalSource a
s1 <- Simulation (SignalSource a) -> Event (SignalSource a)
forall a. Simulation a -> Event a
forall (m :: * -> *) a. SimulationLift m => Simulation a -> m a
liftSimulation Simulation (SignalSource a)
forall a. Simulation (SignalSource a)
newSignalSource
     SignalSource (a, b)
s2 <- Simulation (SignalSource (a, b)) -> Event (SignalSource (a, b))
forall a. Simulation a -> Event a
forall (m :: * -> *) a. SimulationLift m => Simulation a -> m a
liftSimulation Simulation (SignalSource (a, b))
forall a. Simulation (SignalSource a)
newSignalSource
     SignalSource a
s3 <- Simulation (SignalSource a) -> Event (SignalSource a)
forall a. Simulation a -> Event a
forall (m :: * -> *) a. SimulationLift m => Simulation a -> m a
liftSimulation Simulation (SignalSource a)
forall a. Simulation (SignalSource a)
newSignalSource
     SignalSource a
s4 <- Simulation (SignalSource a) -> Event (SignalSource a)
forall a. Simulation a -> Event a
forall (m :: * -> *) a. SimulationLift m => Simulation a -> m a
liftSimulation Simulation (SignalSource a)
forall a. Simulation (SignalSource a)
newSignalSource
     Operation a b -> Event (Operation a b)
forall a. a -> Event a
forall (m :: * -> *) a. Monad m => a -> m a
return Operation { operationInitProcess :: a -> Process b
operationInitProcess = a -> Process b
provide,
                        operationProcessPreemptible :: Bool
operationProcessPreemptible = Bool
preemptible,
                        operationStartTimeRef :: IORef Double
operationStartTimeRef = IORef Double
r',
                        operationLastTimeRef :: IORef Double
operationLastTimeRef = IORef Double
r0,
                        operationTotalUtilisationTimeRef :: IORef Double
operationTotalUtilisationTimeRef = IORef Double
r1,
                        operationTotalPreemptionTimeRef :: IORef Double
operationTotalPreemptionTimeRef = IORef Double
r2,
                        operationUtilisationTimeRef :: IORef (SamplingStats Double)
operationUtilisationTimeRef = IORef (SamplingStats Double)
r3,
                        operationPreemptionTimeRef :: IORef (SamplingStats Double)
operationPreemptionTimeRef = IORef (SamplingStats Double)
r4,
                        operationUtilisingSource :: SignalSource a
operationUtilisingSource = SignalSource a
s1,
                        operationUtilisedSource :: SignalSource (a, b)
operationUtilisedSource = SignalSource (a, b)
s2,
                        operationPreemptionBeginningSource :: SignalSource a
operationPreemptionBeginningSource = SignalSource a
s3,
                        operationPreemptionEndingSource :: SignalSource a
operationPreemptionEndingSource = SignalSource a
s4 }

-- | Return a computation for the specified operation. It updates internal counters.
--
-- The computation can be used only within one process at any time.
operationProcess :: Operation a b -> a -> Process b
operationProcess :: forall a b. Operation a b -> a -> Process b
operationProcess Operation a b
op a
a =
  do Double
t0 <- Dynamics Double -> Process Double
forall a. Dynamics a -> Process a
forall (m :: * -> *) a. DynamicsLift m => Dynamics a -> m a
liftDynamics Dynamics Double
time
     Event () -> Process ()
forall a. Event a -> Process a
forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent (Event () -> Process ()) -> Event () -> Process ()
forall a b. (a -> b) -> a -> b
$
       SignalSource a -> a -> Event ()
forall a. SignalSource a -> a -> Event ()
triggerSignal (Operation a b -> SignalSource a
forall a b. Operation a b -> SignalSource a
operationUtilisingSource Operation a b
op) a
a
     -- utilise the activity
     (b
b, Double
dt) <- if Operation a b -> Bool
forall a b. Operation a b -> Bool
operationProcessPreemptible Operation a b
op
                then Operation a b -> a -> Process (b, Double)
forall a b. Operation a b -> a -> Process (b, Double)
operationProcessPreempting Operation a b
op a
a
                else do b
b <- Operation a b -> a -> Process b
forall a b. Operation a b -> a -> Process b
operationInitProcess Operation a b
op a
a
                        (b, Double) -> Process (b, Double)
forall a. a -> Process a
forall (m :: * -> *) a. Monad m => a -> m a
return (b
b, Double
0)
     Double
t1 <- Dynamics Double -> Process Double
forall a. Dynamics a -> Process a
forall (m :: * -> *) a. DynamicsLift m => Dynamics a -> m a
liftDynamics Dynamics Double
time
     Event () -> Process ()
forall a. Event a -> Process a
forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent (Event () -> Process ()) -> Event () -> Process ()
forall a b. (a -> b) -> a -> b
$
       do IO () -> Event ()
forall a. IO a -> Event a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Event ()) -> IO () -> Event ()
forall a b. (a -> b) -> a -> b
$
            do IORef Double -> (Double -> Double) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationTotalUtilisationTimeRef Operation a b
op) (Double -> Double -> Double
forall a. Num a => a -> a -> a
+ (Double
t1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
t0 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
dt))
               IORef (SamplingStats Double)
-> (SamplingStats Double -> SamplingStats Double) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' (Operation a b -> IORef (SamplingStats Double)
forall a b. Operation a b -> IORef (SamplingStats Double)
operationUtilisationTimeRef Operation a b
op) ((SamplingStats Double -> SamplingStats Double) -> IO ())
-> (SamplingStats Double -> SamplingStats Double) -> IO ()
forall a b. (a -> b) -> a -> b
$
                 Double -> SamplingStats Double -> SamplingStats Double
forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats (Double
t1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
t0 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
dt)
               IORef Double -> Double -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationLastTimeRef Operation a b
op) Double
t1
          SignalSource (a, b) -> (a, b) -> Event ()
forall a. SignalSource a -> a -> Event ()
triggerSignal (Operation a b -> SignalSource (a, b)
forall a b. Operation a b -> SignalSource (a, b)
operationUtilisedSource Operation a b
op) (a
a, b
b)
     b -> Process b
forall a. a -> Process a
forall (m :: * -> *) a. Monad m => a -> m a
return b
b

-- | Process the input with ability to handle a possible preemption.
operationProcessPreempting :: Operation a b -> a -> Process (b, Double)
operationProcessPreempting :: forall a b. Operation a b -> a -> Process (b, Double)
operationProcessPreempting Operation a b
op a
a =
  do ProcessId
pid <- Process ProcessId
processId
     Double
t0  <- Dynamics Double -> Process Double
forall a. Dynamics a -> Process a
forall (m :: * -> *) a. DynamicsLift m => Dynamics a -> m a
liftDynamics Dynamics Double
time
     IORef Double
rs  <- IO (IORef Double) -> Process (IORef Double)
forall a. IO a -> Process a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef Double) -> Process (IORef Double))
-> IO (IORef Double) -> Process (IORef Double)
forall a b. (a -> b) -> a -> b
$ Double -> IO (IORef Double)
forall a. a -> IO (IORef a)
newIORef Double
0
     IORef Double
r0  <- IO (IORef Double) -> Process (IORef Double)
forall a. IO a -> Process a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef Double) -> Process (IORef Double))
-> IO (IORef Double) -> Process (IORef Double)
forall a b. (a -> b) -> a -> b
$ Double -> IO (IORef Double)
forall a. a -> IO (IORef a)
newIORef Double
t0
     DisposableEvent
h1  <- Event DisposableEvent -> Process DisposableEvent
forall a. Event a -> Process a
forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent (Event DisposableEvent -> Process DisposableEvent)
-> Event DisposableEvent -> Process DisposableEvent
forall a b. (a -> b) -> a -> b
$
            Signal () -> (() -> Event ()) -> Event DisposableEvent
forall a. Signal a -> (a -> Event ()) -> Event DisposableEvent
handleSignal (ProcessId -> Signal ()
processPreemptionBeginning ProcessId
pid) ((() -> Event ()) -> Event DisposableEvent)
-> (() -> Event ()) -> Event DisposableEvent
forall a b. (a -> b) -> a -> b
$ \() ->
            do Double
t0 <- Dynamics Double -> Event Double
forall a. Dynamics a -> Event a
forall (m :: * -> *) a. DynamicsLift m => Dynamics a -> m a
liftDynamics Dynamics Double
time
               IO () -> Event ()
forall a. IO a -> Event a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Event ()) -> IO () -> Event ()
forall a b. (a -> b) -> a -> b
$ IORef Double -> Double -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef Double
r0 Double
t0
               SignalSource a -> a -> Event ()
forall a. SignalSource a -> a -> Event ()
triggerSignal (Operation a b -> SignalSource a
forall a b. Operation a b -> SignalSource a
operationPreemptionBeginningSource Operation a b
op) a
a
     DisposableEvent
h2  <- Event DisposableEvent -> Process DisposableEvent
forall a. Event a -> Process a
forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent (Event DisposableEvent -> Process DisposableEvent)
-> Event DisposableEvent -> Process DisposableEvent
forall a b. (a -> b) -> a -> b
$
            Signal () -> (() -> Event ()) -> Event DisposableEvent
forall a. Signal a -> (a -> Event ()) -> Event DisposableEvent
handleSignal (ProcessId -> Signal ()
processPreemptionEnding ProcessId
pid) ((() -> Event ()) -> Event DisposableEvent)
-> (() -> Event ()) -> Event DisposableEvent
forall a b. (a -> b) -> a -> b
$ \() ->
            do Double
t0 <- IO Double -> Event Double
forall a. IO a -> Event a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Double -> Event Double) -> IO Double -> Event Double
forall a b. (a -> b) -> a -> b
$ IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef IORef Double
r0
               Double
t1 <- Dynamics Double -> Event Double
forall a. Dynamics a -> Event a
forall (m :: * -> *) a. DynamicsLift m => Dynamics a -> m a
liftDynamics Dynamics Double
time
               let dt :: Double
dt = Double
t1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
t0
               IO () -> Event ()
forall a. IO a -> Event a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Event ()) -> IO () -> Event ()
forall a b. (a -> b) -> a -> b
$
                 do IORef Double -> (Double -> Double) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef Double
rs (Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
dt)
                    IORef Double -> (Double -> Double) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationTotalPreemptionTimeRef Operation a b
op) (Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
dt)
                    IORef (SamplingStats Double)
-> (SamplingStats Double -> SamplingStats Double) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' (Operation a b -> IORef (SamplingStats Double)
forall a b. Operation a b -> IORef (SamplingStats Double)
operationPreemptionTimeRef Operation a b
op) ((SamplingStats Double -> SamplingStats Double) -> IO ())
-> (SamplingStats Double -> SamplingStats Double) -> IO ()
forall a b. (a -> b) -> a -> b
$
                      Double -> SamplingStats Double -> SamplingStats Double
forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats Double
dt
                    IORef Double -> Double -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationLastTimeRef Operation a b
op) Double
t1
               SignalSource a -> a -> Event ()
forall a. SignalSource a -> a -> Event ()
triggerSignal (Operation a b -> SignalSource a
forall a b. Operation a b -> SignalSource a
operationPreemptionEndingSource Operation a b
op) a
a 
     let m1 :: Process (b, Double)
m1 =
           do b
b <- Operation a b -> a -> Process b
forall a b. Operation a b -> a -> Process b
operationInitProcess Operation a b
op a
a
              Double
dt <- IO Double -> Process Double
forall a. IO a -> Process a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Double -> Process Double) -> IO Double -> Process Double
forall a b. (a -> b) -> a -> b
$ IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef IORef Double
rs
              (b, Double) -> Process (b, Double)
forall a. a -> Process a
forall (m :: * -> *) a. Monad m => a -> m a
return (b
b, Double
dt)
         m2 :: Process ()
m2 =
           Event () -> Process ()
forall a. Event a -> Process a
forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent (Event () -> Process ()) -> Event () -> Process ()
forall a b. (a -> b) -> a -> b
$
           do DisposableEvent -> Event ()
disposeEvent DisposableEvent
h1
              DisposableEvent -> Event ()
disposeEvent DisposableEvent
h2
     Process (b, Double) -> Process () -> Process (b, Double)
forall a b. Process a -> Process b -> Process a
finallyProcess Process (b, Double)
m1 Process ()
m2

-- | Return the counted total time when the operation activity was utilised.
--
-- The value returned changes discretely and it is usually delayed relative
-- to the current simulation time.
--
-- See also 'operationTotalUtilisationTimeChanged' and 'operationTotalUtilisationTimeChanged_'.
operationTotalUtilisationTime :: Operation a b -> Event Double
operationTotalUtilisationTime :: forall a b. Operation a b -> Event Double
operationTotalUtilisationTime Operation a b
op =
  (Point -> IO Double) -> Event Double
forall a. (Point -> IO a) -> Event a
Event ((Point -> IO Double) -> Event Double)
-> (Point -> IO Double) -> Event Double
forall a b. (a -> b) -> a -> b
$ \Point
p -> IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationTotalUtilisationTimeRef Operation a b
op)
  
-- | Signal when the 'operationTotalUtilisationTime' property value has changed.
operationTotalUtilisationTimeChanged :: Operation a b -> Signal Double
operationTotalUtilisationTimeChanged :: forall a b. Operation a b -> Signal Double
operationTotalUtilisationTimeChanged Operation a b
op =
  (() -> Event Double) -> Signal () -> Signal Double
forall a b. (a -> Event b) -> Signal a -> Signal b
mapSignalM (Event Double -> () -> Event Double
forall a b. a -> b -> a
const (Event Double -> () -> Event Double)
-> Event Double -> () -> Event Double
forall a b. (a -> b) -> a -> b
$ Operation a b -> Event Double
forall a b. Operation a b -> Event Double
operationTotalUtilisationTime Operation a b
op) (Operation a b -> Signal ()
forall a b. Operation a b -> Signal ()
operationTotalUtilisationTimeChanged_ Operation a b
op)
  
-- | Signal when the 'operationTotalUtilisationTime' property value has changed.
operationTotalUtilisationTimeChanged_ :: Operation a b -> Signal ()
operationTotalUtilisationTimeChanged_ :: forall a b. Operation a b -> Signal ()
operationTotalUtilisationTimeChanged_ Operation a b
op =
  ((a, b) -> ()) -> Signal (a, b) -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (() -> (a, b) -> ()
forall a b. a -> b -> a
const ()) (Operation a b -> Signal (a, b)
forall a b. Operation a b -> Signal (a, b)
operationUtilised Operation a b
op)

-- | Return the counted total time when the operation activity was preemted waiting for
-- the further proceeding.
--
-- The value returned changes discretely and it is usually delayed relative
-- to the current simulation time.
--
-- See also 'operationTotalPreemptionTimeChanged' and 'operationTotalPreemptionTimeChanged_'.
operationTotalPreemptionTime :: Operation a b -> Event Double
operationTotalPreemptionTime :: forall a b. Operation a b -> Event Double
operationTotalPreemptionTime Operation a b
op =
  (Point -> IO Double) -> Event Double
forall a. (Point -> IO a) -> Event a
Event ((Point -> IO Double) -> Event Double)
-> (Point -> IO Double) -> Event Double
forall a b. (a -> b) -> a -> b
$ \Point
p -> IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationTotalPreemptionTimeRef Operation a b
op)
  
-- | Signal when the 'operationTotalPreemptionTime' property value has changed.
operationTotalPreemptionTimeChanged :: Operation a b -> Signal Double
operationTotalPreemptionTimeChanged :: forall a b. Operation a b -> Signal Double
operationTotalPreemptionTimeChanged Operation a b
op =
  (() -> Event Double) -> Signal () -> Signal Double
forall a b. (a -> Event b) -> Signal a -> Signal b
mapSignalM (Event Double -> () -> Event Double
forall a b. a -> b -> a
const (Event Double -> () -> Event Double)
-> Event Double -> () -> Event Double
forall a b. (a -> b) -> a -> b
$ Operation a b -> Event Double
forall a b. Operation a b -> Event Double
operationTotalPreemptionTime Operation a b
op) (Operation a b -> Signal ()
forall a b. Operation a b -> Signal ()
operationTotalPreemptionTimeChanged_ Operation a b
op)
  
-- | Signal when the 'operationTotalPreemptionTime' property value has changed.
operationTotalPreemptionTimeChanged_ :: Operation a b -> Signal ()
operationTotalPreemptionTimeChanged_ :: forall a b. Operation a b -> Signal ()
operationTotalPreemptionTimeChanged_ Operation a b
op =
  (a -> ()) -> Signal a -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (() -> a -> ()
forall a b. a -> b -> a
const ()) (Operation a b -> Signal a
forall a b. Operation a b -> Signal a
operationPreemptionEnding Operation a b
op)

-- | Return the statistics for the time when the operation activity was utilised.
--
-- The value returned changes discretely and it is usually delayed relative
-- to the current simulation time.
--
-- See also 'operationUtilisationTimeChanged' and 'operationUtilisationTimeChanged_'.
operationUtilisationTime :: Operation a b -> Event (SamplingStats Double)
operationUtilisationTime :: forall a b. Operation a b -> Event (SamplingStats Double)
operationUtilisationTime Operation a b
op =
  (Point -> IO (SamplingStats Double))
-> Event (SamplingStats Double)
forall a. (Point -> IO a) -> Event a
Event ((Point -> IO (SamplingStats Double))
 -> Event (SamplingStats Double))
-> (Point -> IO (SamplingStats Double))
-> Event (SamplingStats Double)
forall a b. (a -> b) -> a -> b
$ \Point
p -> IORef (SamplingStats Double) -> IO (SamplingStats Double)
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef (SamplingStats Double)
forall a b. Operation a b -> IORef (SamplingStats Double)
operationUtilisationTimeRef Operation a b
op)
  
-- | Signal when the 'operationUtilisationTime' property value has changed.
operationUtilisationTimeChanged :: Operation a b -> Signal (SamplingStats Double)
operationUtilisationTimeChanged :: forall a b. Operation a b -> Signal (SamplingStats Double)
operationUtilisationTimeChanged Operation a b
op =
  (() -> Event (SamplingStats Double))
-> Signal () -> Signal (SamplingStats Double)
forall a b. (a -> Event b) -> Signal a -> Signal b
mapSignalM (Event (SamplingStats Double) -> () -> Event (SamplingStats Double)
forall a b. a -> b -> a
const (Event (SamplingStats Double)
 -> () -> Event (SamplingStats Double))
-> Event (SamplingStats Double)
-> ()
-> Event (SamplingStats Double)
forall a b. (a -> b) -> a -> b
$ Operation a b -> Event (SamplingStats Double)
forall a b. Operation a b -> Event (SamplingStats Double)
operationUtilisationTime Operation a b
op) (Operation a b -> Signal ()
forall a b. Operation a b -> Signal ()
operationUtilisationTimeChanged_ Operation a b
op)
  
-- | Signal when the 'operationUtilisationTime' property value has changed.
operationUtilisationTimeChanged_ :: Operation a b -> Signal ()
operationUtilisationTimeChanged_ :: forall a b. Operation a b -> Signal ()
operationUtilisationTimeChanged_ Operation a b
op =
  ((a, b) -> ()) -> Signal (a, b) -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (() -> (a, b) -> ()
forall a b. a -> b -> a
const ()) (Operation a b -> Signal (a, b)
forall a b. Operation a b -> Signal (a, b)
operationUtilised Operation a b
op)

-- | Return the statistics for the time when the operation activity was preempted
-- waiting for the further proceeding.
--
-- The value returned changes discretely and it is usually delayed relative
-- to the current simulation time.
--
-- See also 'operationPreemptionTimeChanged' and 'operationPreemptionTimeChanged_'.
operationPreemptionTime :: Operation a b -> Event (SamplingStats Double)
operationPreemptionTime :: forall a b. Operation a b -> Event (SamplingStats Double)
operationPreemptionTime Operation a b
op =
  (Point -> IO (SamplingStats Double))
-> Event (SamplingStats Double)
forall a. (Point -> IO a) -> Event a
Event ((Point -> IO (SamplingStats Double))
 -> Event (SamplingStats Double))
-> (Point -> IO (SamplingStats Double))
-> Event (SamplingStats Double)
forall a b. (a -> b) -> a -> b
$ \Point
p -> IORef (SamplingStats Double) -> IO (SamplingStats Double)
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef (SamplingStats Double)
forall a b. Operation a b -> IORef (SamplingStats Double)
operationPreemptionTimeRef Operation a b
op)
  
-- | Signal when the 'operationPreemptionTime' property value has changed.
operationPreemptionTimeChanged :: Operation a b -> Signal (SamplingStats Double)
operationPreemptionTimeChanged :: forall a b. Operation a b -> Signal (SamplingStats Double)
operationPreemptionTimeChanged Operation a b
op =
  (() -> Event (SamplingStats Double))
-> Signal () -> Signal (SamplingStats Double)
forall a b. (a -> Event b) -> Signal a -> Signal b
mapSignalM (Event (SamplingStats Double) -> () -> Event (SamplingStats Double)
forall a b. a -> b -> a
const (Event (SamplingStats Double)
 -> () -> Event (SamplingStats Double))
-> Event (SamplingStats Double)
-> ()
-> Event (SamplingStats Double)
forall a b. (a -> b) -> a -> b
$ Operation a b -> Event (SamplingStats Double)
forall a b. Operation a b -> Event (SamplingStats Double)
operationPreemptionTime Operation a b
op) (Operation a b -> Signal ()
forall a b. Operation a b -> Signal ()
operationPreemptionTimeChanged_ Operation a b
op)
  
-- | Signal when the 'operationPreemptionTime' property value has changed.
operationPreemptionTimeChanged_ :: Operation a b -> Signal ()
operationPreemptionTimeChanged_ :: forall a b. Operation a b -> Signal ()
operationPreemptionTimeChanged_ Operation a b
op =
  (a -> ()) -> Signal a -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (() -> a -> ()
forall a b. a -> b -> a
const ()) (Operation a b -> Signal a
forall a b. Operation a b -> Signal a
operationPreemptionEnding Operation a b
op)
  
-- | It returns the factor changing from 0 to 1, which estimates how often
-- the operation activity was utilised since the time of creating the operation.
--
-- The value returned changes discretely and it is usually delayed relative
-- to the current simulation time.
--
-- See also 'operationUtilisationFactorChanged' and 'operationUtilisationFactorChanged_'.
operationUtilisationFactor :: Operation a b -> Event Double
operationUtilisationFactor :: forall a b. Operation a b -> Event Double
operationUtilisationFactor Operation a b
op =
  (Point -> IO Double) -> Event Double
forall a. (Point -> IO a) -> Event a
Event ((Point -> IO Double) -> Event Double)
-> (Point -> IO Double) -> Event Double
forall a b. (a -> b) -> a -> b
$ \Point
p ->
  do Double
t0 <- IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationStartTimeRef Operation a b
op)
     Double
t1 <- IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationLastTimeRef Operation a b
op)
     Double
x  <- IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationTotalUtilisationTimeRef Operation a b
op)
     Double -> IO Double
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
t1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
t0))
  
-- | Signal when the 'operationUtilisationFactor' property value has changed.
operationUtilisationFactorChanged :: Operation a b -> Signal Double
operationUtilisationFactorChanged :: forall a b. Operation a b -> Signal Double
operationUtilisationFactorChanged Operation a b
op =
  (() -> Event Double) -> Signal () -> Signal Double
forall a b. (a -> Event b) -> Signal a -> Signal b
mapSignalM (Event Double -> () -> Event Double
forall a b. a -> b -> a
const (Event Double -> () -> Event Double)
-> Event Double -> () -> Event Double
forall a b. (a -> b) -> a -> b
$ Operation a b -> Event Double
forall a b. Operation a b -> Event Double
operationUtilisationFactor Operation a b
op) (Operation a b -> Signal ()
forall a b. Operation a b -> Signal ()
operationUtilisationFactorChanged_ Operation a b
op)
  
-- | Signal when the 'operationUtilisationFactor' property value has changed.
operationUtilisationFactorChanged_ :: Operation a b -> Signal ()
operationUtilisationFactorChanged_ :: forall a b. Operation a b -> Signal ()
operationUtilisationFactorChanged_ Operation a b
op =
  ((a, b) -> ()) -> Signal (a, b) -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (() -> (a, b) -> ()
forall a b. a -> b -> a
const ()) (Operation a b -> Signal (a, b)
forall a b. Operation a b -> Signal (a, b)
operationUtilised Operation a b
op) Signal () -> Signal () -> Signal ()
forall a. Semigroup a => a -> a -> a
<>
  (a -> ()) -> Signal a -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (() -> a -> ()
forall a b. a -> b -> a
const ()) (Operation a b -> Signal a
forall a b. Operation a b -> Signal a
operationPreemptionEnding Operation a b
op)
  
-- | It returns the factor changing from 0 to 1, which estimates how often
-- the operation activity was preempted waiting for the further proceeding
-- since the time of creating the operation.
--
-- The value returned changes discretely and it is usually delayed relative
-- to the current simulation time.
--
-- See also 'operationPreemptionFactorChanged' and 'operationPreemptionFactorChanged_'.
operationPreemptionFactor :: Operation a b -> Event Double
operationPreemptionFactor :: forall a b. Operation a b -> Event Double
operationPreemptionFactor Operation a b
op =
  (Point -> IO Double) -> Event Double
forall a. (Point -> IO a) -> Event a
Event ((Point -> IO Double) -> Event Double)
-> (Point -> IO Double) -> Event Double
forall a b. (a -> b) -> a -> b
$ \Point
p ->
  do Double
t0 <- IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationStartTimeRef Operation a b
op)
     Double
t1 <- IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationLastTimeRef Operation a b
op)
     Double
x  <- IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationTotalPreemptionTimeRef Operation a b
op)
     Double -> IO Double
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
t1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
t0))
  
-- | Signal when the 'operationPreemptionFactor' property value has changed.
operationPreemptionFactorChanged :: Operation a b -> Signal Double
operationPreemptionFactorChanged :: forall a b. Operation a b -> Signal Double
operationPreemptionFactorChanged Operation a b
op =
  (() -> Event Double) -> Signal () -> Signal Double
forall a b. (a -> Event b) -> Signal a -> Signal b
mapSignalM (Event Double -> () -> Event Double
forall a b. a -> b -> a
const (Event Double -> () -> Event Double)
-> Event Double -> () -> Event Double
forall a b. (a -> b) -> a -> b
$ Operation a b -> Event Double
forall a b. Operation a b -> Event Double
operationPreemptionFactor Operation a b
op) (Operation a b -> Signal ()
forall a b. Operation a b -> Signal ()
operationPreemptionFactorChanged_ Operation a b
op)
  
-- | Signal when the 'operationPreemptionFactor' property value has changed.
operationPreemptionFactorChanged_ :: Operation a b -> Signal ()
operationPreemptionFactorChanged_ :: forall a b. Operation a b -> Signal ()
operationPreemptionFactorChanged_ Operation a b
op =
  ((a, b) -> ()) -> Signal (a, b) -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (() -> (a, b) -> ()
forall a b. a -> b -> a
const ()) (Operation a b -> Signal (a, b)
forall a b. Operation a b -> Signal (a, b)
operationUtilised Operation a b
op) Signal () -> Signal () -> Signal ()
forall a. Semigroup a => a -> a -> a
<>
  (a -> ()) -> Signal a -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (() -> a -> ()
forall a b. a -> b -> a
const ()) (Operation a b -> Signal a
forall a b. Operation a b -> Signal a
operationPreemptionEnding Operation a b
op)
  
-- | Raised when starting to utilise the operation activity after a new input task is received.
operationUtilising :: Operation a b -> Signal a
operationUtilising :: forall a b. Operation a b -> Signal a
operationUtilising = SignalSource a -> Signal a
forall a. SignalSource a -> Signal a
publishSignal (SignalSource a -> Signal a)
-> (Operation a b -> SignalSource a) -> Operation a b -> Signal a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Operation a b -> SignalSource a
forall a b. Operation a b -> SignalSource a
operationUtilisingSource

-- | Raised when the operation activity has been utilised after the current task is processed.
operationUtilised :: Operation a b -> Signal (a, b)
operationUtilised :: forall a b. Operation a b -> Signal (a, b)
operationUtilised = SignalSource (a, b) -> Signal (a, b)
forall a. SignalSource a -> Signal a
publishSignal (SignalSource (a, b) -> Signal (a, b))
-> (Operation a b -> SignalSource (a, b))
-> Operation a b
-> Signal (a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Operation a b -> SignalSource (a, b)
forall a b. Operation a b -> SignalSource (a, b)
operationUtilisedSource

-- | Raised when the operation activity utilisation was preempted.
operationPreemptionBeginning :: Operation a b -> Signal a
operationPreemptionBeginning :: forall a b. Operation a b -> Signal a
operationPreemptionBeginning = SignalSource a -> Signal a
forall a. SignalSource a -> Signal a
publishSignal (SignalSource a -> Signal a)
-> (Operation a b -> SignalSource a) -> Operation a b -> Signal a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Operation a b -> SignalSource a
forall a b. Operation a b -> SignalSource a
operationPreemptionBeginningSource

-- | Raised when the operation activity utilisation was proceeded after it had been preempted earlier.
operationPreemptionEnding :: Operation a b -> Signal a
operationPreemptionEnding :: forall a b. Operation a b -> Signal a
operationPreemptionEnding = SignalSource a -> Signal a
forall a. SignalSource a -> Signal a
publishSignal (SignalSource a -> Signal a)
-> (Operation a b -> SignalSource a) -> Operation a b -> Signal a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Operation a b -> SignalSource a
forall a b. Operation a b -> SignalSource a
operationPreemptionEndingSource

-- | Signal whenever any property of the operation changes.
operationChanged_ :: Operation a b -> Signal ()
operationChanged_ :: forall a b. Operation a b -> Signal ()
operationChanged_ Operation a b
op =
  (a -> ()) -> Signal a -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (() -> a -> ()
forall a b. a -> b -> a
const ()) (Operation a b -> Signal a
forall a b. Operation a b -> Signal a
operationUtilising Operation a b
op) Signal () -> Signal () -> Signal ()
forall a. Semigroup a => a -> a -> a
<>
  ((a, b) -> ()) -> Signal (a, b) -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (() -> (a, b) -> ()
forall a b. a -> b -> a
const ()) (Operation a b -> Signal (a, b)
forall a b. Operation a b -> Signal (a, b)
operationUtilised Operation a b
op) Signal () -> Signal () -> Signal ()
forall a. Semigroup a => a -> a -> a
<>
  (a -> ()) -> Signal a -> Signal ()
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (() -> a -> ()
forall a b. a -> b -> a
const ()) (Operation a b -> Signal a
forall a b. Operation a b -> Signal a
operationPreemptionEnding Operation a b
op)

-- | Return the summary for the operation with desciption of its
-- properties using the specified indent.
operationSummary :: Operation a b -> Int -> Event ShowS
operationSummary :: forall a b. Operation a b -> Int -> Event ShowS
operationSummary Operation a b
op Int
indent =
  (Point -> IO ShowS) -> Event ShowS
forall a. (Point -> IO a) -> Event a
Event ((Point -> IO ShowS) -> Event ShowS)
-> (Point -> IO ShowS) -> Event ShowS
forall a b. (a -> b) -> a -> b
$ \Point
p ->
  do Double
t0  <- IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationStartTimeRef Operation a b
op)
     Double
t1  <- IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationLastTimeRef Operation a b
op)
     Double
tx1 <- IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationTotalUtilisationTimeRef Operation a b
op)
     Double
tx2 <- IORef Double -> IO Double
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationTotalPreemptionTimeRef Operation a b
op)
     let xf1 :: Double
xf1 = Double
tx1 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
t1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
t0)
         xf2 :: Double
xf2 = Double
tx2 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
t1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
t0)
     SamplingStats Double
xs1 <- IORef (SamplingStats Double) -> IO (SamplingStats Double)
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef (SamplingStats Double)
forall a b. Operation a b -> IORef (SamplingStats Double)
operationUtilisationTimeRef Operation a b
op)
     SamplingStats Double
xs2 <- IORef (SamplingStats Double) -> IO (SamplingStats Double)
forall a. IORef a -> IO a
readIORef (Operation a b -> IORef (SamplingStats Double)
forall a b. Operation a b -> IORef (SamplingStats Double)
operationPreemptionTimeRef Operation a b
op)
     let tab :: [Char]
tab = Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate Int
indent Char
' '
     ShowS -> IO ShowS
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ShowS -> IO ShowS) -> ShowS -> IO ShowS
forall a b. (a -> b) -> a -> b
$
       [Char] -> ShowS
showString [Char]
tab ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
"total utilisation time = " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> ShowS
forall a. Show a => a -> ShowS
shows Double
tx1 ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
"\n" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
tab ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
"total preemption time = " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> ShowS
forall a. Show a => a -> ShowS
shows Double
tx2 ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
"\n" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
tab ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
"utilisation factor (from 0 to 1) = " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> ShowS
forall a. Show a => a -> ShowS
shows Double
xf1 ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
"\n" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
tab ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
"preemption factor (from 0 to 1) = " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> ShowS
forall a. Show a => a -> ShowS
shows Double
xf2 ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
"\n" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
tab ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
"utilisation time:\n\n" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       SamplingStats Double -> Int -> ShowS
forall a. Show a => SamplingStats a -> Int -> ShowS
samplingStatsSummary SamplingStats Double
xs1 (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
indent) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
"\n\n" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
tab ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       [Char] -> ShowS
showString [Char]
"preemption time:\n\n" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
       SamplingStats Double -> Int -> ShowS
forall a. Show a => SamplingStats a -> Int -> ShowS
samplingStatsSummary SamplingStats Double
xs2 (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
indent)

-- | Reset the statistics.
resetOperation :: Operation a b -> Event ()
resetOperation :: forall a b. Operation a b -> Event ()
resetOperation Operation a b
op =
  (Point -> IO ()) -> Event ()
forall a. (Point -> IO a) -> Event a
Event ((Point -> IO ()) -> Event ()) -> (Point -> IO ()) -> Event ()
forall a b. (a -> b) -> a -> b
$ \Point
p ->
  do let t0 :: Double
t0 = Point -> Double
pointTime Point
p
     IORef Double -> Double -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationStartTimeRef Operation a b
op) Double
t0
     IORef Double -> Double -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationLastTimeRef Operation a b
op) Double
t0
     IORef Double -> Double -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationTotalUtilisationTimeRef Operation a b
op) Double
0
     IORef Double -> Double -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Operation a b -> IORef Double
forall a b. Operation a b -> IORef Double
operationTotalPreemptionTimeRef Operation a b
op) Double
0
     IORef (SamplingStats Double) -> SamplingStats Double -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Operation a b -> IORef (SamplingStats Double)
forall a b. Operation a b -> IORef (SamplingStats Double)
operationUtilisationTimeRef Operation a b
op) SamplingStats Double
forall a. SamplingData a => SamplingStats a
emptySamplingStats
     IORef (SamplingStats Double) -> SamplingStats Double -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (Operation a b -> IORef (SamplingStats Double)
forall a b. Operation a b -> IORef (SamplingStats Double)
operationPreemptionTimeRef Operation a b
op) SamplingStats Double
forall a. SamplingData a => SamplingStats a
emptySamplingStats