User Manual, Developers Guide and API Documentation

SubStrategy.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2009
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <WNS/scheduler/SchedulerTypes.hpp>
00029 #include <WNS/scheduler/strategy/staticpriority/SubStrategy.hpp>
00030 
00031 #include <vector>
00032 #include <map>
00033 
00034 using namespace wns::scheduler;
00035 using namespace wns::scheduler::strategy;
00036 using namespace wns::scheduler::strategy::staticpriority;
00037 
00038 
00039 SubStrategy::SubStrategy()
00040     : logger(std::string("WNS"), std::string("SubStrategy")),
00041       colleagues(),
00042       useDynamicSegmentation(false),
00043       minimumSegmentSize(-1),
00044       useHARQ(false)
00045 {
00046 }
00047 
00048 SubStrategy::SubStrategy(const wns::pyconfig::View& config)
00049     : logger(config.get("logger")),
00050       colleagues(),
00051       useDynamicSegmentation(false),
00052       minimumSegmentSize(-1),
00053       useHARQ(config.get<bool>("useHARQ"))
00054 {
00055 }
00056 
00057 void
00058 SubStrategy::setColleagues(wns::scheduler::strategy::Strategy* _strategy,
00059                            wns::scheduler::queue::QueueInterface* _queue,
00060                            wns::scheduler::RegistryProxyInterface* _registry,
00061                            wns::scheduler::harq::HARQInterface* _harq)
00062 {
00063     colleagues.strategy = _strategy;
00064     colleagues.queue = _queue;
00065     colleagues.registry = _registry;
00066     colleagues.harq = _harq;
00067     assure(colleagues.strategy!=NULL, "Need access to the strategy");
00068     assure(dynamic_cast<queue::QueueInterface*>(colleagues.queue), "Need access to the queue");
00069     assure(dynamic_cast<RegistryProxyInterface*>(colleagues.registry), "Need access to the registry");
00070     useDynamicSegmentation = colleagues.queue->supportsDynamicSegmentation();
00071     if (useDynamicSegmentation) {
00072         minimumSegmentSize = colleagues.queue->getMinimumSegmentSize();
00073     }
00074     this->initialize();
00075 }
00076 
00077 bool
00078 SubStrategy::scheduleCid(SchedulerStatePtr schedulerState,
00079                          wns::scheduler::SchedulingMapPtr schedulingMap,
00080                          const wns::scheduler::ConnectionID cid,
00081                          int& pduCounter, // modified
00082                          const int blockSize,
00083                          MapInfoCollectionPtr mapInfoCollection // result
00084     )
00085 {
00086     assure(pduCounter<blockSize,"required: pduCounter="<<pduCounter<<" < blockSize="<<blockSize);
00087     UserID userID = colleagues.registry->getUserForCID(cid);
00088     int queuedBits = colleagues.queue->getHeadOfLinePDUbits(cid);
00089     int requestedBits =
00090         (useDynamicSegmentation && (queuedBits>minimumSegmentSize)) ?
00091         minimumSegmentSize // ask for any free space of at least this size (so that there is always a chance of space; the real request is extended later after we know the PhyMode)
00092         :
00093         queuedBits;
00094     MESSAGE_SINGLE(NORMAL, logger, "scheduleCid(CID="<<cid<<" of "<<userID.getName()<<",#"<<pduCounter<<"): bits: "<<queuedBits<<" queued, "<<requestedBits<<" requested");
00095 
00096     // do resource scheduling here:
00097     RequestForResource request(cid,userID,requestedBits, queuedBits, useHARQ);
00098     MapInfoEntryPtr mapInfoEntry =
00099         colleagues.strategy->doAdaptiveResourceScheduling(request, schedulingMap);
00100     if (mapInfoEntry == MapInfoEntryPtr()) // no result
00101         return false;
00102     // ^ maybe it could make sense to try other connections here instead of aborting?
00103     // ^ they could have smaller PDUs, better PhyMode or oneUserOnOneSubChannel=true
00104     // Answer: which connection to choose is responsibility of the PacketScheduler (SubStrategy)
00105     int subChannel = mapInfoEntry->subBand;  // DSA result
00106     int timeSlot   = mapInfoEntry->timeSlot; // DSA result
00107     int spatialLayer       = mapInfoEntry->spatialLayer;     // DSA result
00108     simTimeType compoundStartTime = schedulingMap->getNextPosition(subChannel, timeSlot, spatialLayer);
00109     simTimeType allCompoundsEndTime = compoundStartTime;
00110     assure(compoundStartTime==schedulingMap->subChannels[subChannel].temporalResources[timeSlot]->physicalResources[spatialLayer].getNextPosition(),"mismatch in getNextPosition");
00111     mapInfoEntry->start = compoundStartTime;
00112     // ^ all the above is constant even if we schedule another compound of the same cid
00113     mapInfoEntry->sourceUser = schedulerState->myUserID;
00114 
00115     // this depends on phyMode and subChannel used so far:
00116     int freeBits = schedulingMap->getFreeBitsOnSubChannel(mapInfoEntry); // how much fits into the selected subChannel?
00117     // ^ can be used with DynamicSegmentation
00118     MESSAGE_SINGLE(NORMAL, logger, "scheduleCid(CID="<<cid<<" of "<<userID.getName()<<"): bits: "<<queuedBits<<" queued, "<<requestedBits<<" requested, "<<freeBits<<" free on sc="<<mapInfoEntry->subBand<<"."<<mapInfoEntry->timeSlot<<"."<<mapInfoEntry->spatialLayer);
00119     if (freeBits<=0) return false; // can be =0 if !subChannelIsUsable
00120     if (useDynamicSegmentation) {
00121         request.bits = freeBits;
00122         MESSAGE_SINGLE(NORMAL, logger, "scheduleCid(CID="<<cid<<" of "<<userID.getName()<<"): bits: "<<queuedBits<<" queued, "<<requestedBits<<" requested, "<<freeBits<<" free, get="<<request.bits);
00123         wns::ldk::CompoundPtr compoundPtr = colleagues.queue->getHeadOfLinePDUSegment(cid,request.bits);
00124         if (compoundPtr != wns::ldk::CompoundPtr()) // no fake
00125         { 
00126             request.bits = compoundPtr->getLengthInBits();
00127         }
00128         else // fake, use result from previous call to getHeadOfLinePDUbits or the free bit of resource if more data was queued
00129         {
00130             request.bits = freeBits < queuedBits?freeBits:queuedBits;
00131         }
00132         simTimeType compoundDuration = request.getDuration();
00133         MESSAGE_SINGLE(NORMAL, logger, "scheduleCid(CID="<<cid<<" of "<<userID.getName()<<"): getHeadOfLinePDUSegment("<<freeBits<<") => "<<request.bits<<" bits dequeued, d="<<compoundDuration*1e6<<"us");
00134         bool ok = schedulingMap->addCompound(request, mapInfoEntry, compoundPtr, useHARQ);
00135         assure(ok,"schedulingMap->addCompound("<<request.toString()<<") failed. mapInfoEntry="<<mapInfoEntry->toString());
00136         mapInfoEntry->compounds.push_back(compoundPtr); // (currentBurst)
00137         allCompoundsEndTime += compoundDuration;
00138         pduCounter++;
00139         freeBits -= request.bits;
00140     } else { // normal pre-segmented PDUs
00141         if (request.bits > freeBits) {
00142             MESSAGE_SINGLE(NORMAL, logger, "scheduleCid(CID="<<cid<<" of "<<userID.getName()<<"): request.bits="<<request.bits<<" do not fit into free "<<freeBits<<" bits.");
00143             return false;
00144         }
00145 
00146         // loop to put more pdus into the resource block if possible
00147         while (request.bits <= freeBits)
00148         { // try to put one (or more) pdus into this resource block
00149             wns::ldk::CompoundPtr compoundPtr = colleagues.queue->getHeadOfLinePDU(cid);
00150             MESSAGE_SINGLE(NORMAL, logger, "scheduleCid(CID="<<cid<<" of "<<userID.getName()<<"): request.bits="<<request.bits);
00151             bool ok = schedulingMap->addCompound(request, mapInfoEntry, compoundPtr, useHARQ);
00152             assure(ok,"schedulingMap->addCompound("<<request.toString()<<") failed. mapInfoEntry="<<mapInfoEntry->toString());
00153             mapInfoEntry->compounds.push_back(compoundPtr); // (currentBurst)
00154             allCompoundsEndTime += request.getDuration();
00155             pduCounter++;
00156             freeBits -= request.bits;
00157             // another one?
00158             if (colleagues.queue->queueHasPDUs(cid)) {
00159                 request.bits = colleagues.queue->getHeadOfLinePDUbits(cid);
00160                 // mapInfoEntry can be left unchanged (contains only invariants)
00161             } else {
00162                 break; // no more pdu in queue[cid]
00163             }
00164         } // while still space on subChannel
00165 
00166     } // no DynamicSegmentation
00167     mapInfoEntry->end = allCompoundsEndTime;
00168     mapInfoCollection->push_back(mapInfoEntry);
00169     MESSAGE_SINGLE(NORMAL, logger, "scheduleCid(CID="<<cid<<" of "<<userID.getName()<<"): start..end[us]="<<mapInfoEntry->start*1e6<<".."<<mapInfoEntry->end*1e6);
00170     MESSAGE_SINGLE(NORMAL, logger, "scheduleCid(CID="<<cid<<" of "<<userID.getName()<<"): next PDU on next subChannel...?");
00171     return true; // true means success
00172 } // scheduleCid
00173 
00174 bool
00175 SubStrategy::usesHARQ()
00176 {
00177     return useHARQ;
00178 }

Generated on Sat May 26 03:31:51 2012 for openWNS by  doxygen 1.5.5