![]() |
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/strategy/staticpriority/HARQRetransmission.hpp> 00029 #include <WNS/scheduler/SchedulerTypes.hpp> 00030 00031 #include <vector> 00032 #include <map> 00033 #include <algorithm> 00034 #include <iostream> 00035 00036 using namespace std; 00037 using namespace wns::scheduler; 00038 using namespace wns::scheduler::strategy; 00039 using namespace wns::scheduler::strategy::staticpriority; 00040 00041 STATIC_FACTORY_REGISTER_WITH_CREATOR(HARQRetransmission, 00042 SubStrategyInterface, 00043 "HARQRetransmission", 00044 wns::PyConfigViewCreator); 00045 00046 00047 HARQRetransmission::HARQRetransmission(const wns::pyconfig::View& config) 00048 : SubStrategy(config) 00049 { 00050 blockSize=INT_MAX; // ExhaustiveRoundRobin=RoundRobin with infinite blockSize 00051 MESSAGE_SINGLE(NORMAL, logger, "HARQRetransmission(): constructed"); 00052 } 00053 00054 HARQRetransmission::~HARQRetransmission() 00055 { 00056 } 00057 00058 void 00059 HARQRetransmission::initialize() 00060 { 00061 // make state 00062 lastScheduledConnection = 0; 00063 //colleagues.harq->initialize(); // TODO! 00064 MESSAGE_SINGLE(NORMAL, logger, "HARQRetransmission(): initialized"); 00065 } 00066 00067 wns::scheduler::ConnectionID 00068 HARQRetransmission::getValidCurrentConnection(const ConnectionSet ¤tConnections, ConnectionID cid) const 00069 { 00070 MESSAGE_SINGLE(NORMAL, logger, "HARQRetransmission::getValidCurrentConnection"); 00071 // uses state var currentConnections 00072 wns::scheduler::ConnectionSet::iterator iter = 00073 currentConnections.upper_bound(cid); 00074 if ( iter != currentConnections.end() ) { // exists 00075 return *iter; 00076 } else { // continue with next higher cid 00077 return *currentConnections.begin(); 00078 } 00079 //MESSAGE_SINGLE(NORMAL, logger, "getValidCurrentConnection("<<cid<<") = "); 00080 } 00081 00082 wns::scheduler::ConnectionID 00083 HARQRetransmission::getNextConnection(const ConnectionSet ¤tConnections, ConnectionID cid) const 00084 { 00085 MESSAGE_SINGLE(NORMAL, logger, "HARQRetransmission::getNextConnection"); 00086 // uses state var currentConnections 00087 wns::scheduler::ConnectionSet::iterator iter = 00088 currentConnections.upper_bound(cid); 00089 if ( iter != currentConnections.end() ) { // found 00090 if ( *iter == cid ) { // go on 00091 iter++; 00092 } else { 00093 return *iter; 00094 } 00095 } 00096 if ( iter != currentConnections.end() ) { // exists 00097 return *iter; 00098 } else { // continue with next higher cid 00099 return *currentConnections.begin(); 00100 } 00101 //MESSAGE_SINGLE(NORMAL, logger, "getNextConnection("<<cid<<") = "); 00102 } 00103 00104 std::vector<int> 00105 HARQRetransmission::getUsableSubChannelsIDs(wns::scheduler::UserID user, const wns::scheduler::SchedulingMapPtr& schedulingMap) 00106 { 00107 std::vector<int> result; 00108 00109 for (wns::scheduler::SubChannelVector::const_iterator iterSubChannel = schedulingMap->subChannels.begin(); 00110 iterSubChannel != schedulingMap->subChannels.end(); 00111 ++iterSubChannel 00112 ) 00113 { 00114 const SchedulingSubChannel& subChannel = *iterSubChannel; 00115 int subChannelIndex = subChannel.subChannelIndex; 00116 00117 // Is it blocked? 00118 if (!subChannel.subChannelIsUsable) continue; 00119 00120 for ( SchedulingTimeSlotPtrVector::const_iterator iterTimeSlot = subChannel.temporalResources.begin(); 00121 iterTimeSlot != subChannel.temporalResources.end(); ++iterTimeSlot) 00122 { 00123 const SchedulingTimeSlotPtr timeSlotPtr = *iterTimeSlot; 00124 int timeSlotIndex = timeSlotPtr->timeSlotIndex; 00125 if ( ((!timeSlotPtr->getUserID().isValid()) || 00126 timeSlotPtr->getUserID() == user) && 00127 timeSlotPtr->countScheduledCompounds()==0) 00128 { // free space found. Pack it into. 00129 result.push_back(subChannel.subChannelIndex); 00130 } 00131 } 00132 } 00133 return result; 00134 } 00135 00136 wns::scheduler::MapInfoCollectionPtr 00137 HARQRetransmission::doStartSubScheduling(SchedulerStatePtr schedulerState, 00138 wns::scheduler::SchedulingMapPtr schedulingMap) 00139 { 00140 ConnectionSet ¤tConnections = schedulerState->currentState->activeConnections; 00141 assure(currentConnections.empty(), "HARQ retransmission cannot have active connections. This should not have happened."); 00142 00143 // harq colleague may be NULL, e.g. Uplink Master Scheduler does not have HARQ 00144 if(colleagues.harq == NULL) 00145 { 00146 MapInfoCollectionPtr mapInfoCollection = MapInfoCollectionPtr(new wns::scheduler::MapInfoCollection); 00147 MESSAGE_SINGLE(NORMAL, logger, "colleagues.harq==NULL is illegal. Please choose another strategy than HARQRetransmission"); 00148 return mapInfoCollection; 00149 } 00150 00151 assure(colleagues.harq!=NULL,"colleagues.harq==NULL is illegal. Please choose another strategy than HARQRetransmission"); 00152 00156 wns::scheduler::UserSet usersWithRetransmissions = colleagues.harq->getUsersWithRetransmissions(); 00157 00158 for (wns::scheduler::UserSet::iterator it = usersWithRetransmissions.begin(); 00159 it != usersWithRetransmissions.end(); 00160 ++it) 00161 { 00162 int processID = colleagues.harq->getProcessesWithRetransmissions(*it).front(); 00163 00164 int numberOfRetransmissions = colleagues.harq->getNumberOfRetransmissions(*it, processID); 00165 00166 MESSAGE_SINGLE(NORMAL, logger, "doStartSubScheduling: "<<numberOfRetransmissions<<" HARQ retransmission(s) waiting for user=" << it->getName() << " ,processID=" << processID); 00167 00168 wns::scheduler::SchedulingTimeSlotPtr resourceBlock = colleagues.harq->peekNextRetransmission(*it, processID); 00169 assure(resourceBlock != NULL, "resourceBlock == NULL although numberOfRetransmissions="<<numberOfRetransmissions); 00170 00171 std::vector<int> subchannels = getUsableSubChannelsIDs(resourceBlock->getUserID(), schedulingMap); 00172 00173 if (numberOfRetransmissions > subchannels.size()) 00174 { 00175 MESSAGE_BEGIN(NORMAL, logger, m, "Not enough room for "); 00176 m << numberOfRetransmissions; 00177 m << " retransmissions for user " << it->getName(); 00178 m << " (pid=" << processID << ") skipping this user"; 00179 MESSAGE_END(); 00180 continue; 00181 } 00182 00183 00184 while(resourceBlock != NULL) 00185 { 00186 subchannels = getUsableSubChannelsIDs(resourceBlock->getUserID(), schedulingMap); 00187 00188 size_t numAvailable = subchannels.size(); 00189 00190 if (numAvailable > 0) 00191 { 00192 double random = randomDist(); 00193 int sc = subchannels[int(random*numAvailable)]; 00194 00195 for ( SchedulingTimeSlotPtrVector::iterator iterTimeSlot = schedulingMap->subChannels[sc].temporalResources.begin(); 00196 iterTimeSlot != schedulingMap->subChannels[sc].temporalResources.end(); ++iterTimeSlot) 00197 { 00198 SchedulingTimeSlotPtr timeSlotPtr = *iterTimeSlot; 00199 int timeSlotIndex = timeSlotPtr->timeSlotIndex; 00200 00201 if ( ((!timeSlotPtr->getUserID().isValid()) || 00202 timeSlotPtr->getUserID() == resourceBlock->getUserID()) && 00203 timeSlotPtr->countScheduledCompounds()==0) 00204 { // free space found. Pack it into. 00205 // We found room for the retransmission, now remove it from 00206 // the pending retransmissions 00207 resourceBlock = colleagues.harq->getNextRetransmission(*it, processID); 00208 MESSAGE_BEGIN(NORMAL, logger, m, "Retransmitting"); 00209 m << " HARQ block ("<<resourceBlock->getUserID().getName()<<",processID=" << resourceBlock->harq.processID; 00210 m << ",Retry="<<resourceBlock->harq.retryCounter<<")"; 00211 m << " inside subchannel.timeslot=" <<sc<<"."<<timeSlotIndex; 00212 m << " (ex "<<resourceBlock->subChannelIndex<<"."<<resourceBlock->timeSlotIndex<<")"; 00213 MESSAGE_END(); 00214 assure(resourceBlock->subChannelIndex==resourceBlock->physicalResources[0].getSubChannelIndex(), 00215 "mismatch of subChannelIndex: "<<resourceBlock->subChannelIndex<<"!="<<resourceBlock->physicalResources[0].getSubChannelIndex()); 00216 assure(resourceBlock->timeSlotIndex==resourceBlock->physicalResources[0].getTimeSlotIndex(), 00217 "mismatch of timeSlotIndex: "<<resourceBlock->timeSlotIndex<<"!="<<resourceBlock->physicalResources[0].getTimeSlotIndex()); 00218 assure (resourceBlock != wns::scheduler::SchedulingTimeSlotPtr(),"resourceBlock==NULL"); 00219 00220 if (resourceBlock->harq.ackCallback.empty()) 00221 { 00222 std::cout << "Trying to transmit resource block with empty ack callback in ResourceScheduler::finishCollection" << std::endl; 00223 exit(1); 00224 } 00225 00226 if (resourceBlock->harq.nackCallback.empty()) 00227 { 00228 std::cout << "Trying to transmit resource block with empty nack callback in ResourceScheduler::finishCollection" << std::endl; 00229 exit(1); 00230 } 00231 00232 schedulingMap->subChannels[sc].temporalResources[timeSlotIndex] = resourceBlock; // copy Smartptr over 00233 // at this point timeSlotPtr is no longer valid for use! Only resourceBlock 00234 resourceBlock->subChannelIndex = sc; 00235 resourceBlock->timeSlotIndex = timeSlotIndex; 00236 assure(resourceBlock->physicalResources.size()==resourceBlock->numSpatialLayers, 00237 "mismatch in spatial domain: "<<resourceBlock->physicalResources.size()<<"!="<<resourceBlock->numSpatialLayers); 00238 // foreach PRB... fix subChannelIndex 00239 for ( PhysicalResourceBlockVector::iterator iterPRB = resourceBlock->physicalResources.begin(); 00240 iterPRB != resourceBlock->physicalResources.end(); ++iterPRB) 00241 { 00242 int spatialIndex = iterPRB->getSpatialLayerIndex(); 00243 MESSAGE_SINGLE(NORMAL, logger, sc<<"."<<timeSlotIndex<<".PRB["<<spatialIndex<<"]: Adjusting subChannelIndex from "<<iterPRB->getSubChannelIndex()<<" to "<<sc); 00244 iterPRB->setSubChannelIndex(sc); 00245 iterPRB->setTimeSlotIndex(timeSlotIndex); 00246 } 00247 resourceBlock = colleagues.harq->peekNextRetransmission(*it, processID); 00248 break; 00249 } 00250 } 00251 } 00252 else 00253 { 00254 // Due to the BCH fix see above we drop the remaining retransmissions here. 00255 while(resourceBlock != NULL) 00256 { 00257 resourceBlock = colleagues.harq->getNextRetransmission(*it, processID); 00258 } 00259 } 00260 } // while resource block to send 00261 } // for 00262 00263 MapInfoCollectionPtr mapInfoCollection = MapInfoCollectionPtr(new wns::scheduler::MapInfoCollection); 00264 00265 return mapInfoCollection; 00266 } // doStartSubScheduling 00267
1.5.5