![]() |
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 * email: info@openwns.org 00009 * www: http://www.openwns.org 00010 * _____________________________________________________________________________ 00011 * 00012 * openWNS is free software; you can redistribute it and/or modify it under the 00013 * terms of the GNU Lesser General Public License version 2 as published by the 00014 * Free Software Foundation; 00015 * 00016 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00017 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00018 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00019 * details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public License 00022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00023 * 00024 ******************************************************************************/ 00025 00026 #include <WIMAC/scheduler/BypassQueue.hpp> 00027 #include <WNS/ldk/HasReceptor.hpp> 00028 #include <WNS/simulator/Bit.hpp> 00029 #include <WIMAC/Logger.hpp> 00030 00031 STATIC_FACTORY_REGISTER_WITH_CREATOR(wimac::scheduler::BypassQueue, 00032 wns::scheduler::queue::QueueInterface, 00033 "wimac.BypassQueue", 00034 wns::HasReceptorConfigCreator); 00035 00036 00037 class QueueHasPDUs: 00038 public wimac::scheduler::BypassQueue::IsAcceptingChecker 00039 { 00040 public: 00041 QueueHasPDUs(wns::scheduler::RegistryProxyInterface* reg, 00042 wns::scheduler::ConnectionID cid): 00043 reg_(reg), 00044 cid_(cid), 00045 result_(false) 00046 {} 00047 00048 bool operator()(const wns::ldk::CompoundPtr& compound) 00049 { 00050 if (reg_->getCIDforPDU(compound) == cid_) 00051 result_ = true; 00052 return false; 00053 } 00054 00055 bool result() const {return result_;} 00056 00057 private: 00058 wns::scheduler::RegistryProxyInterface* reg_; 00059 wns::scheduler::ConnectionID cid_; 00060 bool result_; 00061 }; 00062 00063 class FilterQueued : 00064 public wimac::scheduler::BypassQueue::IsAcceptingChecker 00065 { 00066 public: 00067 FilterQueued(wns::scheduler::RegistryProxyInterface* reg, 00068 wns::scheduler::ConnectionSet candidates) : 00069 reg_(reg), 00070 candidates_(candidates) 00071 { 00072 } 00073 00074 bool 00075 operator()(const wns::ldk::CompoundPtr& compound) 00076 { 00077 wns::scheduler::ConnectionID id = reg_->getCIDforPDU(compound); 00078 if (candidates_.find(id) != candidates_.end()) 00079 result_.insert(id); 00080 } 00081 00082 wns::scheduler::ConnectionSet 00083 result() const 00084 { 00085 return result_; 00086 } 00087 00088 private: 00089 wns::scheduler::RegistryProxyInterface* reg_; 00090 wns::scheduler::ConnectionSet candidates_; 00091 wns::scheduler::ConnectionSet result_; 00092 }; 00093 00094 class AcceptCID : 00095 public wimac::scheduler::BypassQueue::IsAcceptingChecker 00096 { 00097 public: 00098 AcceptCID(wns::scheduler::RegistryProxyInterface* reg, 00099 wns::ldk::CompoundPtr* current, 00100 wns::scheduler::ConnectionID cid): 00101 reg_(reg), 00102 current_(current), 00103 cid_(cid) 00104 { 00105 } 00106 00107 bool 00108 operator()(const wns::ldk::CompoundPtr& compound) 00109 { 00110 using namespace wimac; 00111 return (*current_ == wns::ldk::CompoundPtr()) 00112 && (reg_->getCIDforPDU(compound) == cid_); 00113 } 00114 00115 private: 00116 wns::scheduler::RegistryProxyInterface* reg_; 00117 wns::ldk::CompoundPtr* current_; 00118 wns::scheduler::ConnectionID cid_; 00119 bool alreadyAccepted_; 00120 }; 00121 00122 00123 class HeadOfLinePDUBits : 00124 public wimac::scheduler::BypassQueue::IsAcceptingChecker 00125 { 00126 public: 00127 HeadOfLinePDUBits(wns::scheduler::RegistryProxyInterface* reg, 00128 wns::scheduler::ConnectionID cid) : 00129 reg_(reg), 00130 cid_(cid), 00131 result_(0) 00132 {} 00133 00134 bool 00135 operator()(const wns::ldk::CompoundPtr& compound) 00136 { 00137 if (reg_->getCIDforPDU(compound) == cid_) 00138 result_ = compound->getLengthInBits(); 00139 return false; 00140 } 00141 00142 Bit 00143 result() const 00144 { 00145 return result_; 00146 } 00147 private: 00148 wns::scheduler::RegistryProxyInterface* reg_; 00149 wns::scheduler::ConnectionID cid_; 00150 Bit result_; 00151 }; 00152 00153 class ListUsers : 00154 public wimac::scheduler::BypassQueue::IsAcceptingChecker 00155 { 00156 public: 00157 ListUsers(wns::scheduler::RegistryProxyInterface* reg) : 00158 reg_(reg), 00159 result_() 00160 {} 00161 00162 bool 00163 operator()(const wns::ldk::CompoundPtr& compound) 00164 { 00165 using namespace wimac; 00166 result_.insert(reg_->getUserForCID( reg_->getCIDforPDU(compound))); 00167 return false; 00168 } 00169 00170 wns::scheduler::UserSet 00171 result() 00172 { 00173 return result_; 00174 } 00175 00176 private: 00177 wns::scheduler::RegistryProxyInterface* reg_; 00178 wns::scheduler::UserSet result_; 00179 }; 00180 00181 class ListConnections : 00182 public wimac::scheduler::BypassQueue::IsAcceptingChecker 00183 { 00184 public: 00185 ListConnections(wns::scheduler::RegistryProxyInterface* reg) : 00186 reg_(reg), 00187 result_() 00188 {} 00189 00190 bool 00191 operator()(const wns::ldk::CompoundPtr& compound) 00192 { 00193 result_.insert(reg_->getCIDforPDU(compound)); 00194 return false; 00195 } 00196 00197 wns::scheduler::ConnectionSet 00198 result() 00199 { 00200 return result_; 00201 } 00202 00203 private: 00204 wns::scheduler::RegistryProxyInterface* reg_; 00205 wns::scheduler::ConnectionSet result_; 00206 }; 00207 00208 class ListPriorityConns : 00209 public wimac::scheduler::BypassQueue::IsAcceptingChecker 00210 { 00211 public: 00212 ListPriorityConns(wns::scheduler::RegistryProxyInterface* reg, int priority) : 00213 reg_(reg), 00214 priority_(priority), 00215 result_() 00216 {} 00217 00218 bool 00219 operator()(const wns::ldk::CompoundPtr& compound) 00220 { 00221 if (reg_->getPriorityForConnection(reg_->getCIDforPDU(compound)) == priority_) 00222 result_.insert(reg_->getCIDforPDU(compound)); 00223 return false; 00224 } 00225 00226 wns::scheduler::ConnectionSet 00227 result() 00228 { 00229 return result_; 00230 } 00231 00232 private: 00233 wns::scheduler::RegistryProxyInterface* reg_; 00234 int priority_; 00235 wns::scheduler::ConnectionSet result_; 00236 }; 00237 00238 using namespace wimac::scheduler; 00239 00240 00241 BypassQueue::BypassQueue(wns::ldk::HasReceptorInterface* parent, const wns::pyconfig::View&): 00242 hasReceptor_(parent), 00243 isAcceptingChecker_(0), 00244 current_(wns::ldk::CompoundPtr()) 00245 { 00246 } 00247 00248 bool 00249 BypassQueue::isAccepting(const wns::ldk::CompoundPtr& compound) const 00250 { 00251 if (isAcceptingChecker_) 00252 return (*isAcceptingChecker_)(compound); 00253 return false; 00254 } 00255 00256 bool 00257 BypassQueue::queueHasPDUs(wns::scheduler::ConnectionID cid) const 00258 { 00259 std::auto_ptr<QueueHasPDUs> queueHasPDUs( new QueueHasPDUs(colleagues_.registry, cid)); 00260 isAcceptingChecker_ = queueHasPDUs.get(); 00261 getReceptor()->wakeup(); 00262 isAcceptingChecker_ = 0; 00263 return queueHasPDUs->result(); 00264 } 00265 00266 bool 00267 BypassQueue::isEmpty() const 00268 { 00269 // Example from libwns: 00270 // for (QueueContainer::const_iterator iter = queues.begin(); iter != queues.end(); ++iter) 00271 // { 00272 // if ((*iter).second.pduQueue.size() != 0) 00273 // return false; 00274 // } 00275 // return true; 00276 throw wns::Exception("not implemented"); 00277 } 00278 00279 00280 wns::scheduler::ConnectionSet 00281 BypassQueue::filterQueuedCids(wns::scheduler::ConnectionSet connections) 00282 { 00283 std::auto_ptr<FilterQueued> filtered( new FilterQueued(colleagues_.registry, connections)); 00284 isAcceptingChecker_ = filtered.get(); 00285 getReceptor()->wakeup(); 00286 isAcceptingChecker_ = 0; 00287 return filtered->result(); 00288 } 00289 00290 wns::ldk::CompoundPtr 00291 BypassQueue::getHeadOfLinePDU(wns::scheduler::ConnectionID cid) 00292 { 00293 std::auto_ptr<AcceptCID> acceptor(new AcceptCID(colleagues_.registry, ¤t_, cid)); 00294 isAcceptingChecker_ = acceptor.get(); 00295 getReceptor()->wakeup(); 00296 isAcceptingChecker_ = 0; 00297 wns::ldk::CompoundPtr result = current_; 00298 assure(result != wns::ldk::CompoundPtr(), "wimac::BypassQueue: about to return null compound"); 00299 current_ = wns::ldk::CompoundPtr(); 00300 return result; 00301 } 00302 00303 int 00304 BypassQueue::getHeadOfLinePDUbits(wns::scheduler::ConnectionID cid) 00305 { 00306 std::auto_ptr<HeadOfLinePDUBits> counter(new HeadOfLinePDUBits(colleagues_.registry, cid)); 00307 isAcceptingChecker_ = counter.get(); 00308 getReceptor()->wakeup(); 00309 isAcceptingChecker_ = 0; 00310 return counter->result(); 00311 } 00312 00313 bool 00314 BypassQueue::hasQueue(wns::scheduler::ConnectionID) 00315 { 00316 return false; 00317 } 00318 00319 void 00320 BypassQueue::put(const wns::ldk::CompoundPtr& compound) 00321 { 00322 assure((*isAcceptingChecker_)(compound), "BypassQueue is unable to accept a compound"); 00323 assure(current_ == wns::ldk::CompoundPtr(), "Already accepted a compound"); 00324 current_ = compound; 00325 } 00326 00327 wns::scheduler::queue::QueueInterface::ProbeOutput 00328 BypassQueue::resetAllQueues() 00329 { 00330 return wns::scheduler::queue::QueueInterface::ProbeOutput(); 00331 } 00332 00333 wns::scheduler::queue::QueueInterface::ProbeOutput 00334 BypassQueue::resetQueues(wns::scheduler::UserID) 00335 { 00336 return wns::scheduler::queue::QueueInterface::ProbeOutput(); 00337 } 00338 00339 void 00340 BypassQueue::frameStarts() 00341 { 00342 } 00343 00344 wns::scheduler::queue::QueueInterface::ProbeOutput 00345 BypassQueue::resetQueue(wns::scheduler::ConnectionID) 00346 { 00347 return wns::scheduler::queue::QueueInterface::ProbeOutput(); 00348 } 00349 00350 bool 00351 BypassQueue::supportsDynamicSegmentation() const 00352 { 00353 return false; 00354 } 00355 00356 wns::ldk::CompoundPtr 00357 BypassQueue::getHeadOfLinePDUSegment(wns::scheduler::ConnectionID cid, int bits) 00358 { 00359 throw wns::Exception("Segmentation in bypass queue is not supported"); 00360 } 00361 00362 00363 wns::scheduler::UserSet 00364 BypassQueue::getQueuedUsers() const 00365 { 00366 std::auto_ptr<ListUsers> listUsers(new ListUsers(colleagues_.registry)); 00367 isAcceptingChecker_ = listUsers.get(); 00368 getReceptor()->wakeup(); 00369 isAcceptingChecker_ = 0; 00370 return listUsers->result(); 00371 } 00372 00373 wns::scheduler::ConnectionSet 00374 BypassQueue::getActiveConnections() const 00375 { 00376 std::auto_ptr<ListConnections> listConnections(new ListConnections(colleagues_.registry)); 00377 isAcceptingChecker_ = listConnections.get(); 00378 getReceptor()->wakeup(); 00379 isAcceptingChecker_ = 0; 00380 return listConnections->result(); 00381 } 00382 00383 wns::scheduler::ConnectionSet 00384 BypassQueue::getActiveConnectionsForPriority(unsigned int priority) const 00385 { 00386 std::auto_ptr<ListPriorityConns> listConnections(new ListPriorityConns(colleagues_.registry, priority)); 00387 isAcceptingChecker_ = listConnections.get(); 00388 getReceptor()->wakeup(); 00389 isAcceptingChecker_ = 0; 00390 return listConnections->result(); 00391 } 00392 00393 /* obsolete 00394 unsigned long int 00395 BypassQueue::numCompoundsForUser(wns::scheduler::UserID user) const 00396 { 00397 throw wns::Exception("not implemented"); 00398 } 00399 */ 00400 unsigned long int 00401 BypassQueue::numCompoundsForCid(wns::scheduler::ConnectionID cid) const 00402 { 00403 throw wns::Exception("not implemented"); 00404 } 00405 /* obsolete 00406 unsigned long int 00407 BypassQueue::numBitsForUser(wns::scheduler::UserID user) const 00408 { 00409 throw wns::Exception("not implemented"); 00410 } 00411 */ 00412 unsigned long int 00413 BypassQueue::numBitsForCid(wns::scheduler::ConnectionID cid) const 00414 { 00415 throw wns::Exception("not implemented"); 00416 } 00417 00418 wns::scheduler::QueueStatusContainer 00419 BypassQueue::getQueueStatus() const 00420 { 00421 throw wns::Exception("not implemented"); 00422 } 00423 00424 void 00425 BypassQueue::setColleagues(wns::scheduler::RegistryProxyInterface* registry) 00426 { 00427 colleagues_.registry = registry; 00428 } 00429 00430 void 00431 BypassQueue::setFUN(wns::ldk::fun::FUN*) 00432 { 00433 } 00434 00435 std::string 00436 BypassQueue::printAllQueues() 00437 { 00438 throw wns::Exception("not implemented"); 00439 } 00440 00441 wns::ldk::Receptor* 00442 BypassQueue::getReceptor() const 00443 { 00444 return hasReceptor_->getReceptor(); 00445 } 00446 00447 std::queue<wns::ldk::CompoundPtr> 00448 BypassQueue::getQueueCopy(wns::scheduler::ConnectionID cid) 00449 { 00450 wns::Exception("You should not call getQueueCopy of the BypassQueue."); 00451 }
1.5.5