![]() |
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/dsastrategy/BestCapacity.hpp> 00029 #include <WNS/scheduler/strategy/dsastrategy/DSAStrategyInterface.hpp> 00030 #include <WNS/scheduler/SchedulerTypes.hpp> 00031 #include <vector> 00032 #include <iostream> 00033 #include <algorithm> 00034 00035 using namespace wns::scheduler; 00036 using namespace wns::scheduler::strategy; 00037 using namespace wns::scheduler::strategy::dsastrategy; 00038 00039 STATIC_FACTORY_REGISTER_WITH_CREATOR(BestCapacity, 00040 DSAStrategyInterface, 00041 "BestCapacity", 00042 wns::PyConfigViewCreator); 00043 00044 BestCapacity::BestCapacity(const wns::pyconfig::View& config) 00045 : DSAStrategy(config) 00046 { 00047 //useRandomChannelAtBeginning = 00048 //config.get<bool>("useRandomChannelAtBeginning"); 00049 } 00050 00051 BestCapacity::~BestCapacity() 00052 { 00053 } 00054 00055 // call this before each timeSlot/frame 00056 void 00057 BestCapacity::initialize(SchedulerStatePtr schedulerState, 00058 SchedulingMapPtr schedulingMap) 00059 { 00060 DSAStrategy::initialize(schedulerState,schedulingMap); // must always initialize base class too 00061 if (!userInfoMap.empty()) 00062 { 00063 userInfoMap.clear(); 00064 } 00065 // just a SmartPtr: 00066 //ChannelQualitiesOfAllUsersPtr 00067 assure(schedulerState->currentState!=RevolvingStatePtr(),"currentState must be valid"); 00068 // set member: 00069 channelQualitiesOfAllUsers = 00070 schedulerState->currentState->channelQualitiesOfAllUsers; 00071 } 00072 00073 DSAResult 00074 BestCapacity::getSubChannelWithDSA(RequestForResource& request, 00075 SchedulerStatePtr schedulerState, 00076 SchedulingMapPtr schedulingMap) 00077 { 00078 DSAResult dsaResult; 00079 UserID user = request.user; 00080 if (userInfoMap.find(user) == userInfoMap.end()) { 00081 userInfoMap.insert(UserInfoMap::value_type(user, UserInfo(schedulerState->currentState->strategyInput->fChannels))); 00082 } 00083 UserInfo& userInfo = userInfoMap.find(user)->second; 00084 00085 int lastUsedSubChannel = userInfo.lastUsedSubChannel; 00086 int subChannel = lastUsedSubChannel; 00087 int maxSubChannel = schedulingMap->subChannels.size(); 00088 int maxTimeSlots = schedulerState->currentState->strategyInput->getNumberOfTimeSlots(); 00089 int lastUsedTimeSlot = userInfo.lastUsedTimeSlot; 00090 int timeSlot = lastUsedTimeSlot; 00091 00092 assure(maxSubChannel==schedulerState->currentState->strategyInput->fChannels,"maxSubChannel="<<maxSubChannel<<"!=fChannels"); 00093 ChannelQualitiesOnAllSubBandsPtr channelQualitiesOnAllSubBands = userInfo.channelQualitiesOnAllSubBands; 00094 if (channelQualitiesOnAllSubBands==ChannelQualitiesOnAllSubBandsPtr()) { // empty 00095 assure(channelQualitiesOfAllUsers->knowsUser(user),"channelQualitiesOfAllUsers["<<user.getName()<<"] invalid"); 00096 // ^ or should we ask the registryProxy for CQI here? 00097 channelQualitiesOnAllSubBands = channelQualitiesOfAllUsers->find(user)->second; 00098 userInfo.channelQualitiesOnAllSubBands = channelQualitiesOnAllSubBands; 00099 } 00100 MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA("<<request.toString()<<"): lastSC="<<lastUsedSubChannel); 00101 00102 int spatialLayer=0; 00103 bool found = false; 00104 bool giveUp = false; 00105 if (!schedulerState->isTx 00106 && adjacentSubchannelsOnUplink 00107 && (lastUsedSubChannel!=DSAsubChannelNotFound) // already used subChannel 00108 ) 00109 { // UL SC-FDMA 00110 // adjacentSubchannelsOnUplink 00111 while(!found && !giveUp) 00112 { 00113 // try same old subChannel again: 00114 subChannel = lastUsedSubChannel; 00115 if (!userInfo.usedSubChannels[subChannel] 00116 && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap)) 00117 { // PDU fits in 00118 found=true; break; 00119 } else { // mark unusable 00120 userInfo.usedSubChannels[subChannel] = true; 00121 } 00122 // TODO: consider timeSlots !!! 00123 00124 // try +/-1 +/-2 and so on 00125 for (int tryThisSubChannelOffset=0; tryThisSubChannelOffset<maxSubChannel/2; tryThisSubChannelOffset++) 00126 { 00127 subChannel = (lastUsedSubChannel + tryThisSubChannelOffset*userInfo.toggleOffset); 00128 if ((subChannel>=0) && !userInfo.usedSubChannels[subChannel] 00129 && (subChannel<maxSubChannel) 00130 && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap)) 00131 { // PDU fits in 00132 found=true; break; 00133 } else { // mark unusable 00134 userInfo.usedSubChannels[subChannel] = true; 00135 } 00136 subChannel = (lastUsedSubChannel - tryThisSubChannelOffset*userInfo.toggleOffset); 00137 if ((subChannel>=0) && !userInfo.usedSubChannels[subChannel] 00138 && (subChannel<maxSubChannel) 00139 && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap)) 00140 { // PDU fits in 00141 found=true; break; 00142 } else { // mark unusable 00143 userInfo.usedSubChannels[subChannel] = true; 00144 } 00145 } // for offset +/- 00146 // the resulting DSA may not be contiguous in the case of another small-band user nearby 00147 } // while 00148 userInfo.toggleOffset *= -1; 00149 } else { // free search 00150 BetterChannelCapacity comparator; // from SchedulerTypes.hpp 00151 wns::service::phy::phymode::PhyModeMapperInterface* phyModeMapper = colleagues.registry->getPhyModeMapper(); 00152 double channelCapacity = 0.0; 00153 double remainingTimeOnthisChannel = 0.0; 00154 wns::Power nominalPower; 00155 // to get tx power, default or nominal 00156 // the same power will be used on all subchannels for comparing, so that 00157 // the best capacity depend only on the free time and datarate 00158 if (schedulerState->defaultTxPower!=wns::Power()) 00159 { // predefined, e.g. in slave mode 00160 nominalPower = schedulerState->defaultTxPower; 00161 } else { 00162 wns::scheduler::PowerCapabilities powerCapabilities = 00163 schedulerState->strategy->getPowerCapabilities(request.user); 00164 nominalPower = powerCapabilities.nominalPerSubband; 00165 } 00166 00167 // O(N^2) operations: 00168 while(!found && !giveUp) 00169 { 00170 subChannel = DSAsubChannelNotFound; 00171 double bestChannelCapacity = 0.0; 00172 // find channel with best capacity of the remaining subChannels: 00173 for (int tryThisSubChannel=0; tryThisSubChannel<maxSubChannel; tryThisSubChannel++) 00174 { 00175 for (int tryThisTimeSlot=0; tryThisTimeSlot<maxTimeSlots; tryThisTimeSlot++) 00176 { 00177 // TODO: userInfo.usedSubChannels[tryThisSubChannel][tryThisTimeSlot] 00178 if (!userInfo.usedSubChannels[tryThisSubChannel]) { // could be free (at least not checked before) 00179 ChannelQualityOnOneSubChannel channelQuality 00180 = (*channelQualitiesOnAllSubBands)[tryThisSubChannel]; 00181 if (channelIsUsable(tryThisSubChannel, tryThisTimeSlot, request, schedulerState, schedulingMap)) 00182 { 00183 spatialLayer = getSpatialLayerForSubChannel(tryThisSubChannel, tryThisTimeSlot, request, schedulerState, schedulingMap); 00184 } 00185 else 00186 { 00187 continue; 00188 } 00189 00190 remainingTimeOnthisChannel = schedulingMap->subChannels[tryThisSubChannel].temporalResources[tryThisTimeSlot]->physicalResources[spatialLayer].getFreeTime(); 00191 wns::Ratio sinr = nominalPower/(channelQuality.interference * channelQuality.pathloss.get_factor()); 00192 wns::SmartPtr<const wns::service::phy::phymode::PhyModeInterface> bestPhyMode = phyModeMapper->getBestPhyMode(sinr); 00193 channelCapacity = bestPhyMode->getDataRate() * remainingTimeOnthisChannel; 00194 00195 if (comparator(channelCapacity, bestChannelCapacity)) { 00196 bestChannelCapacity = channelCapacity; 00197 subChannel = tryThisSubChannel; 00198 timeSlot = tryThisTimeSlot; 00199 } 00200 } // if unused 00201 } // forall tryThisTimeSlot 00202 } // forall tryThisSubChannel 00203 00204 if (subChannel==DSAsubChannelNotFound) 00205 { // one complete round already done 00206 giveUp=true; break; 00207 } 00208 // best subChannel and spatialLayer found; now check if usable: 00209 if (channelIsUsable(subChannel, timeSlot, spatialLayer, request, schedulerState, schedulingMap)) 00210 { // PDU fits in 00211 found=true; break; 00212 } else { // mark unusable 00213 // TODO: userInfo.usedSubChannels[tryThisSubChannel][tryThisTimeSlot] 00214 userInfo.usedSubChannels[subChannel] = true; 00215 } 00216 } // while 00217 } // if free search or linear (SC-FDMA) 00218 00219 if (giveUp) { 00220 MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA(): no free subchannel"); 00221 return dsaResult; // empty with subChannel=DSAsubChannelNotFound 00222 } else { 00223 MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA(): subChannel="<<subChannel); 00224 userInfo.lastUsedSubChannel = subChannel; 00225 dsaResult.subChannel = subChannel; 00226 dsaResult.spatialLayer = spatialLayer; 00227 return dsaResult; 00228 } 00229 return dsaResult; // empty with subChannel=DSAsubChannelNotFound 00230 } 00231
1.5.5