%% $Id: mc.tex,v 1.11 2004/11/03 14:39:36 gokhale Exp $

\section{Performance Evaluation of the Reactor Pattern}
\label{sec:reactor_perf}

This section describes the process of constructing different performance
evaluation models for the Reactor pattern and provides analytical
performance results solving these models. Initially, a Markov 
model for the Reactor pattern is presented. Towards this end, 
we first describe the characteristics of the analytical model for the
Reactor pattern and the relevant performance measures. We then 
describe how these performance measures can be obtained 
from the Markov model by an appropriate assignment of the
reward rates. The complex (and potentially error-prone) process of
constructing a Markov model serves as a motivation for a high-level
specification mechanism of Stochastic Reward Nets (SRNs) for the
automatic generation of the Markov model. A SRN model of the Reactor
pattern is presented along with a discussion of how the performance
measures can be obtained by assigning reward rates at the net
level. We conclude the section with illustrative examples of how the
SRN model can be used to obtain an estimate of the performance metrics
as well as to analyze the sensitivity of the performance metrics 
for different configuration options. 

\subsection{Characteristics of the Reactor Pattern}
\label{sec:reactor_modeling}
This paper focusses on the analytical modeling of the Reactor
pattern. To demonstrate our techniques, we have chosen the simpler
single-threaded, {\em select}-based Reactor implementation. In our
model we consider a Reactor pattern with the following
characteristics:

\begin{itemize}\crunchlist
\item The system is modeled with two types of input events with one
      event handler for each type of event registered with the Reactor.
\item Each event type has a separate queue, which holds the incoming
      events of that type. The buffer capacity for the queue of type
      one events is denoted $N_1$ and of type two events is denoted $N_2$.
\item Event arrivals for both types of events follow a Poisson
      distribution with rates $\lambda_1$ and $\lambda_2$, while the
      service times of the events are exponentially distributed with
      rates $\mu_1$ and $\mu_2$. 
\item In a snapshot, when event handles corresponding to both event 
      types are enabled, the event corresponding to type one is 
      serviced with a priority over event handle of type two event. 
      over event
\end{itemize}

\subsection{Performance Metrics}
\label{sec:reactor_metrics}

The following performance metrics are of interest for each one of
the event types in the Reactor pattern model described in
Section~\ref{sec:reactor_modeling}: 

\begin{itemize}\crunchlist
\item {\bf Event throughput} -- which indicates the number of events 
      per unit time that can be processed by the single threaded event
      demultiplexing framework. An estimate of event throughput is 
      is important for
      applications such as telecommunications call processing.
\item {\bf Queue length} -- which indicates the number of events in 
      the event handler queue. An estimate of queue length is important
      to be able to develop appropriate scheduling
      policies for applications with real-time requirements.
\item {\bf Total number of events} -- which indicates 
      the total number of events in a system. An estimate of the 
      total number of events is important for making scheduling 
      decisions. In addition, this estimate will also determine 
      the right levels of resource provisioning required to 
      sustain system demands. 
\item {\bf Probability of event loss} -- which indicates how many events
      will have to be discarded due to lack of buffer space. This
      estimate is important particularly for safety-critical
      systems, which cannot afford to lose events. Alternately, this
      estimate also gives an estimate on the desired levels of resource
      provisioning. 
\item {\bf Response time:} -- which indicates the time taken to service
      an incoming event. This estimate is important to 

\end{itemize}

Section~\ref{sec:mrm} describes the performance analysis of the 
Reactor pattern using a Markov Reward Model. Section~\ref{sec:srn}
describes the performance analysis of the Reactor 
pattern using a Stochastic Reward Net. 

\subsection{Performance Evaluation using Markov Reward Model}
\label{sec:mrm}
In this section we describe the construction of the Markov models
for the Reactor pattern described in Section~\ref{sec:reactor} for
the characteristics and policies 
described in Section~\ref{sec:reactor_modeling}. 
To illustrate the reasoning used in the construction of the model,
we consider a simple case where the maximum buffer capacity for each
type of event is one, where $N_1=1$, and $N_2=1$.

The state of the system in this case is described by a 4-tuple 
$(i,j,k,l)$.
The first element, $i$, in the tuple represents the number of events
in the queue for the first event type; the second element, $j$,
represents the number of events in the queue of the second event type;
the third element in the tuple, $k$, represents an enabled handle
serving the first type of event; and the fourth element, $l$, represents
an enabled handle corresponding to the second type of event.  
Figure~\ref{fig:mrm} shows the Markov reward model for the Reactor
pattern when the maximum buffer capacity for each event type is assumed
to be one. 

\begin{figure}[htb]
\centerline{\epsfig{figure=eps/mrm.eps,height=3.3in}}
\caption{Markov model for the Reactor pattern}
\label{fig:mrm}
\end{figure}

The evolution of the system through a sequence of states is described
below. 
\begin{itemize}\crunchlist
\item {\bf Initial condition:} Initially, the system starts in state
      $(0,0,0,0)$, which depicts the condition that no events are
      queued and no event handles are enabled. In the initial state
      $(0,0,0,0)$, any one of the two events can occur, namely, the
      arrival of the first type of event or the arrival of the second
      type of event. 

\item {\bf Event arrivals:} Upon the occurrence of either one
      of these events described above, a snapshot is taken, and the
      incoming event is serviced. Thus, the occurrence of the first
      type of event transitions the system to state $(0,0,1,0)$
      from $(0,0,0,0)$, whereas, the occurrence of the second 
      type of event transitions the system to state $(0,0,0,1)$ 
      from state $(0,0,0,0)$. Taking a snapshot is equivalent
      to the Reactor listening for an event to be notified of the
      event and the ensuing operations of demultiplexing and
      dispatching described in Section~\ref{sec:reactor}.
      In state $(0,0,1,0)$ if an event of type one arrives 
      then it is queued and the system transitions to state $(1,0,1,0)$. 
      Similarly, the occurence of an event of type two in state 
      $(0,0,1,0)$ transitions the system to state $(0,1,1,0)$. 
      Using similar reasoning, the system can transition
      from state $(0,0,0,1)$ to state $(1,0,0,1)$ and $(0,1,0,1)$. 
      In state $(1,0,1,0)$ an incoming event of type two is queued 
      which transitions the system to state $(1,1,1,0)$. Similarly,
      in state $(0,1,1,0)$ an incoming event of type one is 
      queued which transitions the system to state $(1,1,1,0)$.  
      In state $(0,0,1,1)$, if a first type
      of event arrives, the system transitions to state $(1,0,1,1)$,
      if a second type of event arrives, the system transitions to
      state $(0,1,1,1)$. In state $(1,0,1,1)$, an arrival of second
      type of event transitions the system to state $(1,1,1,1)$.

\item {\bf Loss of events:} In state $(1,0,1,0)$ an incoming event of
      type one is lost because the buffer is full.
      Similarly, in state $(0,1,1,0)$, an incoming event of type 
      two is lost. In states $(1,1,1,0)$, $(1,1,0,1)$ and $(1,1,1,1)$
      incoming events of both types are lost. 

\item {\bf Handling priorities:}  In
      states $(0,0,1,1)$, $(1,0,1,1)$, $(0,1,1,1)$, and $(1,0,1,1)$
      the handles corresponding to both types of events are
      enabled. However, since the event of type one is serviced with a
      higher priority than the event of type two, the only service
      completion that can occur in these states is that of type one
      event. Upon the completion of service of first type of event,
      the system transitions to state $(0,0,0,1)$ from state
      $(0,0,1,1)$, to state $(1,0,0,1)$ from state $(1,0,1,1)$, to
      state $(0,1,0,1)$ from state $(0,1,1,1)$ and to state
      $(1,1,0,1)$ from state $(1,1,1,1)$. 

\item {\bf Service completions:} 
      The only event that can occur in state
      $(1,1,1,0)$ is the completion of service of first type of
      event. This marks the completion of the present snapshot and
      commencement of the next one, transitioning the system to state
      $(0,0,1,1)$. Similarly in state $(1,1,0,1)$, the completion of
      service of the second type of event transitions the system to
      state $(0,0,1,1)$.  Using similar arguments it can be seen that
      service completion from: (i)~states $(0,0,0,1)$  and $(0,0,1,0)$
      transition the system to the initial state $(0,0,0,0)$.
      (ii)~states $(1,0,1,0)$ and $(1,0,0,1)$ transition the system to
      state $(0,0,1,0)$. (iii)~states  $(0,1,1,0)$ and $(0,1,0,1)$
      transition the system to state $(0,0,0,1)$.  (iv)~state
      $(1,0,1,0)$ transition the system to state $(0,0,1,0)$ and
      (v)~state $(0,1,0,1)$ transition the system to state
      $(0,0,0,1)$. 

\end{itemize}

The Markov model presented in Figure~\ref{fig:mrm} can be solved to
obtain the probabilities of being in each one of the states using
packages, such as SHARPE~\cite{sahner}. We let $p_{i,j,k,l}$ denote the
probability of being in state $(i,j,k,l)$. Next, we describe how the
Markov reward model can be used to obtain the performance metrics
described in Section~\ref{sec:reactor_metrics} by appropriately
assigning reward rates to the states in the model.  

Let $T_1$ and $T_2$ denote the expected throughput for the first 
and second type of events respectively. $T_1$ is the rate at
which the events of type one are serviced, and is given by
$\mu_1$ times the sum of the probabilities of the states in 
which an event of type one is being serviced, namely, $k=1$.
Similarly, $T_2$ is the rate at which the events of type two
are serviced, and is given by $\mu_2$ times the sum of the 
probabilities of the states in which an event of type two is
serviced, namely, $l=1$ and $k=0$.  

The condition $k=0$ is necessary to enforce the prioritized
service provided to type one events over type two events.
$T_1$ and $T_2$ are given by Equation (\ref{eqn:tput1}) 
and (\ref{eqn:tput2}). Thus, $T_1$ can be obtained by assigning a reward
rate of $\mu_1$ to states $(i,j,k,l)$, where $k = 1$.
Similarly, $T_2$ can be obtained by assigning
the reward rate of $\mu_2$ to those states where $l = 1$ and
$k = 0$. 

\begin{eqnarray} 
T_1 & = & \mu_1*(p_{0,0,1,0} + p_{1,0,1,0} + p_{0,1,1,0} + p_{1,1,1,0}
+ \notag \\ 
    &  & p_{0,0,1,1} + p_{1,0,1,1} + p_{0,1,1,1} + p_{1,1,1,1}) 
\label{eqn:tput1}
\end{eqnarray}

\begin{equation}
T_2 = \mu_2*(p_{0,0,0,1} + p_{1,0,0,1} + p_{0,1,0,1} + p_{1,1,0,1})
\label{eqn:tput2}
\end{equation}

Let $Q_1$ and $Q_2$ denote the queue lengths for the events
of type one and two respectively. Typically, $Q_1$ is
obtained as the weighted sum of the number of events of type one
in the buffer, and the weights are given by the probability distribution
of the number of events. Similarly, $Q_2$ is obtained as the 
weighted sum of the number of events of type two in the buffer. 
Since the maximum buffer capacity
is one, $Q_1$ will be given by the sum of the probabilities of 
the states in which there is one event in the buffer of type one events,
or $i=1$. 

Similarly, $Q_2$ will be given by the sum of the probabilities of
those states in which there is one event in the queue of type two
events, or $k=1$. $Q_1$ and $Q_2$ are given 
by Equations (\ref{eqn:q1}) and (\ref{eqn:q2}), respectively.
Thus, $Q_1$ can be obtained by assigning a reward rate of $1.0$
to the states in Equation (\ref{eqn:q1}). Similarly, $Q_2$ can be 
obtained by assigning a reward rate of $1.0$ to the states in 
Equation (\ref{eqn:q2}).    

\begin{equation}
Q_1 = 1.0*(p_{1,0,1,0} + p_{1,1,1,0} + p_{1,0,1,1} + p_{1,1,1,1})
\label{eqn:q1}
\end{equation}

\begin{equation}
Q_2 = 1.0*(p_{0,1,0,1} + p_{1,1,0,1})
\label{eqn:q2}
\end{equation}

Let $L_1$ and $L_2$ be the loss probability of the events of type 
one and two, respectively. Typically, $L_1$ is the sum of the probabilities
of those states in which the number of type one events in the queue 
is equal to the maximum buffer capacity $N_1$. Similarly, $L_2$ is the
sum of the probabilities of those states in which the number of type 
two events in the queue is equal to the maximum buffer capacity $N_2$.
Since the maximum buffer capacity for type one events is one, $L_1$
is the sum of the probabilities of the states in which $i=1$, and
$L_2$ is the sum of the probabilities of the states in which $k=1$.  
$L_1$ and $L_2$ are also given by Equation (\ref{eqn:q1})
and Equation (\ref{eqn:q2}), respectively.

For each event type, the total number of events in the system 
is the sum of the enabled event handle and the number of events 
in the queue. The 
expected total number of events of type one and two (denoted 
$E_1$ and $E_2$) are given by Equation (\ref{eqn:e1}) and 
Equation (\ref{eqn:e2}), respectively. Thus, $E_1$ can be obtained 
by assigning a reward rate of $1.0$ to states $(i,j,k,l)$ where 
$i+k = 1$ and a reward rate of $2.0$ to those states where $i+k=2$. 
The condition $i+k=1$ indicates that there is either one event 
of type one in the queue or one event handle enabled. The 
condition $i+k=2$ indicates that there is an event of type one 
in the queue and an event handle corresponding to type one
event enabled. Similarly,
$E_2$ can be obtained by assigning a reward rate of $1.0$ to states
where $j+l = 1$ and a reward rate of $2.0$ to states where $j+l = 2$.

\begin{eqnarray}
E_1 & = & 1.0*(p_{0,0,1,0} + p_{0,1,1,0} + p_{0,0,1,1} + p_{0,1,1,1})
+ \nonumber \\ 
 & & 2.0*(p_{1,0,1,0} + p_{1,1,1,0} + p_{1,0,1,1} + p_{1,1,1,1})
\label{eqn:e1}
\end{eqnarray}

\begin{equation}
E_2 = 1.0*(p_{0,0,0,1} + p_{1,0,0,1}) + 2.0*(p_{0,1,0,1} + p_{0,1,1,1} + p_{1,1,1,1})
\label{eqn:e2}
\end{equation}

We obtain the response time of the events using the tagged customer
approach~\cite{}. In the tagged customer approach, an arriving event
% Swapna, missing citation
is tagged and its trajectory through the system is followed from entry to
exit. The response time of the tagged event is then determined conditional
to the state in which the system lies when the event arrives. The 
unconditional response time can be obtained as the weighted sum of
the conditional response times, with the weights given by the 
steady state probabilities of being in each one of the states. 
Typically, the response time of an event consists of two pieces, namely,
the time taken to service the event hereafter referred to as the 
``service time'', and the time that the event must
wait in the system before its service commences, hereafter referred to
as ``waiting time''. In our case, the average response time of
% Swapna, is it average response time or service time?
an event of an incoming type one and type two event 
is given by $1/\mu_1$ and $1/\mu_2$ respectively, irrespective of
the state in which the system lies when the event arrives. The waiting
time, however, will depend on the system state. Next, we discuss
how the conditional waiting time of each event type is determined.

An arriving event of type one can find the system in each
one of the thirteen states shown in Figure~\ref{fig:mrm}. 
In the state $(0,0,0,0)$ when no event handle is being serviced, 
the waiting time is zero. In states $(1,0,1,0)$, $(1,0,0,1)$,
$(1,1,1,0)$, $(1,1,0,1)$, and $(1,1,1,1)$ an arriving event
of type one is lost. The waiting time of an arriving event
of type one needs to be determined for all the remaining 
states. In state $(0,0,1,0)$, an event of 
type one is being serviced in the present snapshot 
when the tagged event of type one arrives. This ongoing 
service must be completed, prior to the commencement of the service
of the tagged event, and thus the waiting time in this state is 
$1/\mu_1$. In state $(0,0,0,1)$, an event of type two is being serviced
in the current snapshot, and using the same 
argument as in the case of state $(0,0,0,1)$ the waiting time is $1/\mu_2$.
In state $(0,1,1,0)$, an event of type one is being serviced. Although
an event of type two is in the queue, in the next snapshot the incoming
event of type one will be serviced prior to the event of type two 
that is queued due to the prioritized service provided to event of 
type one. Thus the waiting
time in state $(0,1,1,0)$ is $1/\mu_1$. Using similar arguments, the 
waiting time in state $(0,1,0,1)$ is $1/\mu_2$. In state $(0,0,1,1)$,
an event of type one is being serviced in the present snapshot, 
and the event handle corresponding to the event of type two
is enabled. These two enabled event handles must be serviced prior 
to the commencement of the service of the tagged event, which  
results in a waiting time of $(1/\mu_1 + 1/\mu_2)$. 
% Swapna, is this because the reactor is a single threaded which means
% service one by one? So if this was a concurrent thread pool reactor,
% things will be different, right?
In state $(0,1,1,1)$, due to the priority given to events of type one
over event of type two, the waiting time is given by $(1/\mu_1 + 1/\mu_2)$.
The conditional waiting times for a tagged event of type one are 
summarized in Table~\ref{table:cond_w1}. 
The unconditional or the 
expected waiting time for an arriving event of type one is
given by Equation (\ref{eqn:w1_p}). Using $W_1$, the expected response time
for an event of type one is given by Equation (\ref{eqn:r1_p}). 

\begin{table}
\begin{center}
\caption{Conditional waiting time for type one events}
\label{table:cond_w1}
\begin{tabular}{|c|c} \hline 
State & Waiting time \\ \hline 
$(0,0,0,0)$ & $0.0$ \\ \hline 
$(0,0,1,0)$ & $\frac{1}{\mu_1}$  \\ \hline 
$(0,0,0,1)$ & $\frac{1}{\mu_2}$ \\ \hline 
$(0,1,1,0)$ & $\frac{1}{\mu_1}$ \\ \hline 
$(0,1,0,1)$ & $\frac{1}{\mu_2}$ \\ \hline 
$(0,0,1,1)$ & $\frac{1}{\mu_1} + \frac{1}{\mu_2}$ \\ \hline 
$(0,1,1,1)$ & $\frac{1}{\mu_1} + \frac{1}{\mu_2}$ \\ \hline 
\end{tabular}
\end{center}
\end{table}

% Swapna, we have not defined the symbols W1 and R1 before. Similarly,
% eqn 7 is not referred in the text
\begin{eqnarray}
W_1 & = & \frac{1}{\mu_1}p_{0,0,1,0} + \frac{1}{\mu_2}p_{0,0,0,1} + \frac{1}{\mu_1}p_{0,1,1,0} + \\ \notag
     & & \frac{1}{\mu_2}p_{0,1,0,1} + (\frac{1}{\mu_1}+\frac{1}{\mu_2})p_{0,0,1,1} + \\ \notag
     & & (\frac{1}{\mu_1}+\frac{1}{\mu_2})p_{0,1,1,1} 
\label{eqn:w1_p}
\end{eqnarray}

\begin{equation}
R_1 = \frac{1}{\mu_1} + W_1
\label{eqn:r1_p}
\end{equation}

The waiting time for a tagged event of type two can be determined 
using the following reasoning. In the state $(0,0,0,0)$ 
when no event handle is being serviced, the waiting time is zero. 
On the other hand, in states $(0,1,0,1)$, $(0,1,1,0)$, $(1,1,1,0)$,
$(1,1,0,1)$, $(0,1,1,1)$ and $(1,1,1,1)$ an incoming event
of type two is lost. In state $(0,0,0,1)$, an event of
type two is being serviced in the current snapshot, and this
service must be completed. Prior to the service completion of this
event which will mark the completion of the present snapshot, 
and the commencement of the service of the tagged event, two
possible scenarios can occur. In the first scenario, no additional
event of type one arrives in which case the waiting time is $1/\mu_2$.
In the second scenario, an event of type one arrives and
this type one event has to be serviced prior to the tagged event. 
Thus, the waiting time is $1/\mu_1 + 1/\mu_2$. The 
probabilities of these two scenarios can be computed and based on
these probabilities the average waiting time can be determined. It
can be seen, however, that the waiting time in case of the second
scenario is pessimistic compared to the waiting time in case of
the first scenario. Since an estimate of the response time will be
used to determine if the performance of the system is capable of
meeting real-time deadlines, we choose to consider the pessimistic
waiting time in this as well as all in the rest of the paper.  
In state $(1,0,1,0)$, two events of type
one (one that is already being serviced and the one that is in
the queue) need to be serviced prior to the tagged event, and 
thus the waiting time is $2/\mu_1$. Using similar reasoning 
for the remaining states, the waiting time for a tagged event
of type two can be determined for each one of the states and 
is summarized in Table~\ref{table:w2}. The expected 
waiting time for an incoming
event of type two is given by Equation (\ref{eqn:w2_p}). The expected
response time for an event of type two 
is given by Equation (\ref{eqn:r2_p}). 

\begin{table}
\begin{center}
\caption{Conditional waiting time for type two events}
\label{table:cond_w2}
\begin{tabular}{|c|c} \hline 
State & Waiting time \\ \hline 
$(0,0,0,0)$ & $0.0$ \\ \hline 
$(0,0,1,0)$ & $\frac{1}{\mu_1}$  \\ \hline 
$(0,0,0,1)$ & $\frac{1}{\mu_1}+\frac{1}{\mu_2}$ \\ \hline 
$(1,0,1,0)$ & $\frac{2}{\mu_1}$  \\ \hline 
$(1,0,0,1)$ & $\frac{1}{\mu_1}+\frac{1}{\mu_2}$ \\ \hline 
$(0,0,1,1)$ & $\frac{2}{\mu_1} + \frac{1}{\mu_2}$ \\ \hline 
$(1,0,1,1)$ & $\frac{2}{\mu_1} + \frac{1}{\mu_2}$ \\ \hline 
\end{tabular}
\end{center}
\end{table}

\begin{eqnarray}
W_2 & = & (\frac{1}{\mu_2} + \frac{1}{\mu_1})(p_{0,0,0,1} + \frac{2}{\mu_1}p_{1,0,1,0} + \\ \notag
    & & (\frac{1}{\mu_1} + \frac{1}{\mu_2})p_{1,0,0,1} + (\frac{2}{\mu_1} + \frac{1}{\mu_2})p_{0,0,1,1} + \\ \notag
    & & (\frac{2}{\mu_1} + \frac{1}{\mu_2})p_{1,0,1,1} 
\label{eqn:w2_p}
\end{eqnarray}

\begin{equation}
R_2 = \frac{1}{\mu_2} + W_2
\label{eqn:r1_p}
\end{equation}

% Swapna, there is an abrupt transition to this section
\subsection{Performance Evaluation using Stochastic Reward Net}
\label{sec:srn}
The manual construction of the Markov reward model becomes cumbersome 
and prone to errors as the maximum buffer capacities for the events
and number of handlers increase. We now describe how SRNs can be used
to specify the behavior of the Reactor pattern at a higher level, which is
closer to the designer's intuition. 

Figure~\ref{fig:srn} shows the 
SRN model for the Reactor pattern when the events of type one
are serviced with priority over events of type two. It consists
of two parts, namely part (a) and part (b).
Part (a) models the arrival, queuing and service of the two types 
of events. In the figure, transitions $A1$ and $A2$
represent the  
arrivals of the events of types one and two, respectively. 
Places $B1$ and $B2$ represent the queue for the two
types of events. Transitions $Sn1$ and $Sn2$ are immediate transitions
which are enabled when a snapshot is taken. Places $S1$ and $S2$ 
represent the enabled handles of the two types of events, whereas 
transitions $Sr1$ and transition $Sr2$ represent the execution of
the enabled event handlers of the two types of events. An inhibitor
arc from place $B1$ to transition $A1$ with multiplicity $N1$ prevents 
the firing of transition $A1$ when there are $N1$ tokens in the 
place $B1$. The presence of $N1$ tokens in the place $B1$ indicates
that the buffer space to hold the incoming input events of the first
type is full, and no additional incoming events can be accepted.
The inhibitor arc from place $B2$ to transition $A2$ achieves
the same purpose for type two events. The inhibitor arc from place 
$S1$ to transition $Sr2$
prevents the firing of transition $Sr2$ when there is a token in 
place $S1$. This models the prioritized service for the events of
type of one over events of type two.

\begin{figure*}[htb]
\centerline{\epsfig{figure=eps/srn.eps,width=4.5in}}
\caption{SRN model for the Reactor pattern}
\label{fig:srn}
\end{figure*}

Part (b) of the net models the process of taking successive snapshots and
prioritized service of event handles corresponding to type one 
in each snapshot as explained below. Transition $Sn1$ 
is enabled when there is a token in place $StSnpSht$, 
at least one token in place $B1$ and no tokens in place $S1$. 
Similarly, transition $Sn2$ is enabled when there is a token 
in place $StSnpSht$, at least one token in place $B2$ and 
no tokens in place $S2$. Transition $T\_SrvSnpSht$ is enabled 
when there is a token in either one of the places $S1$ and 
$S2$, and the firing of this transition deposits a token in
place $SnpShtInProg$. 
Transition $T\_EndSnpSht$ is enabled when there are no tokens
in both place $S1$ and $S2$. Table~\ref{table:enable} 
summarizes the enabling/\-guard functions for the transitions in the net.    

\begin{table*}[hbt]
\begin{center}
\caption{Guard functions}
\label{table:enable}
\begin{tabular}{|c|c|} \hline
Transition & Guard function \\ \hline 
$Sn1$ & $((\#StSnpShot == 1) \&\& (\#B1 >= 1) \&\& (\#S1 == 0)) ? 1:0$ \\ \hline 
$Sn2$ & $((\#StSnpShot == 1) \&\& (\#B2 >= 1) \&\& (\#S2 ==0)) ? 1:0$ \\ \hline 
$T\_SrvSnpSht$ & $((\#S1 == 1) || (\#S2 == 1)) ? 1:0$ \\ \hline 
$T\_EndSnpSht$ & $((\#S1 == 0 \&\& (\#S2 == 0)) ? 1:0$ \\ \hline 
\end{tabular}
\end{center}
\end{table*}

We now explain how the process of taking a single snapshot is
modeled by the SRN model presented in Figure~\ref{fig:srn} with an example. 
We consider the scenario where there is one token in each one of 
the places $B1$ and $B2$, and there is a token in the place 
$StSnpSht$. Also, there are no tokens in places $S1$ and $S2$.
In this scenario, transitions $Sn1$ and $Sn2$ are enabled. Both of
these transitions are assigned the same priority, and any
one of these transitions can fire first. Also, since these 
transitions are immediate, their firing occurs instantaneously. 
Without loss of generality, we assume that transition $Sn1$ fires before 
$Sn2$ depositing a token in place $S1$. 

When a token is deposited 
in place $S1$ transition $T\_SrvSnpSht$ is enabled. In addition, 
transition $Sn2$ is already enabled. If transition $T\_SrvSnpSht$ were
to fire before transition $Sn2$, it would disable transition
$Sn2$, and prevent the handle corresponding to the second event
type from being enabled. In order to prevent transition $T\_SrvSnpSht$
from firing before transition $Sn2$, transition $T\_SrvSnpSht$
is assigned a lower priority than transition $Sn2$. Since transitions
$Sn1$ and $Sn2$ have the same priority, this also implies that 
the transition $T\_SrvSnpSht$ has a lower priority than transition
$Sn1$. This ensures that in a given snapshot, event handles corresponding
to each event type are enabled when there is at least one event in
the queue. 

After both the event handles are enabled, transition 
$T\_SrvSnpSht$ fires and deposits a token in place $SnpShtInProg$. 
The presence of a token in the place 
$SnpShtInProg$ indicates that the event handles that were enabled 
in the current snapshot are being serviced.
The event handle corresponding to type one event is serviced first
which causes transition $Sr1$ to fire and the removal of the token
from place $S1$. Subsequently, transition $Sr2$ fires and the event
handle corresponding to the event of type two is serviced. This
causes the removal of the token from place $S2$. Once both the events
are serviced and there are no tokens in places $S1$ and $S2$, transition
$T\_EndSnpSht$ fires. This marks the end of the present snapshot and
the beginning of the next one. 

The performance measures described in
Section~\ref{sec:reactor_metrics} can be computed  
by assigning reward rates at the net level as summarized in 
Table~\ref{table:rr}. The throughputs $T_1$ and $T_2$ are respectively
given by the rate at which transitions $Sr1$ and $Sr2$ fire. 
The queue lengths $Q_1$ and $Q_2$ are given by the average number 
of tokens in places $B1$ and $B2$, respectively. The total number of events
$E_1$ is given by the sum of the number of tokens in places $B1$ and $S1$.
Similarly, the total number of events $E_2$ is given by the sum of the
number of tokens in places $B2$ and $S2$. The loss 
probability $L_1$ is given by the probability of $N1$
tokens in place $B1$. Similarly, the loss probability $L_2$ is given by
the probability of $N2$ tokens in place $B2$.  

\begin{table*}[htb]
\begin{center}
\caption{Reward assignments to obtain performance measures}
\label{table:rr}
\begin{tabular}{|c|c|c|} \hline
Performance metric & Notation & Reward rate \\ \hline 
Throughput of event type \#1 & $T_1$ & return rate($Sr1$) \\ \hline 
Throughput of event type \#2 & $T_2$ & return rate($Sr2$)  \\ \hline 
Queue length of event type \#1 & $Q_1$ & return ($\#B1$)  \\ \hline 
Queue length of event type \#2 & $Q_2$ & return ($\#B2$)  \\ \hline 
Loss probability of event type \#1 & $L_1$ & return ($\#B1 == N1 ? 1:0$) \\  \hline 
Loss probability of event type \#2 & $L_2$ &  return ($\#B2 == N2 ? 1:0$) \\ \hline 
Total number of events of type \#1 & $E_1$ & return($\#B1 + \#S1$) \\ \hline 
Total number of events of type \#2 & $E_2$ & return($\#B2 + \#S2$) \\ \hline 
Response time of event type \#1 & $R_1$ & return($\#B1 < N1 ? 1/\mu_1*(\#S1+\#B1+1) + 1/\mu_2*(\#S2+\#B1):0)$ \\ \hline 
Response time of event type \#2 & $R_2$ & return($\#B2 < N2 ? 1/\mu_2*(\#S2+\#B2+1) + 1/\mu_1*(\#S1+\#B2+1):0)$ \\ \hline 
\end{tabular}
\end{center}
\end{table*}

As described in Section~\ref{sec:mrm}, the waiting time for the two
types of events needs to be determined using the tagged customer
approach. The conditional waiting time for a tagged event
of type one and type two will depend on the state of the system,
where the state is given by the number of tokens or markings of 
places $S1$, $S2$, $B1$ and $B2$. Of these four places, the markings
of the places $S1$ and $S2$ determine the progress of the current
snapshot, whereas, the markings of places $B1$ and $B2$ determine
the state of the queue. The time taken to complete the current
snapshot is given by the sum of two terms, the first term is 
the product of the number of tokens in place $S1$ and $1/\mu_1$,
and the second term is the product of the number of tokens in
place $S2$ and $1/\mu_2$. Even if there are no additional events 
in the queues, the current snapshot must be completed, before
the service of an incoming event of either type can begin. Hence 
the time taken to complete the current snapshot contributes to the 
waiting time for each one of the event types. In order to obtain
the entire waiting time of the two types of events, the contribution 
of the queued events of type one and type two needs to be determined. 

Let $n_1$ be the number of events of type one in the queue, 
and $n_2$ be the number
of events of type two in the queue, when the tagged event of type one 
arrives. This implies that after $n_1$ snapshots the tagged event
will be serviced. The following three possibilities arise between
the relative values of $n_1$ and $n_2$. 
If $n_1 < n_2$, then only $n_1$ of the type two events
need to be serviced before the service of the tagged event can commence,
and hence the waiting time is given by $n_1(1/\mu_1 + 1/\mu_2)$. If 
$n_1 = n_2$, then $n_1$ events of type one and type two need to be serviced
before the service of the incoming type one event can commence, 
and hence the waiting time is given by $n_1(1/\mu_1 + 1/\mu_2)$. 
If $n_1 > n_2$, then in the optimistic case, 
$n_1$ events of type one and $n_2$ events of type two need to be 
serviced before the service of the tagged event can commence. The
optimistic case assumes that no additional events of type two arrive in
the first $n_1$ snapshots. In the pessimistic case, however, $n_1 - n_2$ events
will arrive while the first $n_2$ events are being serviced. Thus,
in the optimistic case, the waiting time will be  $n_1/\mu_1 + n_2/\mu_2$,
and in the pessimistic case, the waiting time will be $n_1(1/\mu_1 + 1/\mu_2)$.
The pessimistic contribution of the queued events 
to the waiting time is given by the product of the number of tokens in
place $B1$ and the sum of the reciprocals of $\mu_1$ and $\mu_2$.
Thus, the overall response time of the tagged event will be given
by the sum of two terms, the first term is $1/\mu_1$
times the sum of the tokens in places $S1$, $B1$ and $1$, while the 
second term is given by the product of $1/\mu_2$ and the sum
of the number of tokens in place $S2$ and $B1$. The reward rate to
obtain the response time for an event of type one is summarized
in Table~\ref{table:rr}. 

The contribution of the queued events to the waiting time of
the tagged event of type two can be determined as follows.  Let $n_1$ be
the number of events of type one in the queue, and $n_2$ be the number
of events of type two in the queue, when the tagged type two event
arrives. This implies that after $n_2$ snapshots the tagged event will
be serviced. We now consider three cases similar to the tagged event of
type one. When $n_2 < n_1$, 
the service time of the first $n_2$ snapshots is given by 
$n_2(1/\mu_1+1/\mu_2)$. In the $(n_2+1)^st$ snapshot in which
the tagged event will be serviced, an event of type one will be 
serviced prior to the tagged event due to the priorities. Thus, 
the total waiting time will be given by $(n_2+1)/\mu_1+n_2/\mu_2$. 
If $n_2 = n_1$, in the first $n_2$ snapshots, an additional event
of type one may arrive, making the total waiting time as 
$(n_2+1)/\mu_1+n_2/\mu_2$. If $n_2 > n_1$, then in the pessimistic case,
in the first $n_1$ snapshots, an additional $n_1 - n_2 + 1$ events 
of type one arrive, making the total waiting time 
as $(n_2+1)/\mu_1+n_2/\mu_2$. Thus, a pessimistic estimate of
the total waiting time for given values of $n_1$ and $n_2$ is 
$(n_2+1)/\mu_1+n_2/\mu_2$.  
Thus, the response time of the tagged event of second type will be given
by the sum of two terms, the first term is $1/\mu_2$
times the sum of the tokens in places $S2$, $B2$ and $1$, while the 
second term is given by the product of $1/\mu_1$ and the sum
of the number of tokens in place $S1$, $B2$ and $1$. The reward rate to
obtain the response time for an event of type one is summarized
in Table~\ref{table:rr}. 
 
\subsection{Illustration}
In this section we illustrate how the SRN presented in 
Section~\ref{sec:srn} can be used to determine the impact of
different parameters on the performance measures by careful
design of experiments. The SRN is solved using SPNP~\cite{spnp-new} to
obtain the performance measures in all of the experiments described
below. 

In the first experiment we seek to determine the impact of maximum
buffer capacity on the performance measures. For this experiment,
the values of the 
remaining parameters (except for the buffer capacities) are summarized 
in Table~\ref{table:param}. We consider two values of buffer capacities 
$N_1$ and $N_2$. In the
first experiment we consider a buffer capacity of $1$ for both types
of events, whereas in the second experiment we consider a buffer 
capacity of $5$ for both types of events. The performance metrics for 
both of the experiments are summarized in Table~\ref{table:perf}.  
Since the values of the parameters of the first type of events
($\lambda_1$, $\mu_1$ and $N_1$) are the same 
as the values of the parameters
for the second type of events ($\lambda_2$, $\mu_1$, and $N_2$), the
throughputs, queue lengths, and the loss probabilities are the same
for these two event types. 

The total number of events for the 
events of type two $E_2$ is slightly higher than the total 
number of events of type one $E_1$. Since the events of type one
are provided prioritized service over the events of type two,
on an average it takes longer to service a type two event 
than it takes to service type one event. This results
in a higher total number of events of the second type than of 
the first type. These observations hold for both values of maximum
buffer capacity. It can be observed that the loss 
probability is significantly higher when the buffer capacity is $1$ 
compared to the case when the buffer space is $5$. Also, due to the
higher loss probability, the throughput is slightly lower when
the maximum buffer capacity is $1$ than when the maximum buffer
capacity is $5$. 

\begin{table}[htb]
\begin{center}
\caption{Values of parameters}
\label{table:param}
\begin{tabular}{|c|c|} \hline 
Parameter & Value \\ \hline 
$\lambda_1$ & $0.400$/sec. \\ \hline 
$\lambda_2$ & $0.400$/sec. \\ \hline 
$\mu_1$ & $2.000$/sec. \\ \hline 
$\mu_2$ & $2.000$/sec. \\ \hline 
\end{tabular}
\end{center}
\end{table}

\begin{table}[htb]
\begin{center}
\caption{Impact of buffer capacity on performance measures}
\label{table:perf}
\begin{tabular}{|c|c|c|} \hline 
Performance measure & \multicolumn{2}{|c|}{Buffer space} \\ 
                    & $N_1=1$, $N_2=1$ & $N_1=5$, $N_2 = 5$ \\ \hline 
$T_1$ & $0.37$ & $0.40$/sec \\ \hline 
$T_2$ & $0.37$ & $0.40$/sec \\ \hline 
$Q_1$ & $0.065$ & $0.12$ \\ \hline 
$Q_2$ & $0.065$ & $0.12$ \\ \hline 
$E_1$ & $0.25$ & $0.32$ \\ \hline 
$E_2$ & $0.27$ & $0.35$ \\ \hline 
$L_1$ & $0.065$ & $0.00026$ \\ \hline 
$L_2$ & $0.065$ & $0.00026$ \\ \hline
$R_1$ & $0.6298$ sec. & $0.8310$ sec. \\ \hline 
$R_2$ & $1.0973$ sec. & $1.3309$ sec. \\ \hline 
\end{tabular}
\end{center}
\end{table}

Next, we determine the sensitivity of the performance measures to
the arrival rate of the events of type one and type two,
that is, $\lambda_1$ and $\lambda_2$. 
For sensitivity analysis, we set the maximum buffer capacity
for both the type of events to be $5$. We vary both $\lambda_1$ and
$\lambda_2$ one at a time 
in the range of $0.5$/sec. to $2.0$/sec. to obtain the different performance
measures by solving the SRN shown in Figure~\ref{fig:srn}. 
The remaining parameters are held at the values reported in 
Table~\ref{table:param}. 

Figure~\ref{fig:sens_lam1} shows the performance measures as a
function of $\lambda_1$ and $\lambda_2$. The plots in the left
column show the variation of the performance measures with
respect to $\lambda_1$, whereas the plots in the right column
show the variation of the performance measures with respect
to $\lambda_2$. Referring to the topmost figure in the left 
column, it can be observed that initially, 
the throughput of type one events is nearly the same as the
arrival rate of the events, indicating that the events are serviced 
at the same rate at which they arrive into the system. However, as 
$\lambda_1$ increases, the throughput starts lagging the arrival rate,
which indicates that the service rate $\mu_1$ is not sufficiently
high to process the events at the rate at which they arrive. This 
may cause the event queue for the type one events to operate at 
full capacity for an extended period of time which results in a 
rejection of the incoming input events. 

Thus, a decrease in the 
rate at which the throughput increases is marked by an increase in
the loss probability of the events (as shown in the third plot in 
the left column) and an increase in 
the queue length (as shown in the right plot
in the top row) in Figure~\ref{fig:sens_lam1}. The left plot in the bottom
row represents the total number of events of each type as a function
of $\lambda_1$. The plot indicates that the total number of type two
events in the system increases as $\lambda_1$ increases. When $\lambda_1$
increases, the probability of having to service a type one 
event prior to servicing a type two event 
in a snapshot increases. Since events of type one have priority
over events of type two, type two events tend to reside longer in the
system as $\lambda_1$ increases. Thus, although the throughput of 
type two events is unchanged with respect to $\lambda_1$, the 
response time of a type two event may increase.  
The plots in the right column of Figure~\ref{fig:sens_lam} indicate
that similar trends can be observed in the performance measures with
respect to $\lambda_2$, except that the roles of the two types of 
events are reversed. 
  
\begin{figure*}[htb]
\centerline{\hbox{
\psfig{file=eps/tputlam1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/tputlam2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/totlam1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/totlam2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/losslam1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/losslam2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/quelam1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/quelam2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/resplam1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/resplam2.ps,height=2.5in,angle=270}
}}
\caption{Sensitivity of performance measures to arrival rates $\lambda_1$ and $\lambda_2$}
\label{fig:sens_lam}
\end{figure*}

In the next experiment we determine the sensitivity of the 
performance measures to the service rates of the events, 
namely, $\mu_1$ and $\mu_2$. We set the maximum buffer capacity
for both the type of events to be $5$. We vary both $\mu_1$ and $\mu_2$
in the range of $1/2.5$/sec. to $1/0.5$/sec. in steps of $1/0.25$, one 
at a time to obtain the different performance
measures by solving the SRN shown in Figure~\ref{fig:srn}. 
The remaining parameters are held at the values reported in 
Table~\ref{table:param}. 

The plots in the left column of Figure~\ref{fig:sens_mu} 
show the variation of the performance measures with
respect to $\mu_1$, while the plots in the right column of 
Figure~\ref{fig:sens_mu} show the variation with respect
to $\mu_2$. The topmost plot in the left column shows the 
variation of throughputs of events of type one and two with respect
to $\mu_1$. The figure indicates that as $\mu_1$ decreases, 
the throughputs of both types of events decreases, however,
the magnitude of decrease in the throughput of the event of 
type one is more than the magnitude of decrease in the throughput
of the event of type two. The second and the fourth 
plots in the same column 
shows the variation of the total number of events and the queue length 
of both types as a function of $\mu_1$.
It can be observed that both the total number of events and the queue 
length increases as $\mu_1$ decreases, and the magnitude of 
increase for type one events is higher than the magnitude of
increase for type two events. Similar trends can be observed in
the variation of the loss probabilities and response times 
(plots third and fifth). 
  
\begin{figure*}[htb]
\centerline{\hbox{
\psfig{file=eps/tputmu1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/tputmu2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/totmu1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/totmu2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/lossmu1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/lossmu2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/quemu1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/quemu2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/respmu1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/respmu2.ps,height=2.5in,angle=270}
}}
\caption{Sensitivity of performance measures to service rate $\mu_1$ and service rate $\mu_2$}
\label{fig:sens_mu}
\end{figure*}

It can be noted that as $\mu_1$ decreases, the 
performance measures deteriorate rapidly (loss probability, queue
length, total number of events and response time increases,
and throughput decreases). Also, as $\mu_1$ decreases below 
$0.8$/sec., the performance measures deteriorate rapidly.  
With decreasing $\mu_1$, the time taken
to service an event of type one increases, due to which the time
taken to complete each snapshot increases. As a result, 
indirectly, this also increases the time taken to service an 
event of type two in each snapshot.  Thus, the performance 
measures of both types of events are adversely impacted,
even though only the service time of only one of the event
types increases. This is in contrast to the variation of
the performance measures as a function of the event arrival
rates, where an increase in the arrival rate of a given type of
event adversely impacts the performance measures of only
that type of event. 

The variation of the performance measures with respect to
$\mu_2$ shows the same trend, with the role of event types 
reversed. 

\begin{figure*}[htb]
\centerline{\hbox{
\psfig{file=eps/tputmu1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/tputmu2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/totmu1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/totmu2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/lossmu1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/lossmu2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/quemu1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/quemu2.ps,height=2.5in,angle=270}
}}
\centerline{\hbox{
\psfig{file=eps/respmu1.ps,height=2.5in,angle=270}
\hspace*{0.0in}
\psfig{file=eps/respmu2.ps,height=2.5in,angle=270}
}}
\caption{Sensitivity of performance measures to service rates $\mu_1$
and $\mu_2$} 
\label{fig:sens_mu}
\end{figure*}
