RINASim  October 2016
Documentation of framework for OMNeT++
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MM_eDL_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_eDL_Out.h>
19 
20 namespace MM_eDL_Out {
21 
23 
24 void MM_eDL_Out::initialize() {
25  defaultPriority = par("defPriority").longValue();
26  if(defaultPriority < 0) { error("Error at eDL_Out. defPriority must be >=0!"); }
27 
28  maxPriority = defaultPriority;
29 
30  cXMLElement* Xml = NULL;
31  if (par("data").xmlValue() != NULL && par("data").xmlValue()->hasChildren()){
32  Xml = par("data").xmlValue();
33  } else {
34  return;
35  }
36  cXMLElementList queues = Xml->getChildrenByTagName("queue");
37  for(auto queue : queues){
38  if (!queue->getAttribute("id")) { error("Error parsing eDL_Out Queue. Its ID is missing!"); }
39  std::string id = queue->getAttribute("id");
40  if (id=="") { error("Error parsing eDL_Out Queue. Queue ID cannot be empty!"); }
41 
42  if (!queue->getAttribute("priority")) { error("Error parsing eDL_Out Queue. Its Priority is missing!"); }
43  int priority = atoi(queue->getAttribute("priority"));
44  if (priority<0) { error("Error parsing eDL_Out Queue. Queue Priority must be >=0!"); }
45 
46  queueName2Priority[id] = priority;
47 
48  if(maxPriority<priority) { maxPriority = priority ; }
49  }
50 
51 
52 
53  if (par("data2").xmlValue() != NULL && par("data2").xmlValue()->hasChildren()){
54  Xml = par("data2").xmlValue();
55  } else {
56  return;
57  }
58  cXMLElementList priorities = Xml->getChildrenByTagName("priority");
59  for(auto priority : priorities){
60  if (!priority->getAttribute("val")) { error("Error parsing eDL_Out Priority. Its val is missing!"); }
61  int id = atoi(priority->getAttribute("val"));
62  if (id<=0) { error("Error parsing eDL_Out Priority. Priority val cannot be <=0!"); }
63 
64  if (!priority->getAttribute("prob")) { error("Error parsing eDL_Out Priority. Its prob is missing!"); }
65  double prob = atof(priority->getAttribute("prob"));
66  if (prob<0 || prob >1) { error("Error parsing eDL_Out Priority. Priority prob must be between 0 and 1!"); }
67 
68  prioritySkip[maxPriority-id] = prob;
69  }
70 }
71 
72 MM_eDL_Out::~MM_eDL_Out(){}
73 
74 void MM_eDL_Out::finish() {}
75 
76 void MM_eDL_Out::pduInsertered(RMTQueue * q, RMTPort * p) {
77  portQueues[p][queuePriority[q]].push_back(q);
78 }
79 
80 void MM_eDL_Out::pduDropped(RMTQueue * q, const cPacket * s, RMTPort * p) {
81  portQueues[p][queuePriority[q]].pop_back();
82 }
83 
84 void MM_eDL_Out::pduReleased(RMTQueue * q, RMTPort * p) {}
85 
86 void MM_eDL_Out::queueCreated(RMTQueue * q, RMTPort * p) {
87  if(queueName2Priority.find(q->getName()) != queueName2Priority.end()) {
88  queuePriority[q] = maxPriority-queueName2Priority[q->getName()];
89  } else {
90  queuePriority[q] = maxPriority-defaultPriority;
91  }
92 }
93 
94 RMTQueue * MM_eDL_Out::getnextQueue(RMTPort * p) {
95  int selP = -1;
96 
97  for(auto &pQ : portQueues[p]) {
98  if(!pQ.second.empty()) {
99  selP = pQ.first;
100 
101  // std::cout << selP << " => " << prioritySkip[selP] << endl;
102  if(uniform(0.0, 1.0) >= prioritySkip[selP]) { break; }
103  }
104  }
105 
106  if(selP < 0) { return NULL; }
107 
108  RMTQueue * q = portQueues[p][selP].front();
109  portQueues[p][selP].pop_front();
110  return q;
111 }
112 
113 simtime_t MM_eDL_Out::getnextTime(RMTPort * p) {
114  return 0;
115 }
116 
117 }
Define_Module(MM_eDL_Out)