RINASim  October 2016
Documentation of framework for OMNeT++
MM_PDQ_Drop.cc
Go to the documentation of this file.
1 //
2 // Copyright © 2014 - 2015 PRISTINE Consortium (http://ict-pristine.eu)
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Lesser General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public License
15 // along with this program. If not, see http://www.gnu.org/licenses/.
16 //
17 
18 #include <MM_PDQ_Drop.h>
19 
20 #include "Utils.h"
21 
22 namespace MM_PDQ_Drop {
23 
25 
26 Threshold::Threshold(int _limit, double _prob) {
27  limit = _limit;
28  prob = _prob;
29 }
30 
31 
33  id ="";
34  absThreshold = 0;
35 }
36 
37 QueueConfig::QueueConfig(string _id, int _absThreshold){
38  id =_id;
39  absThreshold = _absThreshold;
40 }
41 
42 void MM_PDQ_Drop::initialize() {
43 
44  defaultThreshold = par("defaultThreshold").longValue();
45  if(defaultThreshold < 0) { error("Error at DL_Drop. defThreshold must be >= 0!"); }
46 
47  cXMLElement* Xml = NULL;
48  if (par("data").xmlValue() != NULL && par("data").xmlValue()->hasChildren()){
49  Xml = par("data").xmlValue();
50  } else { return; }
51 
52  cXMLElementList queues = Xml->getChildrenByTagName("queue");
53  for(auto queue : queues){
54  if (!queue->getAttribute("id")) { error("Error parsing DQ_Drop Queue. Its ID is missing!"); }
55  std::string id = queue->getAttribute("id");
56  if (id=="") { error("Error parsing DQ_Drop Queue. Queue ID cannot be empty!"); }
57 
58  if (!queue->getAttribute("absThreshold")) { error("Error parsing DQ_Drop Queue. Its absThreshold is missing!"); }
59  int absThreshold = atoi(queue->getAttribute("absThreshold"));
60  if (absThreshold<0) { error("Error parsing DQ_Drop Queue. Queue absThreshold must be >=0!"); }
61 
62  QueueConfig q(id, absThreshold);
63 
64  cXMLElementList THs = queue->getChildrenByTagName("TH");
65 
66  for(auto TH : THs){
67  if(!TH->getAttribute("threshold")) { error("Error parsing TH. threshold must be defined!"); }
68  int threshold = atoi(TH->getAttribute("threshold"));
69  if(threshold<0) { error("Error parsing PP. threshold must be >=0!"); }
70  if(absThreshold<=threshold) { continue; }
71 
72  if(!TH->getAttribute("dropProb")) { error("Error parsing TH. dropProb must be defined!"); }
73  double dropProb = atof(TH->getAttribute("dropProb"));
74  if(dropProb<=0 || dropProb>=1) { error("Error parsing TH. dropProb must be in (0,1)!"); }
75 
76  q.thresholdList.push_back(Threshold(threshold, dropProb));
77  }
78 
79  queuesConf[id] = q;
80  }
81 }
82 
83 MM_PDQ_Drop::~MM_PDQ_Drop(){
84  portCount.clear();
85 }
86 
87 void MM_PDQ_Drop::pduInsertered(RMTQueue * q, RMTPort * p) {
88  portCount[p]++;
89 }
90 
91 void MM_PDQ_Drop::pduDropped(RMTQueue * q, const cPacket * s, RMTPort * p) {
92  portCount[p]--;
93 }
94 
95 void MM_PDQ_Drop::pduReleased(RMTQueue * q, RMTPort * p) {
96  portCount[p]--;
97 }
98 
99 void MM_PDQ_Drop::queueCreated(RMTQueue * q, RMTPort * p) {
100 
101  vector<string> qv = split(q->getName(), '_');
102 
103  if(qv.size() < 2) {
104  error("Queue name must be of the form in/outQ_QoS[_*]");
105  }
106  string qConf = join(qv, 2, '_');
107 
108  if(queuesConf.find(qConf) != queuesConf.end()) {
109  queueConf[q] = &queuesConf[qConf];
110  } else {
111  queueConf[q] = NULL;
112  }
113 
114  portQueues[p].insert(q);
115 }
116 
117 double MM_PDQ_Drop::getDropProbability(RMTQueue * q, RMTPort * p) {
118  int count = portCount[p];
119  QueueConfig * qc = queueConf[q];
120 
121  if(count >= qc->absThreshold) {
122  return 1.0;
123  }
124 
125  double prob = 0.0;
126  int nearTH = 0;
127  for(Threshold & th : qc->thresholdList) {
128  if(count >= th.limit && nearTH < th.limit) {
129  nearTH = th.limit;
130  prob = th.prob;
131  }
132  }
133 
134  return prob;
135 }
136 
137 
138 void MM_PDQ_Drop::finish() {
139 /*
140  cout << "MM_PDQ_Drop "<< this->getFullPath() << endl;
141  for(auto qc : queueConf) {
142  cout << "\tQueue " << qc.second->id << endl;
143  cout << "\t\tAbsolute threshold " << qc.second->absThreshold<<endl;
144  for(Threshold & th : qc.second->thresholdList) {
145  cout << "\t\t-Threshold " << th.limit << " :: "<< th.prob <<endl;
146  }
147 
148  }
149 */
150 }
151 
152 }
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
Definition: Utils.cc:33
Threshold(int, double)
Definition: MM_PDQ_Drop.cc:26
std::string join(const std::vector< std::string > &elems, const unsigned int n, const char delim)
Definition: Utils.cc:48
vector< Threshold > thresholdList
Definition: MM_PDQ_Drop.h:42
Define_Module(MM_PDQ_Drop)