//========================================================================= // CLINKDELAYLOOKAHEAD.CC - part of // // OMNeT++/OMNEST // Discrete System Simulation in C++ // // Author: Andras Varga, 2003 // Dept. of Electrical and Computer Systems Engineering, // Monash University, Melbourne, Australia // //========================================================================= /*--------------------------------------------------------------* Copyright (C) 2003-2017 Andras Varga Copyright (C) 2006-2017 OpenSim Ltd. This file is distributed WITHOUT ANY WARRANTY. See the file `license' for details on this and other legal matters. *--------------------------------------------------------------*/ #include "omnetpp/csimulation.h" #include "omnetpp/cmessage.h" #include "omnetpp/cenvir.h" #include "omnetpp/cparsimcomm.h" #include "omnetpp/cchannel.h" #include "omnetpp/globals.h" #include "omnetpp/regmacros.h" #include "cadvlinkdelaylookahead.h" #include "cnullmessageprot.h" #include "cparsimpartition.h" #include "cplaceholdermod.h" #include "cproxygate.h" namespace omnetpp { Register_Class(cAdvancedLinkDelayLookahead); cAdvancedLinkDelayLookahead::cAdvancedLinkDelayLookahead() { numSeg = 0; segInfo = nullptr; } cAdvancedLinkDelayLookahead::~cAdvancedLinkDelayLookahead() { delete[] segInfo; } void cAdvancedLinkDelayLookahead::startRun() { EV << "starting Link Delay Lookahead...\n"; delete[] segInfo; numSeg = comm->getNumPartitions(); segInfo = new PartitionInfo[numSeg]; // temporarily initialize everything to zero. for (int i = 0; i < numSeg; i++) { segInfo[i].numLinks = 0; segInfo[i].links = nullptr; } // fill numLinks and links[] EV << " collecting links...\n"; // step 1: count gates for (int modId = 0; modId <= sim->getLastComponentId(); modId++) { cPlaceholderModule *mod = dynamic_cast(sim->getModule(modId)); if (mod) { for (cModule::GateIterator i(mod); !i.end(); i++) { cGate *g = i(); cProxyGate *pg = dynamic_cast(g); if (pg && pg->getPreviousGate() && pg->getRemoteProcId() >= 0) segInfo[pg->getRemoteProcId()].numLinks++; } } } // step 2: allocate links[] for (int i = 0; i < numSeg; i++) { int numLinks = segInfo[i].numLinks; segInfo[i].links = new LinkOut *[numLinks]; for (int k = 0; k < numLinks; k++) segInfo[i].links[k] = nullptr; } // step 3: fill in for (int modId = 0; modId <= sim->getLastComponentId(); modId++) { cPlaceholderModule *mod = dynamic_cast(sim->getModule(modId)); if (mod) { for (cModule::GateIterator i(mod); !i.end(); i++) { // if this is a properly connected proxygate, process it // FIXME leave out gates from other cPlaceholderModules cGate *g = i(); cProxyGate *pg = dynamic_cast(g); if (pg && pg->getPreviousGate() && pg->getRemoteProcId() >= 0) { // check we have a delay on this link (it gives us lookahead) cGate *fromg = pg->getPreviousGate(); cChannel *chan = fromg ? fromg->getChannel() : nullptr; cDatarateChannel *datarateChan = dynamic_cast(chan); cPar *delaypar = datarateChan ? datarateChan->getDelay() : nullptr; double linkDelay = delaypar ? delaypar->doubleValue() : 0; if (linkDelay <= 0.0) throw cRuntimeError("cAdvancedLinkDelayLookahead: Zero delay on link from gate '%s', no lookahead for parallel simulation", fromg->getFullPath().c_str()); // store int procId = pg->getRemoteProcId(); int k = 0; while (segInfo[procId].links[k]) k++; // find 1st empty slot LinkOut *link = new LinkOut; segInfo[procId].links[k] = link; pg->setSynchData(link); link->lookahead = linkDelay; link->eot = 0.0; EV << " link " << k << " to procId=" << procId << " on gate '" << fromg->getFullPath() <<"': delay=" << linkDelay << "\n"; } } } } EV << " setup done.\n"; } void cAdvancedLinkDelayLookahead::endRun() { } simtime_t cAdvancedLinkDelayLookahead::getCurrentLookahead(cMessage *msg, int procId, void *data) { // find LinkOut structure in segInfo[destProcId]. LinkOut *link = (LinkOut *)data; if (!link) throw cRuntimeError("Internal parallel simulation error: cProxyGate has no associated data pointer"); // calculate EOT simtime_t eot; simtime_t now = sim->getSimTime(); simtime_t newLinkEot = now + link->lookahead; // TBD finish... return 0.0; } simtime_t cAdvancedLinkDelayLookahead::getCurrentLookahead(int procId) { return segInfo[procId].lookahead; } } // namespace omnetpp