📄 aggcbqegress-adc.cc.cc
字号:
/* Implementation of Egress Admission Control */
/* here the measurement parameter is the peak rate and Delay qos requested of the flow . */
#include "adc.h"
#include "aggcbqegress-est.h"
#include "ip.h"
#include "packet.h"
#include "address.h"
struct numofflowinfo0
{
int flowid0;
double starttime0;
};
typedef struct numofflowinfo0 numofflowinfo0;
struct numofflowinfo1
{
int flowid1;
double starttime1;
};
typedef struct numofflowinfo1 numofflowinfo1;
class AggCbqEgress_ADC : public ADC {
public:
static int flowcount0;
static numofflowinfo0 flowinfoarray0[100];
static int numofacceptcount0;
static int numofrejectcount0;
static int flowcount1;
static numofflowinfo1 flowinfoarray1[100];
static int numofacceptcount1;
static int numofrejectcount1;
AggCbqEgress_ADC();
static void incrementacceptcount0()
{
numofacceptcount0++;
}
static void decrementacceptcount0()
{
numofacceptcount0--;
}
static void incrementrejectcount0()
{
numofrejectcount0++;
}
static void printnumofflowcount0()
{
printf(" The number of flows in the network at %d are %d
\n",(int)Scheduler::instance().clock(),numofacceptcount0);
}
static void incrementacceptcount1()
{
numofacceptcount1++;
}
static void decrementacceptcount1()
{
numofacceptcount1--;
}
static void incrementrejectcount1()
{
numofrejectcount1++;
}
static void printnumofflowcount1()
{
printf(" The number of flows in the network at %d are %d
\n",(int)Scheduler::instance().clock(),numofacceptcount1);
}
int command(int argc, const char*const* argv);
protected:
int admit_flow(int,double,int){}
int admit_flow(Packet*,Handler*,int,double,int);
int admit_flow0(int,double,int,int);
int admit_flow1(int,double,int,int);
void updateflowarray0(int);
void updateflowarray1(int);
int off_ip_;
int off_cmn_;
double clr_;
double delay_; /* figure out how to set this */
double lifetime_;
double delayrequest0_;
double delayrequest1_;
double arrenvelope[17][2];
double serenvelope[17][2];
};
int AggCbqEgress_ADC::flowcount0 = 0;
int AggCbqEgress_ADC::numofacceptcount0 = 0;
int AggCbqEgress_ADC::numofrejectcount0 = 0;
numofflowinfo0 AggCbqEgress_ADC::flowinfoarray0[100];
int AggCbqEgress_ADC::flowcount1 = 0;
int AggCbqEgress_ADC::numofacceptcount1 = 0;
int AggCbqEgress_ADC::numofrejectcount1 = 0;
numofflowinfo1 AggCbqEgress_ADC::flowinfoarray1[100];
static class AggCbqEgress_ADCClass : public TclClass {
public:
AggCbqEgress_ADCClass() : TclClass("ADC/AggCbqEgress") {}
TclObject* create(int,const char*const*) {
return (new AggCbqEgress_ADC());
}
} class_aecbq_adc;
AggCbqEgress_ADC::AggCbqEgress_ADC()
{
bind("clr_", &clr_);
bind("lifetime_",&lifetime_);
bind("delayrequest0_", &delayrequest0_);
bind("delayrequest1_", &delayrequest1_);
bind("off_ip_", &off_ip_);
bind("off_cmn_", &off_cmn_);
/* to accurately set delay_ I need to know the link bandwidth
* and the buffer size. bandwidth is known (needed for admission
* decisions). assume this all gets set with call to 'setbuf'.
*/
type_ = new char[13];
strcpy(type_, "AggCbqEgress");
for(int i = 0;i < 100;i++)
{
flowinfoarray0[i].flowid0 = 0;
flowinfoarray0[i].starttime0 = 0.0;
flowinfoarray1[i].flowid1 = 0;
flowinfoarray1[i].starttime1 = 0.0;
}
}
void AggCbqEgress_ADC::updateflowarray0(int fid)
{
flowinfoarray0[flowcount0].flowid0 = fid;
flowinfoarray0[flowcount0++].starttime0 = (int)Scheduler::instance().clock();
}
void AggCbqEgress_ADC::updateflowarray1(int fid)
{
flowinfoarray1[flowcount1].flowid1 = fid;
flowinfoarray1[flowcount1++].starttime1 = (int)Scheduler::instance().clock();
}
int AggCbqEgress_ADC::admit_flow(Packet *p,Handler *h,int cl, double r,int b)
{
int ret;
int fid;
int classofpacket;
hdr_ip *iph=(hdr_ip*)p->access(off_ip_);
hdr_cmn *ch=(hdr_cmn*)p->access(off_cmn_);
classofpacket = ch->classofpacket();
fid = iph->flowid();
if(classofpacket == 0)
{
ret = admit_flow0(cl, r, b,fid);
printf("Admit_flow for class0 %d\n", ret);
}
else
{
if(classofpacket == 1)
{
ret = admit_flow1(cl, r, b,fid);
printf("Admit_flow for class1 %d\n", ret);
}
}
printnumofflowcount0();
printnumofflowcount1();
printf("\n The number of flows rejected so far for class 0 are %d \n",numofrejectcount0);
printf("\n The number of flows rejected so far for class 1 are %d \n",numofrejectcount1);
return(ret);
}
int AggCbqEgress_ADC::admit_flow0(int /* cl */, double r, int b,int fid)
{
int i;
int ii;
double denotemp;
double numotemp;
double arrenvelopebar[17];
double stddeviation[17];
double alpha = 1.0;
double firstfactor;
double secondfactor;
double lhsfactor;
int admissionflag;
double flowendtime;
double currenttime;
int returnvalue;
printf("\n the rate in admit_flow0 is %f \n",r);
// obtain the envelopes from egress estimator
arrenvelope = AggCbqEgress_Est::arrivalenvelope0;
serenvelope = AggCbqEgress_Est::serviceenvelope0;
// obtain the square root of the sum of the variances of arrival and service envelopes
for(i = 0; i < 17;i++)
{
stddeviation[i] = sqrt(arrenvelope[i][1] + serenvelope[i][1]);
}
// obtain Abar from the arrival envelopes
for(i = 0;i < 17;i++)
{
denotemp = (pow(2,i)*1000*8.0)/(arrenvelope[i][0]);
denotemp = denotemp + r;
numotemp = (pow(2,i)*1000*8.0)/denotemp;
arrenvelopebar[i] = numotemp;
}
// Here we are actually performing the check for admission of the new flow
// The peak rate request by the new flow is r and the Delay request is 20msecs
// The equation is ........for i ranging from 0 to 16
// [servicemean(i) + alpha * standarddeviation of service(i)] -
// [arrivalbarmean(i) - alpha * standarddeviation of arrival(i)] < Delayrequest
// [servicemean(i) - arrivalbarmean(i)] + alpha*[sqrt(servicevariance(i) +
// arrivalvariance(i))]
for(i = 0;i < 17;i++)
{
//if((arrenvelope[i][0] != 0 && serenvelope[i][0] != 0)&&(arrenvelope[i][0] < serenvelope[i][0]))
if(arrenvelope[i][0] != 0 && serenvelope[i][0] != 0)
{
firstfactor = serenvelope[i][0] - arrenvelopebar[i];
secondfactor = alpha * stddeviation[i];
lhsfactor = firstfactor + secondfactor;
}
else
{
lhsfactor = 0.0;
}
printf("\n the lhsfactor for the row %d ----- is %f \n",i,lhsfactor);
if(lhsfactor < delayrequest0_)
{
admissionflag = 1;
}
else
{
admissionflag = 0;
break;
}
}
if(admissionflag == 1)
{
updateflowarray0(fid);
currenttime = (int)Scheduler::instance().clock();
for(ii = 0;ii < flowcount0;ii++)
{
flowendtime = flowinfoarray0[ii].starttime0 + lifetime_;
if(currenttime == flowendtime)
{
AggCbqEgress_ADC::decrementacceptcount0();
}
}
AggCbqEgress_ADC::incrementacceptcount0();
returnvalue = 1;
}
else
{
currenttime = (int)Scheduler::instance().clock();
for(ii = 0;ii < flowcount0;ii++)
{
flowendtime = flowinfoarray0[ii].starttime0 + lifetime_;
if(currenttime == flowendtime)
{
AggCbqEgress_ADC::decrementacceptcount0();
}
}
AggCbqEgress_ADC::incrementrejectcount0();
returnvalue = 0;
}
return(returnvalue);
}
int AggCbqEgress_ADC::admit_flow1(int /* cl */, double r, int b,int fid)
{
int i;
int ii;
double denotemp;
double numotemp;
double arrenvelopebar[17];
double stddeviation[17];
double alpha = 3.0;
double firstfactor;
double secondfactor;
double lhsfactor;
int admissionflag;
double flowendtime;
double currenttime;
int returnvalue;
printf("\n the rate in admit_flow1 is %f \n",r);
// obtain the envelopes from egress estimator
arrenvelope = AggCbqEgress_Est::arrivalenvelope1;
serenvelope = AggCbqEgress_Est::serviceenvelope1;
// obtain the square root of the sum of the variances of arrival and service envelopes
for(i = 0; i < 17;i++)
{
stddeviation[i] = sqrt(arrenvelope[i][1] + serenvelope[i][1]);
}
// obtain Abar from the arrival envelopes
for(i = 0;i < 17;i++)
{
denotemp = (pow(2,i)*1000*8.0)/(arrenvelope[i][0]);
denotemp = denotemp + r;
numotemp = (pow(2,i)*1000*8.0)/denotemp;
arrenvelopebar[i] = numotemp;
}
// Here we are actually performing the check for admission of the new flow
// The peak rate request by the new flow is r and the Delay request is 20msecs
// The equation is ........for i ranging from 0 to 16
// [servicemean(i) + alpha * standarddeviation of service(i)] -
// [arrivalbarmean(i) - alpha * standarddeviation of arrival(i)] < Delayrequest
// [servicemean(i) - arrivalbarmean(i)] + alpha*[sqrt(servicevariance(i) +
// arrivalvariance(i))]
for(i = 0;i < 17;i++)
{
//if((arrenvelope[i][0] != 0 && serenvelope[i][0] != 0)&&(arrenvelope[i][0] < serenvelope[i][0]))
if(arrenvelope[i][0] != 0 && serenvelope[i][0] != 0)
{
firstfactor = serenvelope[i][0] - arrenvelopebar[i];
secondfactor = alpha * stddeviation[i];
lhsfactor = firstfactor + secondfactor;
}
else
{
lhsfactor = 0.0;
}
printf("\n the lhsfactor for the row %d ----- is %f \n",i,lhsfactor);
if(lhsfactor < delayrequest1_)
{
admissionflag = 1;
}
else
{
admissionflag = 0;
break;
}
}
if(admissionflag == 1)
{
updateflowarray1(fid);
currenttime = (int)Scheduler::instance().clock();
for(ii = 0;ii < flowcount1;ii++)
{
flowendtime = flowinfoarray1[ii].starttime1 + lifetime_;
if(currenttime == flowendtime)
{
AggCbqEgress_ADC::decrementacceptcount1();
}
}
AggCbqEgress_ADC::incrementacceptcount1();
returnvalue = 1;
}
else
{
currenttime = (int)Scheduler::instance().clock();
for(ii = 0;ii < flowcount1;ii++)
{
flowendtime = flowinfoarray1[ii].starttime1 + lifetime_;
if(currenttime == flowendtime)
{
AggCbqEgress_ADC::decrementacceptcount1();
}
}
AggCbqEgress_ADC::incrementrejectcount1();
returnvalue = 0;
}
return(returnvalue);
}
int AggCbqEgress_ADC::command(int argc, const char*const* argv)
{
if (argc == 3) {
if (strcmp(argv[1], "setbuf") == 0) {
double b;
b = atof(argv[2]);
/* convert buffer size to delay */
delay_ = b/bandwidth_;
return(TCL_OK);
}
}
return (ADC::command(argc, argv));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -