OverSim
UnderlayConfigurator.cc
Go to the documentation of this file.
1 //
2 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (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 General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18 
24 #include <omnetpp.h>
25 #include <GlobalNodeListAccess.h>
26 #include <ChurnGeneratorAccess.h>
27 #include <GlobalStatisticsAccess.h>
28 
29 #include "UnderlayConfigurator.h"
30 
31 const int32_t UnderlayConfigurator::NUM_COLORS=8;
32 const char* UnderlayConfigurator::colorNames[] = {
33  "red", "green", "yellow", "brown", "grey", "violet", "pink", "orange"};
34 
35 
37 {
38  endSimulationTimer = NULL;
40  endTransitionTimer = NULL;
41  initFinishedTime.tv_sec = 0;
42  initFinishedTime.tv_usec = 0;
43 }
44 
46 {
47  cancelAndDelete(endSimulationNotificationTimer);
48  cancelAndDelete(endSimulationTimer);
49  cancelAndDelete(endTransitionTimer);
50 }
51 
53 {
54  return MAX_STAGE_UNDERLAY + 1;
55 }
56 
58 {
59  if (stage == MIN_STAGE_UNDERLAY) {
60  gracefulLeaveDelay = par("gracefulLeaveDelay");
61  gracefulLeaveProbability = par("gracefulLeaveProbability");
62 
63  transitionTime = par("transitionTime");
64  measurementTime = par("measurementTime");
65 
68 
70  new cMessage("endSimulationNotificationTimer");
71  endSimulationTimer = new cMessage("endSimulationTimer");
72  endTransitionTimer = new cMessage("endTransitionTimer");
73 
74  gettimeofday(&initStartTime, NULL);
75  init = true;
76  simulationEndingSoon = false;
77  initCounter = 0;
78 
79  firstNodeId = -1;
80  WATCH(firstNodeId);
81  WATCH(overlayTerminalCount);
82  }
83 
84  if (stage >= MIN_STAGE_UNDERLAY && stage <= MAX_STAGE_UNDERLAY) {
85  initializeUnderlay(stage);
86  }
87 
88  if (stage == MAX_STAGE_UNDERLAY) {
89  // Create churn generators
90  NodeType t;
91  t.typeID = 0;
92 
93  std::vector<std::string> churnGeneratorTypes =
94  cStringTokenizer(par("churnGeneratorTypes"), " ").asVector();
95  std::vector<std::string> terminalTypes =
96  cStringTokenizer(par("terminalTypes"), " ").asVector();
97 
98  if (terminalTypes.size() != 1
99  && churnGeneratorTypes.size() != terminalTypes.size())
100  {
101  opp_error("UnderlayConfigurator.initialize(): "
102  "terminalTypes size does not match churnGenerator size");
103  }
104 
105  for (std::vector<std::string>::iterator it =
106  churnGeneratorTypes.begin(); it != churnGeneratorTypes.end(); ++it) {
107 
108  cModuleType* genType = cModuleType::get(it->c_str());
109 
110  if (genType == NULL) {
111  throw cRuntimeError((std::string("UnderlayConfigurator::"
112  "initialize(): invalid churn generator: ") + *it).c_str());
113  }
114 
115  ChurnGenerator* gen = check_and_cast<ChurnGenerator*>
116  (genType->create("churnGenerator",
117  getParentModule(),
118  t.typeID + 1, t.typeID));
119 
120  // check threshold for noChurnThreshold hack
121  gen->finalizeParameters();
122 
123  if ((*it == "oversim.common.LifetimeChurn" ||
124  *it == "oversim.common.ParetoChurn") &&
125  ((double)gen->par("noChurnThreshold") > 0) &&
126  ((double)gen->par("lifetimeMean") >=
127  (double)gen->par("noChurnThreshold"))) {
128  gen->callFinish();
129  gen->deleteModule();
130  cModuleType* genType =
131  cModuleType::get("oversim.common.NoChurn");
132  gen = check_and_cast<ChurnGenerator*>
133  (genType->create("churnGenerator", getParentModule(),
134  t.typeID + 1, t.typeID));
135  gen->finalizeParameters();
136  EV << "[UnderlayConfigurator::initialize()]\n"
137  << " churnGenerator[" << t.typeID
138  << "]: \"oversim.common.NoChurn\" is used instead of \""
139  << *it << "\"!\n (lifetimeMean exceeds noChurnThreshold)"
140  << endl;
141  }
142 
143  // Add it to the list of generators and initialize it
144  churnGenerator.push_back(gen);
145  t.terminalType = (terminalTypes.size() == 1) ?
146  terminalTypes[0] :
147  terminalTypes[it - churnGeneratorTypes.begin()];
148 
149  gen->setNodeType(t);
150  gen->buildInside();
151  t.typeID++;
152  }
153  }
154 }
155 
157 {
158  Enter_Method_Silent();
159 
160  if (++initCounter == churnGenerator.size() || !churnGenerator.size()) {
161  init = false;
162  gettimeofday(&initFinishedTime, NULL);
163 
164  scheduleAt(simTime() + transitionTime,
166 
167  if (measurementTime >= 0) {
168  scheduleAt(simTime() + transitionTime + measurementTime,
170 
172  throw cRuntimeError("UnderlayConfigurator::initFinished():"
173  " gracefulLeaveDelay must be bigger "
174  "than transitionTime + measurementTime!");
175  }
176 
177  scheduleAt(simTime() + transitionTime + measurementTime
180  }
181  consoleOut("INIT phase finished");
182  }
183 }
184 
186 {
187  if (msg == endSimulationNotificationTimer) {
188  simulationEndingSoon = true;
189  // globalNodeList->sendNotificationToAllPeers(NF_OVERLAY_NODE_LEAVE);
190  } else if (msg == endSimulationTimer) {
191  endSimulation();
192  } else if (msg == endTransitionTimer) {
193  consoleOut("transition time finished");
195  } else {
196  handleTimerEvent(msg);
197  }
198 }
199 
201 {
202  delete msg;
203 }
204 
206 {
207  finishUnderlay();
208 }
209 
211 {
212  //...
213 }
214 
215 void UnderlayConfigurator::consoleOut(const std::string& text)
216 {
217  if (!ev.isGUI()) {
218  struct timeval now, diff;
219  gettimeofday(&now, NULL);
220  diff = timeval_substract(now, initStartTime);
221 
222  std::stringstream ss;
223  std::string line1(71, '*');
224  std::string line2(71, '*');
225 
226  ss << " " << text << " ";
227  line1.replace(35 - ss.str().size() / 2,
228  ss.str().size(),
229  ss.str());
230  ss.str("");
231 
232  ss << " (sim time: " << simTime()
233  << ", real time: " << diff.tv_sec
234  << "." << diff.tv_usec << ") ";
235  line2.replace(35 - ss.str().size() / 2,
236  ss.str().size(),
237  ss.str());
238 
239  std::cout << "\n" << line1 << "\n"
240  << line2 << "\n" << std::endl;
241  } else {
242  EV << "[UnderlayConfigurator::consoleOut()] " << text;
243  }
244 }
245 
247 {
248  Enter_Method_Silent();
249 
250  return churnGenerator[typeID];
251 }
252 
254 {
255  Enter_Method_Silent();
256 
257  return churnGenerator.size();
258 }