RINASim  October 2016
Documentation of framework for OMNeT++
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MM_maxDelayLimited_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_maxDelayLimited_Out.h>
19 
21 
23 
24 void MM_maxDelayLimited_Out::initialize() {
25  defaultMaxDel = par("defDelay").longValue();
26  if(defaultMaxDel < 0) { error("Error at DL_Out. defDelay must be >=0!"); }
27 
28 
29  cXMLElement* Xml = NULL;
30  if (par("data").xmlValue() != NULL && par("data").xmlValue()->hasChildren()){
31  Xml = par("data").xmlValue();
32  } else {
33  return;
34  }
35  cXMLElementList queues = Xml->getChildrenByTagName("queue");
36  for(auto queue : queues){
37  if (!queue->getAttribute("id")) { error("Error parsing DL_Out Queue. Its ID is missing!"); }
38  std::string id = queue->getAttribute("id");
39  if (id=="") { error("Error parsing DL_Out Queue. Queue ID cannot be empty!"); }
40 
41  if (!queue->getAttribute("delay")) { error("Error parsing DL_Out Queue. Its delay is missing!"); }
42  double delay = atof(queue->getAttribute("delay"));
43  if (delay<0) { error("Error parsing DL_Out Queue. Queue delay must be >=0!"); }
44 
45  double multip = 1.0;
46  if (queue->getAttribute("multip")) {
47  multip = atof(queue->getAttribute("multip"));
48  if (multip<=0) { error("Error parsing DL_Out Queue. Queue multip must be >0!"); }
49  }
50 
51  double burstTime = 0.0;
52  unsigned int burstSize = 1500;
53  if (queue->getAttribute("burstTime")) {
54  burstTime = atof(queue->getAttribute("burstTime"));
55  if (burstTime<=0) { error("Error parsing DL_Out Queue. Queue burstTime must be >0!"); }
56 
57  if (queue->getAttribute("burstSize")) {
58  burstSize = atoi(queue->getAttribute("burstSize"));
59  if (burstSize<=0) { error("Error parsing DL_Out Queue. Queue burstSize must be >0!"); }
60  } else { error("Error parsing DL_Out Queue. Queue burstSize must be initialized!"); }
61  }
62 
63 
64  queueName2Delay[id] = delay;
65  queueName2Multip[id] = multip;
66  queueName2BurstTime[id] = burstTime;
67  queueName2BurstSize[id] = burstSize;
68  }
69 }
70 
71 MM_maxDelayLimited_Out::~MM_maxDelayLimited_Out(){}
72 
73 void MM_maxDelayLimited_Out::finish() {}
74 
75 void MM_maxDelayLimited_Out::pduInsertered(RMTQueue * q, RMTPort * p) {
76  queueInTime[q].push_back(simTime());
77 }
78 
79 void MM_maxDelayLimited_Out::pduDropped(RMTQueue * q, const cPacket * s, RMTPort * p) {
80  queueInTime[q].pop_back();
81 }
82 
83 void MM_maxDelayLimited_Out::pduReleased(RMTQueue * q, RMTPort * p) {}
84 
85 void MM_maxDelayLimited_Out::queueCreated(RMTQueue * q, RMTPort * p) {
86  portQueues[p].insert(q);
87  if(queueName2Delay.find(q->getName()) != queueName2Delay.end()) {
88  queueDelay[q] = queueName2Delay[q->getName()];
89  } else {
90  queueDelay[q] = defaultMaxDel;
91  }
92 
93  queueBurstCount[q];
94  if(queueName2BurstTime.find(q->getName()) != queueName2BurstTime.end() && queueName2BurstSize.find(q->getName()) != queueName2BurstSize.end() ) {
95  queueBurstCount[q].set(queueName2BurstTime[q->getName()], queueName2BurstSize[q->getName()]);
96  }
97 
98 }
99 
100 RMTQueue * MM_maxDelayLimited_Out::getnextQueue(RMTPort * p) {
101  RMTQueue * ret = NULL;
102  simtime_t min = SimTime::getMaxTime();
103  simtime_t now = simTime();
104 
105  double tic;//, toc = 50;
106 
107 
108  for(auto & q : portQueues[p]) {
109  if(!queueInTime[q].empty()) {
110  tic = queueBurstCount[q].tic(q->getFirstPDU()->getByteLength());
111  if(tic < 1.0) {
112  simtime_t temp = queueDelay[q] - now + queueInTime[q].front();
113  if(temp < 0) { temp *= queueMultip[q]; }
114  if(temp < min) {
115  ret = q;
116  min = temp;
117  // toc = tic;
118  }
119  }
120  }
121  }
122 
123  if(ret != NULL) {
124  queueInTime[ret].pop_front();
125  queueBurstCount[ret].in(ret->getFirstPDU()->getByteLength());
126  }
127  return ret;
128 }
129 
130 simtime_t MM_maxDelayLimited_Out::getnextTime(RMTPort * p) {
131  simtime_t time = SimTime::getMaxTime();
132  for(auto & q : portQueues[p]) {
133  if(!queueInTime[q].empty()) {
134  simtime_t t = queueBurstCount[q].getTime(q->getFirstPDU()->getByteLength());
135  if(t < time) { time = t; }
136  }
137  }
138  if(time < SimTime::getMaxTime()) {
139  return time;
140  } else {
141  return 0.0;
142  }
143 }
144 
145 }
const cPacket * getFirstPDU() const
Definition: RMTQueue.cc:271
Define_Module(MM_maxDelayLimited_Out)