Buffer
defined in DEVSsharp/ModelBase/Buffer.cs
is a
concrete class derived from Atomic
. This class has a single
input port in
, an
-vector of input ports pull
and
an
- vector of output ports out
(in this example,
=3). As member data, phase
is a string; m_Jobs
is
a buffer keeping incoming clients whose type is Job
class;
m_OAvail
is a vector of boolean values tracking the
availability of servers; m_OSzie
stores the number of
connected servers; and send_index
is an int
which
tracks the server index to which Buffer
will send output.
public class Buffer: Atomic { public InputPort iin; public List<InputPort> pull; public List<OutputPort> oout; private List<Job> m_Jobs; // FIFO Buffer protected enum PHASE { Idle, SendTo, Ask }; protected PHASE m_phase; protected List<bool> m_OAvail;//check availability of next resource protected int m_Osize; // size of output protected int m_send_index; // index to which it will send protected double m_send_time;
The function C1
updates member data as a function of an
input event x
. If x
comes through the input port
in
, C1
casts the value of x
to Job
and
pushes it back to the buffer m_Jobs
. Otherwise, x
comes through one of pull
ports. So C1
searches the
server index i
, checking the identity of pull[i]
and
the incoming event's port, and updates m_OAvail[i]=true
which marks the i
-th server as being available.
virtual protected void C1(PortValue x) { if(x.port == iin){ //receiving a client if(x.value is Job) { Job client = (Job)x.value; if(client != null) m_Jobs.Add(client); } else throw new Exception("Invalid Input!"); } else // receiving a pull signal { for(int i=0; i<m_Osize; i++) { if(x.port == pull[i]) { m_OAvail[i]= true; // server_i is available break; } } } }The function
Matched()
first checks to see if there is a
waiting job in m_Jobs
and then checks to see if there
exists an available server from 0 to m_Osize
-1. If a match
is found, the function sets m_OAvail[i]=false
, remembers
the index i
at send_index
, then returns true
.
Otherwise it returns false
which means no match.
private bool Matched() { if(m_Jobs.Count > 0){ for(int i=0; i < m_Osize; i++){// select server if(m_OAvail[i] == true){// server i is available m_OAvail[i]=false;//Mark server_i non-available m_send_index = i; // remember i in m_send_index return true; } } return false; }else return false; }
The function C2
creates an the output event and removes the
first job from m_Jobs
when C2
's phase is
SendTo
.
virtual protected void C2(ref PortValue y) { if(m_phase == PHASE.SendTo){ Job job = m_Jobs[0]; y.Set(oout[m_send_index], job); m_Jobs.RemoveAt(0);// remove the first client } }
The function init()
of Buffer
resets phase to
Idle
, assigns m_OAvial[i]=true
for all indices, and
clears
all jobs in m_Jobs
.
public override void init() { m_phase = PHASE.Idle; m_Jobs.Clear(); m_send_index = 0; m_OAvail.Clear(); for (int i = 0; i < m_Osize; i++) m_OAvail.Add(true); // add variable }
Buffer
's tau()
returns
for Idle
and
returns 2.0 for SendTo
.
public override double tau() { if (m_phase == PHASE.Idle) return double.MaxValue; else return m_send_time; }The input transition function
delta_x
of Buffer
updates member data by calling C1(x)
and then, if the phase
of the server is Idle
, checks the returning value of
Matched()
. If the value is true
, the phase of the
server changes into SendTo
.
public override bool delta_x(PortValue x) { C1(x); if (m_phase == PHASE.Idle) { if (Matched()) { m_phase = PHASE.SendTo;// return true; // reschedule as active } } return false; }
When the server is ready to exit the state SendTo
, it gets
y
by calling C2(y)
, if Matched()
returns
true
, the phase stays at SendTo
. Otherwise, the
phase returns to Idle
.
public override void delta_y(ref PortValue y) { C2(ref y); if (Matched()) m_phase = PHASE.SendTo; else m_phase = PHASE.Idle; }
Recall that Buffer
class contains the overriding
Get_Statistics_s()
and GetPerformance()
, which were
investigated in Section 4.2.3. For the
codes of Buffer::Get_s()
, the reader should refer to
Buffer.cs
.