Download this file

RED.cc    84 lines (69 with data), 1.9 kB

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
* RED.cpp
*
* Created on: 17. 11. 2014
* Author: cloq
*/
#include <RED.h>
Define_Module(RED);
void RED::postQueueCreation(RMTQueue* queue)
{
// TODO: fix variable initialization, these are just for demo purposes
qAvgLengths[queue] = 0.0;
qWeights[queue] = 0.5;
qProbabilities[queue] = 0.4;
qCounters[queue] = -1;
}
void RED::preQueueRemoval(RMTQueue* queue)
{
qAvgLengths.erase(queue);
qWeights.erase(queue);
qProbabilities.erase(queue);
qCounters.erase(queue);
}
void RED::run(RMTQueue* queue)
{
maxQPolicy = ModuleAccess<RMTMaxQBase>("maxQueuePolicy").get();
int length = queue->getLength();
int minThresh = queue->getThreshLength();
int maxThresh = queue->getMaxLength();
double avr = qAvgLengths[queue];
double wq = qWeights[queue];
double maxP = qProbabilities[queue];
int count = qCounters[queue];
simtime_t qTime = queue->getQTime();
const char* qname = queue->getFullName();
if (length > 0)
{
avr = (1 - wq) * avr + wq * length;
}
else
{
const double m = SIMTIME_DBL(simTime() - qTime);
avr = pow(1 - wq, m) * avr;
}
qAvgLengths[queue] = avr;
if (length > maxThresh)
{
EV << "RED: Queue " << qname << " is full! Dropping the incoming message." << endl;
maxQPolicy->run(queue);
qCounters[queue] = 0;
}
else if (minThresh <= avr && avr < maxThresh)
{
qCounters[queue] += 1;
const double pb = maxP * (avr - minThresh) / (maxThresh - minThresh);
const double pa = pb / (1 - count * pb);
const double rand = dblrand();
if (rand < pa)
{
EV << "RED: rand < pa (" << rand << " < " << pa << ")! Executing MaxQPolicy." << endl;
maxQPolicy->run(queue);
qCounters[queue] = 0;
}
}
else
{
qCounters[queue] = -1;
}
}