![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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 }
1.5.5