RINASim  October 2016
Documentation of framework for OMNeT++
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TKMonitor.cc
Go to the documentation of this file.
1 //
2 // The MIT License (MIT)
3 //
4 // Copyright (c) 2014-2016 Brno University of Technology, PRISTINE project
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 // THE SOFTWARE.
23 
24 #include <TKMonitor.h>
25 
26 namespace TKMonitor {
27 
29 
31  id = "outQ_";
32  tokensTic = 1;
33  maxTokens = 5;
34 }
35 TKInfo::TKInfo(std::string _id){
36  id = _id;
37  tokensTic = 1;
38  maxTokens = 5;
39 }
40 TKInfo::TKInfo(std::string _id, int _tokensTic, int _maxTokens) {
41  id = _id;
42  tokensTic = _tokensTic;
43  maxTokens = _maxTokens;
44 }
46  info = TKInfo();
47  tokens = 0;
48  count = 0;
49 }
51  info = _info;
52  tokens = 0;
53  count = 0;
54 }
55 
56 void TKMonitor::onPolicyInit(){
57 
58  cXMLElement* tkXml = NULL;
59  if (par("tkData").xmlValue() != NULL && par("tkData").xmlValue()->hasChildren()){
60  tkXml = par("tkData").xmlValue();
61  } else {
62  error("cuData parameter not initialized!");
63  }
64 
65  cXMLElementList tks = tkXml->getChildrenByTagName("TKItem");
66  for(cXMLElement * m : tks){
67  if (!m->getAttribute("id")) {
68  EV << "Error parsing TK. Its ID is missing!" << endl;
69  continue;
70  }
71 
72  TKInfo inf = TKInfo(m->getAttribute("id"));
73 
74  cXMLElementList attrs = m->getChildren();
75  for(cXMLElement * n : attrs) {
76  if ( !strcmp(n->getTagName(), "tokensTic") ) {
77  inf.tokensTic = n->getNodeValue() ? atoi(n->getNodeValue()) : 0;
78  if (inf.tokensTic <= 0) { inf.tokensTic = 1; }
79  }
80 
81  if ( !strcmp(n->getTagName(), "maxTokens") ) {
82  inf.maxTokens = n->getNodeValue() ? atoi(n->getNodeValue()) : 0;
83  if (inf.maxTokens <= 0) { inf.maxTokens = 1; }
84  }
85  }
86 
87  TKs[inf.id] = inf;
88  }
89 
90  tokensPDU = par("tokensPDU").longValue();
91 }
92 
93 void TKMonitor::postPDUInsertion(RMTQueue* queue) {
94  RMTPort* port = rmtAllocator->getQueueToPortMapping(queue);
95  if(port != NULL){
96  if(queue->getType() == RMTQueue::INPUT){
97  inC[port] ++;
98  inQ[port].push_back(queue);
99  }
100  if(queue->getType() == RMTQueue::OUTPUT){
101  outC[port] ++;
102  Qs[queue].count++;
103  }
104  }
105 }
106 
107 void TKMonitor::onMessageDrop(RMTQueue* queue, const cPacket* pdu) {
108  RMTPort* port = rmtAllocator->getQueueToPortMapping(queue);
109  if(port != NULL){
110  if(queue->getType() == RMTQueue::INPUT){
111  inC[port] --;
112  inQ[port].pop_back();
113  } else {
114  outC[port] --;
115  Qs[queue].count--;
116  }
117  }
118 }
119 
120 void TKMonitor::postQueueCreation(RMTQueue* queue){
121  if(queue->getType() == RMTQueue::OUTPUT) {
122  TKInfo t = TKs["BE"];
123  for(auto info : TKs) {
124  if(queue->getName() == info.second.id) {
125  t = info.second;
126  }
127  }
128  Qs[queue].info = t;
129  RMTPort* port = rmtAllocator->getQueueToPortMapping(queue);
130  OutSet[port].insert(queue);
131  }
132 
133 }
134 
135 RMTQueue* TKMonitor::getNextInput(RMTPort* port){
136  RMTQueue* q = NULL;
137 
138  QueuesList* ql = &(inQ[port]);
139  if(!ql->empty()) {
140  q = ql->front();
141  ql->pop_front();
142  }
143 
144  if(q != NULL){
145  inC[port]--;
146  }
147 
148  return q;
149 }
150 
151 RMTQueue* TKMonitor::getNextOutput(RMTPort* port){
152  RMTQueue* ret = NULL;
153 
154  int maxT = -1;
155  int maxC = 0;
156  for(RMTQueue * q : OutSet[port]) {
157  QTKStatus * info = &Qs[q];
158 
159  if(info->count > 0) {
160  if(info->tokens > maxT) {
161  maxC = info->count;
162  maxT = info->tokens;
163  ret = q;
164  } else if (info->tokens == maxT && info->count > maxC) {
165  maxC = info->count;
166  ret = q;
167  }
168  }
169  info->tokens = min(info->info.tokensTic + info->tokens, info->info.maxTokens);
170 
171  }
172 
173  if(ret != NULL){
174  outC[port]--;
175  QTKStatus * info = &Qs[ret];
176  info->count--;
177  info->tokens = max(0, info->tokens-tokensPDU);
178  }
179 
180  return ret;
181 }
182 
183 double TKMonitor::getInDropProb(RMTQueue * queue) {
184  RMTPort* port = rmtAllocator->getQueueToPortMapping(queue);
185  if(port == NULL){ error("RMTPort for RMTQueue not found."); }
186 
187  return ( (int)inC[port] < queue->getMaxLength() )? 0 : 1;
188 }
189 
190 double TKMonitor::getOutDropProb(RMTQueue * queue) {
191  RMTPort* port = rmtAllocator->getQueueToPortMapping(queue);
192  if(port == NULL){ error("RMTPort for RMTQueue not found."); }
193 
194  return ( (int)outC[port] < queue->getMaxLength() )? 0 : 1;
195 }
196 
197 }
Define_Module(TKMonitor)
queueType getType() const
Definition: RMTQueue.cc:241
int getMaxLength() const
Definition: RMTQueue.cc:215
list< RMTQueue * > QueuesList
Definition: TKMonitor.h:38