![]() |
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/RoundRobin.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(RoundRobin, 00042 SubStrategyInterface, 00043 "RoundRobin", 00044 wns::PyConfigViewCreator); 00045 00046 00047 RoundRobin::RoundRobin(const wns::pyconfig::View& config) 00048 : SubStrategy(config), 00049 blockSize(config.get<int>("blockSize")), 00050 lastScheduledConnection(0) 00051 { 00052 assure(blockSize>0,"invalid blockSize="<<blockSize); 00053 MESSAGE_SINGLE(NORMAL, logger, "RoundRobin(): constructed with blockSize="<<blockSize); 00054 } 00055 00056 RoundRobin::~RoundRobin() 00057 { 00058 } 00059 00060 void 00061 RoundRobin::initialize() 00062 { 00063 // make state 00064 MESSAGE_SINGLE(NORMAL, logger, "RoundRobin(): initialized"); 00065 } 00066 00067 wns::scheduler::ConnectionID 00068 RoundRobin::getValidCurrentConnection(const ConnectionSet ¤tConnections, ConnectionID cid) const 00069 { 00070 // uses state var currentConnections 00071 wns::scheduler::ConnectionSet::iterator iter = 00072 currentConnections.upper_bound(cid); 00073 if ( iter != currentConnections.end() ) { // exists 00074 return *iter; 00075 } else { // continue with next higher cid 00076 return *currentConnections.begin(); 00077 } 00078 //MESSAGE_SINGLE(NORMAL, logger, "getValidCurrentConnection("<<cid<<") = "); 00079 } 00080 00081 wns::scheduler::ConnectionID 00082 RoundRobin::getNextConnection(const ConnectionSet ¤tConnections, ConnectionID cid) const 00083 { 00084 // uses state var currentConnections 00085 wns::scheduler::ConnectionSet::iterator iter = 00086 currentConnections.upper_bound(cid); 00087 if ( iter != currentConnections.end() ) { // exists 00088 return *iter; 00089 } else { // continue with next higher cid 00090 return *currentConnections.begin(); 00091 } 00092 //MESSAGE_SINGLE(NORMAL, logger, "getNextConnection("<<cid<<") = "); 00093 } 00094 00095 // return std::list<MapInfoEntryPtr> 00096 wns::scheduler::MapInfoCollectionPtr 00097 RoundRobin::doStartSubScheduling(SchedulerStatePtr schedulerState, 00098 wns::scheduler::SchedulingMapPtr schedulingMap) 00099 { 00100 MapInfoCollectionPtr mapInfoCollection = MapInfoCollectionPtr(new wns::scheduler::MapInfoCollection); // result datastructure 00101 ConnectionSet ¤tConnections = schedulerState->currentState->activeConnections; 00102 if ( currentConnections.empty() ) return mapInfoCollection; // nothing to do 00103 wns::scheduler::ConnectionID currentConnection = getValidCurrentConnection(currentConnections,lastScheduledConnection); 00104 MESSAGE_SINGLE(NORMAL, logger, "RoundRobin::doStartSubScheduling("<<printConnectionSet(currentConnections)<<") start with cid="<<currentConnection); 00105 00106 bool spaceLeft=true; 00107 while(spaceLeft) 00108 { 00109 int pduCounter = 0; 00110 // schedule #=blockSize PDUs for this CID here... 00111 while( colleagues.queue->queueHasPDUs(currentConnection) 00112 && (pduCounter<blockSize) 00113 && spaceLeft) 00114 { // spaceLeft[currentConnection] to be more precise 00115 spaceLeft = scheduleCid(schedulerState,schedulingMap,currentConnection,pduCounter,blockSize,mapInfoCollection); 00116 } // while PDUs in queue 00117 if (!colleagues.queue->queueHasPDUs(currentConnection)) 00118 { // exit because of queue empty (most probable case for low traffic) 00119 currentConnections.erase(currentConnection); 00120 if (currentConnections.size()==0) break; // all queues empty 00121 } 00122 00123 if (spaceLeft) 00124 { 00125 currentConnection = getNextConnection(currentConnections,currentConnection); 00126 MESSAGE_SINGLE(NORMAL, logger, "doStartSubScheduling(): next connection="<<currentConnection); 00127 } 00128 } // while(spaceLeft) 00129 00130 lastScheduledConnection = currentConnection; // this one really had pdus scheduled 00131 00132 MESSAGE_SINGLE(NORMAL, logger, "doStartSubScheduling(): ready: mapInfoCollection="<<mapInfoCollection.getPtr()<<" of size="<<mapInfoCollection->size()); 00133 return mapInfoCollection; 00134 } // doStartSubScheduling 00135
1.5.5