Code:
#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
iat=0.0;
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
last_check=0.0;
tqsize=0.0;
} //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 #
arrst[ssrc]=simclock+iat;
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)
{
out_tdelay=fopen("total_delay.csv","w");
out_avgdelay=fopen("average_delay.csv","w");
out_plr=fopen("packet_loss_ratio.csv","w");
for(noe=0; noe<MAXNOE; ++noe) //represent the repeatition of experiments
{
init();
//repeatition for one individually experiment
while(npd<TOS) //TOS based on npd
{
scheduler(); //invoke scheduler function
updateclock(); //invoke updateclock function
if(evtype==ARRIVAL)
arrival(); //invoke arrival function
else if(evtype==DEPARTURE)
departure(); //invoke departure function
} //end while
result(); //invoke result function
} //end for
fclose(out_tdelay);
fclose(out_avgdelay);
fclose(out_plr);
system("wgnuplot simplot_tdelay.plt");
system("wgnuplot simplot_avgdelay.plt");
system("wgnuplot simplot_plr.plt");
return 0;
} //end main

