How to Extend M/M/1 Queue Simulation to M/M/K

adamms's Avatar, Join Date: Nov 2010
Newbie Member
Hello everyone. Help me to extend the M/M/1 code below to M/M/K.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/*variables declaration*/
#define TOS 10 //termination of service; number of repetition for each experiment :100
#define MAXNOSRC 5 //number of sources 
#define MAXQSIZE 50 //max queue size or buffer 
#define ARRIVAL 0 //event type: arrival
#define DEPARTURE 1 //event type: departure
#define SERVER_IDLE 0 //data sink status: idle
#define SERVER_BUSY 1 //data sink status: busy
#define MAXNOE 20 //number of experiments 

double arrst[MAXNOSRC]; //arrival service time: stores the time each source will generate ‘a’ packet
double patq[MAXQSIZE]; //packet arrival time in queue
double dpst; //departure service time: store the time a packet will leave the server after being processed
double iat; //inter arrival time (iat=1/λ)
double st; //service time (st=1/µ)
double simclock; //simulation clock
double delay; //delay
double tdelay; //total delay
double avgdelay; //average delay= tdelay/npd
double plr; //packet loss ratio=tpl/npa
double smallest; //smallest simulation time
double tqsize;
double last_check;

double load; //λ
double npd; //# of packet departured/processed
double npa; //# of packet arrive/generate
double tpl; //total packet lost
int dss; //data sink status (1: idle; 2: busy)
int ssrc; //selected source
int evtype; //event type (1: arrival; 2: departure)
int cqsize; //current queue size
int noe; //# of experiment

/*functions prototype*/
double traffic(void);
void init(void);
void updateclock(void);
void scheduler(void);
void arrival(void);
void departure(void);
void result(void);
int main(void);

FILE *out_tdelay; //output file pointer for total delay: total_delay.csv
FILE *out_avgdelay; //output file pointer for average delay: average_delay.csv
FILE *out_plr; //output file pointer for packet loss ratio: packet_loss_ratio.csv

double traffic(void)
/*poisson distribution use to generate traffic*/
    double x=rand(); //get random #
    double iat=0; //initialize interAT=0
    iat = -log(x/1.0e+30)/load; //formula to inject randomness into Poisson Distribution
    return iat; //return interAT to caller function

void init(void)
    int a; 
    load+=20; //increament load

    arrst[MAXNOSRC]=0.0; //arrival service time: stores the time each source will generate ‘a’ packet
    patq[MAXQSIZE]=0.0; //packet arrival time in queue
    for(a=0; a<MAXNOSRC; ++a)
        arrst[a]=rand(); //assign random start time to each arrival node==> how to get rand # between 0-1??
    //arrst[0]=0.6; arrst[1]=0.5; arrst[2]=0.8;
    dpst=1.0e+30; //departure service time: store the time a packet will leave the server after being processed
    st=2.5; //fix service time (st=1/µ == packet size/bandwidth)
    simclock=0.0; //simulation clock
    smallest=1.0e+30; //smallest simulation time
    avgdelay=0.0; //average delay= 
    plr=0.0; //packet loss ratio
    tdelay=0.0; //total delay
    npd=0.0; //# of packet departured/sink
    npa=0.0; //# of packet arrived/generate
    tpl=0.0; //# of packet loss
    dss=SERVER_IDLE; //data sink status set to IDLE
    ssrc=0; //selected source
    evtype=1; //event type (1: arrival; 2: departure)
    cqsize=0; //current queue size/number in queue
} //end init

void updateclock(void)
/*Advance the simulation clock*/
    simclock=smallest; //assign current smallest time to simclock

void scheduler(void)
/*Determine the event type of the next event to occur*/
    int a;
    smallest=1.0e+30; //assign very big number(infinity) to smallest time
    for(a=0; a<MAXNOSRC; ++a) //find the smallest among sources
        if(arrst[a]<smallest) //if arrival start time[a] is less than smallest time
            smallest=arrst[a]; //smallest become arrival start time for source [a]
            ssrc=a; //pick selected source 
            evtype=ARRIVAL; //event type is ARRIVAL
        if(dpst<smallest) //if departure start time is less than smallest time
            smallest=dpst; //assign departure start time to smallest time
            evtype=DEPARTURE; //event type is DEPARTURE
    } //end for
} //end scheduler

void arrival(void)
    ++npa; //increament of packet generation/arrival
    iat=traffic(); //inter arrival time set to [-log(x/1.0+30)]/load; x is random #
    if(dss==SERVER_IDLE) //if data sink status is IDLE 1
        dss=SERVER_BUSY; //change data sink status to BUSY 2
        dpst=simclock+st;  //schedule the time a task completely processed
    else if(dss==SERVER_BUSY) //if data sink status is BUSY 2
        if(cqsize==MAXQSIZE) //if queue is full
            ++tpl; //increment total packet lost
        else if(cqsize<MAXQSIZE) //if queue space is still available
            patq[cqsize]=simclock; //assign simclock to the time of current packet in queue 
            ++cqsize; //increment current buffer in queue
        } //end else
    } //end elseif
} //end arrival

void departure(void)
    int i;

    ++npd; //increment the number of task processed/packet departed
    if(cqsize==0) //if the buffer or queue is empty
        dss=SERVER_IDLE; //no processsing
        dpst=1.0e+30; //assign very large value (infinity) to dpst
    else if(cqsize!=0) //if there are packets in the queue
        delay=simclock-patq[0]; //compute delay of packet who is beginning service
        tdelay+=delay; //update of total delay
        for(i=0; i<MAXQSIZE; ++i) 
            patq[i]=patq[i+1]; //move packet in queue up 1 place
        dpst=simclock+st; //departure start time
        --cqsize; //decreament number of packet in queue
    }//end elseif
} //end departure

void result(void)
/*Compute and write estimates of desired measures of performance*/
    avgdelay=tdelay/npd; //to compute average delay
    plr=tpl/npa; //to compute packet loss ratio
    fprintf(out_tdelay,"%f\t%f\n",load, tdelay);
    fprintf(out_avgdelay,"%f\t%f\n",load, avgdelay);
    fprintf(out_plr,"%f\t%f\n",load, plr);
} //end result

int main(void)

    for(noe=0; noe<MAXNOE; ++noe) //represent the repeatition of experiments
        //repeatition for one individually experiment
        while(npd<TOS) //TOS based on npd 
            scheduler(); //invoke scheduler function
            updateclock(); //invoke updateclock function
                arrival(); //invoke arrival function
            else if(evtype==DEPARTURE)
                departure(); //invoke departure function
        } //end while
        result(); //invoke result function
    } //end for
    system("wgnuplot simplot_tdelay.plt");
    system("wgnuplot simplot_avgdelay.plt");
    system("wgnuplot simplot_plr.plt");
    return 0;
} //end main
xpi0t0s's Avatar, Join Date: Aug 2004
Perhaps a little more explanation would be helpful, rather than just dumping 200 lines of code on us and a one-line statement that means virtually nothing? What are MM1 and MMK? What does the code do? What have you tried?
adamms's Avatar, Join Date: Nov 2010
Newbie Member
Sorry for that. I admit my mistake.

This is discrete events simulation program in C that represent the queueing model. It can be used to simulate the real queueing in the computer system or network. M/M/1 queue consists of a server which provides service for the packet who arrive at the system, receive service, and depart. It is a single-server queueing system with exponential interarrival times, exponential service times and first-in–first-out queue discipline. If a packet arrives when the server is busy, it joins the queue (the waiting line). The capital letter "M" represent the Markovian (exponential) distribution of inter arrival time and service time. "1" means a single server. So for M/M/k means that "K" represent the number of server(s). Some times the notation is represent by M/M/n or M/M/s.

So, I just want to extend the capability of my previous program to support multiple server. Any one here can help me with that? Really appreciate your response and many thanks.
Jenifer's Avatar, Join Date: Apr 2011
Newbie Member
hi adamms, I got m/m/k code using linked list if u want it give me ur email address to send this code cause it's kinda long. I wanted to add wfq and leaky bucket to ur code but it didn't work how can I do that ? Is it possible? should it be modified alot?
Idatriska's Avatar, Join Date: Aug 2011
Light Poster
anyone can help me C/C++....i have same with Mr.adamms problem...My final project is about M/M/K queue simulation in LAN network...i have tried source code from Mr.Adamms but i didn't know to extend it...please help me....