UnderlayConfigurator.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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         // Create churn generators
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             // check threshold for noChurnThreshold hack
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             // Add it to the list of generators and initialize it
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         // globalNodeList->sendNotificationToAllPeers(NF_OVERLAY_NODE_LEAVE);
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 }
Generated on Wed May 26 16:21:15 2010 for OverSim by  doxygen 1.6.3