![]() |
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-2007 00006 * Chair of Communication Networks (ComNets) 00007 * Kopernikusstr. 16, 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/queuingsystem/MM1Step5.hpp> 00029 #include <WNS/probe/bus/ContextProvider.hpp> 00030 00031 using namespace wns::queuingsystem; 00032 00033 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00034 SimpleMM1Step5, 00035 wns::simulator::ISimulationModel, 00036 "openwns.queuingsystem.SimpleMM1Step5", 00037 wns::PyConfigViewCreator); 00038 00039 SimpleMM1Step5::SimpleMM1Step5(const wns::pyconfig::View& config) : 00040 priorityDistribution_(Job::lowPriority, Job::highPriority), 00041 config_(config), 00042 logger_(config.get("logger")), 00043 idle(true), 00044 // Below we will put one Context Provider in the collection 00045 cpc_(new wns::probe::bus::ContextProviderCollection()), 00046 // The name of the measurement source. Must match the one configured 00047 // in the global Probe Bus Registry 00048 sojournTime_(cpc_, "SojournTime") 00049 { 00050 wns::pyconfig::View disConfig = config.get("jobInterArrivalTimeDistribution"); 00051 std::string disName = disConfig.get<std::string>("__plugin__"); 00052 jobInterarrivalTime_ = 00053 wns::distribution::DistributionFactory::creator(disName)->create(disConfig); 00054 00055 disConfig = config.get("jobProcessingTimeDistribution"); 00056 disName = disConfig.get<std::string>("__plugin__"); 00057 jobProcessingTime_ = 00058 wns::distribution::DistributionFactory::creator(disName)->create(disConfig); 00059 00060 // Callback Context Provider will call the given function to fill 00061 // in Context information 00062 cpc_->addProvider(wns::probe::bus::contextprovider::Callback( 00063 "priority", 00064 boost::bind(&SimpleMM1Step5::getCurrentJobPriority, this))); 00065 } 00066 00067 void 00068 SimpleMM1Step5::doStartup() 00069 { 00070 MESSAGE_SINGLE(NORMAL, logger_, "MM1Step5 started, generating first job\n" << *this); 00071 00072 generateNewJob(); 00073 } 00074 00075 void 00076 SimpleMM1Step5::doShutdown() 00077 { 00078 assure(cpc_, "No Context Provider Collection"); 00079 delete cpc_; 00080 } 00081 00082 void 00083 SimpleMM1Step5::generateNewJob() 00084 { 00085 // Create a new job 00086 Job job = Job(drawJobPriority()); 00087 00088 if (job.getPriority() == Job::lowPriority) 00089 { 00090 lowPriorityQueue_.push_back(job); 00091 } 00092 else 00093 { 00094 highPriorityQueue_.push_back(job); 00095 } 00096 00097 00098 wns::simulator::Time delayToNextJob = (*jobInterarrivalTime_)(); 00099 00100 MESSAGE_SINGLE(NORMAL, logger_, "Generated new job, next job in " << delayToNextJob << "s\n" << *this); 00101 00102 if (idle) 00103 { 00104 processNextJob(); 00105 } 00106 00107 wns::simulator::getEventScheduler()->scheduleDelay( 00108 boost::bind(&SimpleMM1Step5::generateNewJob, this), 00109 delayToNextJob); 00110 } 00111 00112 void 00113 SimpleMM1Step5::onJobProcessed() 00114 { 00115 // Calculate the Jobs sojourn time 00116 wns::simulator::Time now; 00117 wns::simulator::Time sojournTime; 00118 now = wns::simulator::getEventScheduler()->getTime(); 00119 sojournTime = now - currentJob_.getCreationTime(); 00120 00121 // Give some debug output 00122 MESSAGE_SINGLE(NORMAL, logger_, "Finished a job\n" << *this); 00123 MESSAGE_BEGIN(NORMAL, logger_, m, "Sojourn Time of last job "); 00124 m << sojournTime; 00125 MESSAGE_END(); 00126 00127 // Probe the value. The Context Provider will automatically 00128 // attach information about the priority of the job. 00129 sojournTime_.put(sojournTime); 00130 00131 // if there are still jobs, serve them 00132 if ( getNumberOfJobs() > 0 ) 00133 { 00134 processNextJob(); 00135 } 00136 else 00137 { 00138 idle = true; 00139 } 00140 } 00141 00142 void 00143 SimpleMM1Step5::processNextJob() 00144 { 00145 currentJob_ = getNextJob(); 00146 00147 wns::simulator::Time processingTime = (*jobProcessingTime_)(); 00148 00149 wns::simulator::getEventScheduler()->scheduleDelay( 00150 boost::bind(&SimpleMM1Step5::onJobProcessed, this), 00151 processingTime); 00152 00153 idle = false; 00154 00155 MESSAGE_SINGLE(NORMAL, logger_, "Processing next job, processing time: " << processingTime << "s\n" << *this); 00156 } 00157 00158 int 00159 SimpleMM1Step5::getNumberOfJobs() const 00160 { 00161 return lowPriorityQueue_.size() + highPriorityQueue_.size(); 00162 } 00163 00164 Job 00165 SimpleMM1Step5::getNextJob() 00166 { 00167 Job nextJob; 00168 00169 if (highPriorityQueue_.size() > 0) 00170 { 00171 nextJob = highPriorityQueue_.front(); 00172 00173 highPriorityQueue_.pop_front(); 00174 } 00175 else if(lowPriorityQueue_.size() > 0) 00176 { 00177 nextJob = lowPriorityQueue_.front(); 00178 00179 lowPriorityQueue_.pop_front(); 00180 } 00181 else 00182 { 00183 throw wns::Exception("getNextJob called but now Job queued. You must check for available jobs before calling getNextJob!"); 00184 } 00185 00186 return nextJob; 00187 } 00188 00189 std::string 00190 SimpleMM1Step5::doToString() const 00191 { 00192 std::stringstream ss; 00193 ss << "Jobs in system: " << getNumberOfJobs(); 00194 return ss.str(); 00195 } 00196 00197 Job::Priority 00198 SimpleMM1Step5::drawJobPriority() 00199 { 00200 if (priorityDistribution_() == static_cast<int>(Job::lowPriority)) 00201 { 00202 return Job::lowPriority; 00203 } 00204 else 00205 { 00206 return Job::highPriority; 00207 } 00208 } 00209 00210 int 00211 SimpleMM1Step5::getCurrentJobPriority() const 00212 { 00213 return currentJob_.getPriority(); 00214 }
1.5.5