RINASim  October 2016
Documentation of framework for OMNeT++
MM_maxPST_Out.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_maxPST_Out.h>
19 #include "Utils.h"
20 
21 namespace MM_maxPST_Out {
22 
24 
25 void MM_maxPST_Out::initialize() {
26 
27  maxTH = par("maxTH").longValue();
28  margin = par("margin").longValue();
29 
30  cXMLElement* Xml = NULL;
31  if (par("data").xmlValue() != NULL && par("data").xmlValue()->hasChildren()){
32  Xml = par("data").xmlValue();
33  } else {
34  error("Error data not initialized!");
35  }
36 
37  cXMLElementList queues = Xml->getChildrenByTagName("queue");
38  for(auto queue : queues){
39  if (!queue->getAttribute("id")) { error("Error parsing id missing!"); }
40  if (!queue->getAttribute("th")) { error("Error parsing th missing!"); }
41  if (!queue->getAttribute("p1")) { error("Error parsing p1 missing!"); }
42  if (!queue->getAttribute("p2")) { error("Error parsing p2 missing!"); }
43 
44  string id = queue->getAttribute("id");
45  int th = atoi(queue->getAttribute("th"));
46  int p1 = atoi(queue->getAttribute("p1"));
47  int p2 = atoi(queue->getAttribute("p2"));
48 
49  if(th < 0) { th = 0; }
50  if(p1 < 0) { p1 = 0; }
51  //FIXME Vesely: Corrected self-comparison p2 < p2
52  if(p2 < p1) { p2 = p1; }
53 
54 
55  qName2Threshold[id] = th;
56  qName2PrePrio[id] = p1;
57  qName2PostPrio[id] = p2;
58  }
59 }
60 
61 MM_maxPST_Out::~MM_maxPST_Out(){}
62 
63 void MM_maxPST_Out::finish() {}
64 
65 void MM_maxPST_Out::pduInsertered(RMTQueue * q, RMTPort * p) {
66  queueInTime[q].push_back(portTime[p]);
67 }
68 
69 void MM_maxPST_Out::pduDropped(RMTQueue * q, const cPacket * s, RMTPort * p) {
70  queueInTime[q].pop_back();
71 }
72 
73 void MM_maxPST_Out::pduReleased(RMTQueue * q, RMTPort * p) {}
74 
75 void MM_maxPST_Out::queueCreated(RMTQueue * q, RMTPort * p) {
76 
77  portQueues[p].insert(q);
78 
79  vector<string> qv = split(q->getName(), '_');
80 
81  int th = maxTH;
82  if(qv.size() == 2 && qv[1] == "M") {
83  if(qName2Threshold.find(qv[1]) != qName2Threshold.end()) {
84  th = qName2Threshold[qv[1]];
85  }
86  } else if(qv.size() == 3) {
87  int h = stoi(qv[2].c_str());
88  if(h <= 0) { h = 1; }
89  if(qName2Threshold.find(qv[1]) != qName2Threshold.end()) {
90  th = qName2Threshold[qv[1]];
91  }
92  th /= h;
93  } else {
94  cout << "Queue : "<< q->getName() << endl;
95  error("Queue name must be \"M\" or of the form \"in/outQ_QoS_distance\"");
96  }
97 
98  th -= margin;
99  if(th < 0) { th = 0; }
100 
101  qThreshold[q] = th;
102 
103  qPrePrio[q] = qName2PrePrio[qv[1]];
104  qPostPrio[q] = qName2PostPrio[qv[1]];
105 
106  cout << "queue : " << q->getName() << " | Threshold " << th <<endl ;
107 }
108 
109 RMTQueue * MM_maxPST_Out::getnextQueue(RMTPort * p) {
110  RMTQueue * ret = NULL;
111  long cT = portTime[p];
112 
113  double max = -1;
114  int currP = -1;
115 
116 //cout<<"Now " << cT << endl;
117  for(auto & q : portQueues[p]) {
118  if(!queueInTime[q].empty()) {
119  int pst = cT - queueInTime[q].front();
120  int th = qThreshold[q];
121  int qP = pst < th ? qPrePrio[q] : qPostPrio[q];
122 
123 //if(!strcmp(q->getName(), "outQ_BE_3")) {
124 // cout << qPrePrio[q] << " " << qPostPrio[q]<<endl;
125 //cout<<q->getName() << " Prior " << qP << " pst " << pst << " th :" << th << endl;
126 //}
127  if(qP > currP) {
128  currP = qP;
129  max = pst;
130  if(th >0) { max /= th; }
131  ret = q;
132  } else if(qP == currP) {
133  double temp = pst;
134  if(th >0) { temp /= th; }
135 
136  if(temp > max) {
137  max = temp;
138  ret = q;
139  }
140  }
141  }
142  }
143 
144 //cout << " result >> " << ret->getName() << " Prior " << currP << " maxDif " << max << endl;
145 
146  if(ret != NULL) {
147  queueInTime[ret].pop_front();
148  portTime[p]++;
149  }
150  return ret;
151 }
152 
153 simtime_t MM_maxPST_Out::getnextTime(RMTPort * p) {
154  return 0;
155 }
156 
157 }
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
Definition: Utils.cc:33
Define_Module(MM_maxPST_Out)