UnderlayConfigurator.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <omnetpp.h>
00025 #include <GlobalNodeListAccess.h>
00026 #include <ChurnGeneratorAccess.h>
00027 #include <GlobalStatisticsAccess.h>
00028
00029 #include "UnderlayConfigurator.h"
00030
00031 const uint32_t UnderlayConfigurator::NUM_COLORS=8;
00032 const char* UnderlayConfigurator::colorNames[] = {
00033 "red", "green", "yellow", "brown", "grey", "violet", "pink", "orange"};
00034
00035
00036 UnderlayConfigurator::UnderlayConfigurator()
00037 {
00038 endSimulationTimer = NULL;
00039 endSimulationNotificationTimer = NULL;
00040 endTransitionTimer = NULL;
00041 initFinishedTime.tv_sec = 0;
00042 initFinishedTime.tv_usec = 0;
00043 }
00044
00045 UnderlayConfigurator::~UnderlayConfigurator()
00046 {
00047 cancelAndDelete(endSimulationNotificationTimer);
00048 cancelAndDelete(endSimulationTimer);
00049 cancelAndDelete(endTransitionTimer);
00050 }
00051
00052 int UnderlayConfigurator::numInitStages() const
00053 {
00054 return MAX_STAGE_UNDERLAY + 1;
00055 }
00056
00057 void UnderlayConfigurator::initialize(int stage)
00058 {
00059 if (stage == MIN_STAGE_UNDERLAY) {
00060 gracefulLeaveDelay = par("gracefulLeaveDelay");
00061 gracefulLeaveProbability = par("gracefulLeaveProbability");
00062
00063 transitionTime = par("transitionTime");
00064 measurementTime = par("measurementTime");
00065
00066 globalNodeList = GlobalNodeListAccess().get();
00067 globalStatistics = GlobalStatisticsAccess().get();
00068
00069 endSimulationNotificationTimer =
00070 new cMessage("endSimulationNotificationTimer");
00071 endSimulationTimer = new cMessage("endSimulationTimer");
00072 endTransitionTimer = new cMessage("endTransitionTimer");
00073
00074 gettimeofday(&initStartTime, NULL);
00075 init = true;
00076 simulationEndingSoon = false;
00077 initCounter = 0;
00078
00079 firstNodeId = -1;
00080 WATCH(firstNodeId);
00081 WATCH(overlayTerminalCount);
00082 }
00083
00084 if (stage >= MIN_STAGE_UNDERLAY && stage <= MAX_STAGE_UNDERLAY) {
00085 initializeUnderlay(stage);
00086 }
00087
00088 if (stage == MAX_STAGE_UNDERLAY) {
00089
00090 NodeType t;
00091 std::vector<std::string> churnGeneratorTypes =
00092 cStringTokenizer(par("churnGeneratorTypes"), " ").asVector();
00093 std::vector<std::string> terminalTypes =
00094 cStringTokenizer(par("terminalTypes"), " ").asVector();
00095
00096 if (terminalTypes.size() != 1
00097 && churnGeneratorTypes.size() != terminalTypes.size())
00098 {
00099 opp_error("UnderlayConfigurator.initialize(): "
00100 "terminalTypes size does not match churnGenerator size");
00101 }
00102
00103 for (std::vector<std::string>::iterator it =
00104 churnGeneratorTypes.begin(); it != churnGeneratorTypes.end(); ++it) {
00105
00106 cModuleType* genType = cModuleType::get(it->c_str());
00107
00108 if (genType == NULL) {
00109 throw cRuntimeError((std::string("UnderlayConfigurator::"
00110 "initialize(): invalid churn generator: ") + *it).c_str());
00111 }
00112
00113 ChurnGenerator* gen = check_and_cast<ChurnGenerator*>
00114 (genType->create("churnGenerator",
00115 getParentModule(),
00116 t.typeID + 1, t.typeID));
00117
00118
00119 gen->finalizeParameters();
00120
00121 if ((*it == "oversim.common.LifetimeChurn" ||
00122 *it == "oversim.common.ParetoChurn") &&
00123 ((double)gen->par("noChurnThreshold") > 0) &&
00124 ((double)gen->par("lifetimeMean") >=
00125 (double)gen->par("noChurnThreshold"))) {
00126 gen->callFinish();
00127 gen->deleteModule();
00128 cModuleType* genType =
00129 cModuleType::get("oversim.common.NoChurn");
00130 gen = check_and_cast<ChurnGenerator*>
00131 (genType->create("churnGenerator", getParentModule(),
00132 t.typeID + 1, t.typeID));
00133 gen->finalizeParameters();
00134 EV << "[UnderlayConfigurator::initialize()]\n"
00135 << " churnGenerator[" << t.typeID
00136 << "]: \"oversim.common.NoChurn\" is used instead of \""
00137 << *it << "\"!\n (lifetimeMean exceeds noChurnThreshold)"
00138 << endl;
00139 }
00140
00141
00142 churnGenerator.push_back(gen);
00143 t.typeID++;
00144 t.terminalType = (terminalTypes.size() == 1) ?
00145 terminalTypes[0] :
00146 terminalTypes[it - churnGeneratorTypes.begin()];
00147
00148 gen->setNodeType(t);
00149 gen->buildInside();
00150 }
00151 }
00152 }
00153
00154 void UnderlayConfigurator::initFinished()
00155 {
00156 Enter_Method_Silent();
00157
00158 if (++initCounter == churnGenerator.size() || !churnGenerator.size()) {
00159 init = false;
00160 gettimeofday(&initFinishedTime, NULL);
00161
00162 scheduleAt(simTime() + transitionTime,
00163 endTransitionTimer);
00164
00165 if (measurementTime >= 0) {
00166 scheduleAt(simTime() + transitionTime + measurementTime,
00167 endSimulationTimer);
00168
00169 if ((transitionTime + measurementTime) < gracefulLeaveDelay) {
00170 throw cRuntimeError("UnderlayConfigurator::initFinished():"
00171 " gracefulLeaveDelay must be bigger "
00172 "than transitionTime + measurementTime!");
00173 }
00174
00175 scheduleAt(simTime() + transitionTime + measurementTime
00176 - gracefulLeaveDelay,
00177 endSimulationNotificationTimer);
00178 }
00179 consoleOut("INIT phase finished");
00180 }
00181 }
00182
00183 void UnderlayConfigurator::handleMessage(cMessage* msg)
00184 {
00185 if (msg == endSimulationNotificationTimer) {
00186 simulationEndingSoon = true;
00187
00188 } else if (msg == endSimulationTimer) {
00189 endSimulation();
00190 } else if (msg == endTransitionTimer) {
00191 consoleOut("transition time finished");
00192 globalStatistics->startMeasuring();
00193 } else {
00194 handleTimerEvent(msg);
00195 }
00196 }
00197
00198 void UnderlayConfigurator::handleTimerEvent(cMessage* msg)
00199 {
00200 delete msg;
00201 }
00202
00203 void UnderlayConfigurator::finish()
00204 {
00205 finishUnderlay();
00206 }
00207
00208 void UnderlayConfigurator::finishUnderlay()
00209 {
00210
00211 }
00212
00213 void UnderlayConfigurator::consoleOut(const std::string& text)
00214 {
00215 if (!ev.isGUI()) {
00216 struct timeval now, diff;
00217 gettimeofday(&now, NULL);
00218 diff = timeval_substract(now, initStartTime);
00219
00220 std::stringstream ss;
00221 std::string line1(71, '*');
00222 std::string line2(71, '*');
00223
00224 ss << " " << text << " ";
00225 line1.replace(35 - ss.str().size() / 2,
00226 ss.str().size(),
00227 ss.str());
00228 ss.str("");
00229
00230 ss << " (sim time: " << simTime()
00231 << ", real time: " << diff.tv_sec
00232 << "." << diff.tv_usec << ") ";
00233 line2.replace(35 - ss.str().size() / 2,
00234 ss.str().size(),
00235 ss.str());
00236
00237 std::cout << "\n" << line1 << "\n"
00238 << line2 << "\n" << std::endl;
00239 } else {
00240 EV << "[UnderlayConfigurator::consoleOut()] " << text;
00241 }
00242 }
00243
00244 ChurnGenerator* UnderlayConfigurator::getChurnGenerator(int typeID)
00245 {
00246 Enter_Method_Silent();
00247
00248 return churnGenerator[typeID];
00249 }
00250
00251 uint8_t UnderlayConfigurator::getChurnGeneratorNum()
00252 {
00253 Enter_Method_Silent();
00254
00255 return churnGenerator.size();
00256 }