next up previous contents index
Next: Performance Analysis Up: Client-Server System Previous: Server   Contents   Index


Buffer

Buffer defined in DEVSsharp/ModelBase/Buffer.cs is a concrete class derived from Atomic. This class has a single input port in, an $ n$ -vector of input ports pull and an $ n$ - vector of output ports out (in this example, $ n$ =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 $ \infty$ 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.


next up previous contents index
Next: Performance Analysis Up: Client-Server System Previous: Server   Contents   Index
MHHwang 2007-05-08