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 int32_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 t.typeID = 0;
00092
00093 std::vector<std::string> churnGeneratorTypes =
00094 cStringTokenizer(par("churnGeneratorTypes"), " ").asVector();
00095 std::vector<std::string> terminalTypes =
00096 cStringTokenizer(par("terminalTypes"), " ").asVector();
00097
00098 if (terminalTypes.size() != 1
00099 && churnGeneratorTypes.size() != terminalTypes.size())
00100 {
00101 opp_error("UnderlayConfigurator.initialize(): "
00102 "terminalTypes size does not match churnGenerator size");
00103 }
00104
00105 for (std::vector<std::string>::iterator it =
00106 churnGeneratorTypes.begin(); it != churnGeneratorTypes.end(); ++it) {
00107
00108 cModuleType* genType = cModuleType::get(it->c_str());
00109
00110 if (genType == NULL) {
00111 throw cRuntimeError((std::string("UnderlayConfigurator::"
00112 "initialize(): invalid churn generator: ") + *it).c_str());
00113 }
00114
00115 ChurnGenerator* gen = check_and_cast<ChurnGenerator*>
00116 (genType->create("churnGenerator",
00117 getParentModule(),
00118 t.typeID + 1, t.typeID));
00119
00120
00121 gen->finalizeParameters();
00122
00123 if ((*it == "oversim.common.LifetimeChurn" ||
00124 *it == "oversim.common.ParetoChurn") &&
00125 ((double)gen->par("noChurnThreshold") > 0) &&
00126 ((double)gen->par("lifetimeMean") >=
00127 (double)gen->par("noChurnThreshold"))) {
00128 gen->callFinish();
00129 gen->deleteModule();
00130 cModuleType* genType =
00131 cModuleType::get("oversim.common.NoChurn");
00132 gen = check_and_cast<ChurnGenerator*>
00133 (genType->create("churnGenerator", getParentModule(),
00134 t.typeID + 1, t.typeID));
00135 gen->finalizeParameters();
00136 EV << "[UnderlayConfigurator::initialize()]\n"
00137 << " churnGenerator[" << t.typeID
00138 << "]: \"oversim.common.NoChurn\" is used instead of \""
00139 << *it << "\"!\n (lifetimeMean exceeds noChurnThreshold)"
00140 << endl;
00141 }
00142
00143
00144 churnGenerator.push_back(gen);
00145 t.terminalType = (terminalTypes.size() == 1) ?
00146 terminalTypes[0] :
00147 terminalTypes[it - churnGeneratorTypes.begin()];
00148
00149 gen->setNodeType(t);
00150 gen->buildInside();
00151 t.typeID++;
00152 }
00153 }
00154 }
00155
00156 void UnderlayConfigurator::initFinished()
00157 {
00158 Enter_Method_Silent();
00159
00160 if (++initCounter == churnGenerator.size() || !churnGenerator.size()) {
00161 init = false;
00162 gettimeofday(&initFinishedTime, NULL);
00163
00164 scheduleAt(simTime() + transitionTime,
00165 endTransitionTimer);
00166
00167 if (measurementTime >= 0) {
00168 scheduleAt(simTime() + transitionTime + measurementTime,
00169 endSimulationTimer);
00170
00171 if ((transitionTime + measurementTime) < gracefulLeaveDelay) {
00172 throw cRuntimeError("UnderlayConfigurator::initFinished():"
00173 " gracefulLeaveDelay must be bigger "
00174 "than transitionTime + measurementTime!");
00175 }
00176
00177 scheduleAt(simTime() + transitionTime + measurementTime
00178 - gracefulLeaveDelay,
00179 endSimulationNotificationTimer);
00180 }
00181 consoleOut("INIT phase finished");
00182 }
00183 }
00184
00185 void UnderlayConfigurator::handleMessage(cMessage* msg)
00186 {
00187 if (msg == endSimulationNotificationTimer) {
00188 simulationEndingSoon = true;
00189
00190 } else if (msg == endSimulationTimer) {
00191 endSimulation();
00192 } else if (msg == endTransitionTimer) {
00193 consoleOut("transition time finished");
00194 globalStatistics->startMeasuring();
00195 } else {
00196 handleTimerEvent(msg);
00197 }
00198 }
00199
00200 void UnderlayConfigurator::handleTimerEvent(cMessage* msg)
00201 {
00202 delete msg;
00203 }
00204
00205 void UnderlayConfigurator::finish()
00206 {
00207 finishUnderlay();
00208 }
00209
00210 void UnderlayConfigurator::finishUnderlay()
00211 {
00212
00213 }
00214
00215 void UnderlayConfigurator::consoleOut(const std::string& text)
00216 {
00217 if (!ev.isGUI()) {
00218 struct timeval now, diff;
00219 gettimeofday(&now, NULL);
00220 diff = timeval_substract(now, initStartTime);
00221
00222 std::stringstream ss;
00223 std::string line1(71, '*');
00224 std::string line2(71, '*');
00225
00226 ss << " " << text << " ";
00227 line1.replace(35 - ss.str().size() / 2,
00228 ss.str().size(),
00229 ss.str());
00230 ss.str("");
00231
00232 ss << " (sim time: " << simTime()
00233 << ", real time: " << diff.tv_sec
00234 << "." << diff.tv_usec << ") ";
00235 line2.replace(35 - ss.str().size() / 2,
00236 ss.str().size(),
00237 ss.str());
00238
00239 std::cout << "\n" << line1 << "\n"
00240 << line2 << "\n" << std::endl;
00241 } else {
00242 EV << "[UnderlayConfigurator::consoleOut()] " << text;
00243 }
00244 }
00245
00246 ChurnGenerator* UnderlayConfigurator::getChurnGenerator(int typeID)
00247 {
00248 Enter_Method_Silent();
00249
00250 return churnGenerator[typeID];
00251 }
00252
00253 uint8_t UnderlayConfigurator::getChurnGeneratorNum()
00254 {
00255 Enter_Method_Silent();
00256
00257 return churnGenerator.size();
00258 }