![]() |
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/simulator/StatusReport.hpp> 00029 00030 #include <WNS/pyconfig/View.hpp> 00031 #include <WNS/Assure.hpp> 00032 #include <WNS/osi/PDU.hpp> 00033 00034 #include <iomanip> 00035 #include <fstream> 00036 00037 using namespace wns::simulator; 00038 00039 StatusReport::StatusReport() : 00040 wns::events::PeriodicRealTimeout(), 00041 maxSimTime(0.0), 00042 startTime(time(NULL)), 00043 outputDir("output/"), 00044 statusFileName("output/WNSStatus.dat"), 00045 progressFileName("output/progress") 00046 { 00047 } 00048 00049 void StatusReport::start(const pyconfig::View& _pyConfigView) 00050 { 00051 this->maxSimTime = _pyConfigView.get<double>("maxSimTime"); 00052 this->startTime = time(NULL); 00053 00054 this->outputDir = _pyConfigView.get<std::string>("outputDir"); 00055 00056 // Append trailing '/'? 00057 std::string::size_type len = this->outputDir.length(); 00058 if (this->outputDir.find("/",len-1) == std::string::npos) 00059 { 00060 this->outputDir += "/"; 00061 } 00062 00063 this->statusFileName = this->outputDir + _pyConfigView.get<std::string>("statusFileName"); 00064 this->progressFileName = this->outputDir + "progress"; 00065 00066 // try to write status file 00067 std::ofstream statusFile; 00068 statusFile.open(this->statusFileName.c_str()); 00069 if (statusFile.good() == false) 00070 { 00071 wns::Exception e; 00072 e << "Can't open file " << this->statusFileName; 00073 throw e; 00074 } 00075 statusFile.close(); 00076 00077 // try to write progress file 00078 std::ofstream progressFile; 00079 progressFile.open(this->progressFileName.c_str()); 00080 if (progressFile.good() == false) 00081 { 00082 wns::Exception e; 00083 e << "Can't open file " << this->progressFileName; 00084 throw e; 00085 } 00086 progressFile.close(); 00087 00088 // register memConsumption Probe 00089 memoryConsumption = wns::probe::bus::ContextCollectorPtr( 00090 new wns::probe::bus::ContextCollector(wns::probe::bus::ContextProviderCollection(), 00091 _pyConfigView.get<std::string>("memConsumptionProbeBusName"))); 00092 00093 // register simTime Probe 00094 simTimePerRealTime = wns::probe::bus::ContextCollectorPtr( 00095 new wns::probe::bus::ContextCollector(wns::probe::bus::ContextProviderCollection(), 00096 _pyConfigView.get<std::string>("simTimeProbeBusName"))); 00097 00098 this->writeStatus(false); 00099 this->startPeriodicTimeout(_pyConfigView.get<double>("statusWriteInterval")); 00100 } 00101 00102 void StatusReport::stop() 00103 { 00104 if (this->hasPeriodicRealTimeoutSet() == true) 00105 { 00106 this->cancelPeriodicRealTimeout(); 00107 } 00108 } 00109 00110 void StatusReport::periodically() 00111 { 00112 try 00113 { 00114 this->writeStatus(false); 00115 } 00116 catch(WriteError& we) 00117 { 00118 std::cerr << we; 00119 } 00120 } 00121 00122 void StatusReport::writeStatus(bool anEndOfSimFlag, std::string otherFileName) 00123 { 00124 std::ofstream statusFile; 00125 if (otherFileName == "") 00126 { 00127 statusFile.open(this->statusFileName.c_str()); 00128 if (statusFile.good() == false) 00129 { 00130 throw WriteError(this->statusFileName); 00131 } 00132 } 00133 else 00134 { 00135 statusFile.open((outputDir + otherFileName).c_str()); 00136 if (statusFile.good() == false) 00137 { 00138 throw WriteError(outputDir + otherFileName); 00139 } 00140 } 00141 00142 std::ofstream progressFile; 00143 progressFile.open(this->progressFileName.c_str()); 00144 if (progressFile.good() == false) 00145 { 00146 throw WriteError(this->progressFileName); 00147 } 00148 00149 00150 std::string startTimeStr, curTimeStr; 00151 time_t curTime; 00152 time_t hours, minutes, seconds; 00153 00154 startTimeStr = ctime(&startTime); 00155 curTime = time(NULL); 00156 curTimeStr = ctime(&curTime); 00157 00158 00159 // @bug We've seen this assertion fail on SMP systems with dynamic 00160 // frequency scaling enabled (as power save strategy). 00161 // disabled: msg, 25.11.06 00162 // assure(curTime >= startTime, "\ncurTime: " + curTimeStr + "startTime: " + startTimeStr); 00163 00164 //calculate running time 00165 hours = (curTime - startTime) / 3600; 00166 minutes = (curTime - startTime - 3600 * hours) / 60; 00167 seconds = curTime - startTime - 3600 * hours - minutes * 60; 00168 00169 double curSimTime = wns::simulator::getEventScheduler()->getTime(); 00170 00171 statusFile << " WNS" << std::endl 00172 << " =====" << std::endl 00173 << " Status: " 00174 << (anEndOfSimFlag ? 00175 "Simulation terminated successfully" : 00176 "Simulation is still running") 00177 << std::endl 00178 << " Start: " 00179 << startTimeStr 00180 << " Now: " 00181 << curTimeStr 00182 << " Duration: " 00183 << std::setw(4) 00184 << hours 00185 << ":" 00186 << std::setw(2) 00187 << std::setfill('0') 00188 << minutes 00189 << ":" 00190 << std::setw(2) 00191 << std::setfill('0') 00192 << seconds 00193 << std::endl 00194 << std::endl 00195 << " Simulation time: " 00196 << curSimTime 00197 << std::endl 00198 << " Max. simulation time: " 00199 << maxSimTime 00200 << std::endl 00201 << std::endl 00202 << std::endl 00203 #ifndef NDEBUG 00204 << "Debug output\n" 00205 << "----------------------------------------------------------\n" 00206 << "Max number of PDUs: " << wns::osi::PDU::getMaxExistingPDUs() << "\n" 00207 << "Current number of PDUs: " << wns::osi::PDU::getExistingPDUs() << "\n" 00208 #endif // NDEBUG 00209 << std::endl 00210 << std::endl 00211 << "The following output is read from /proc/self/status\n" 00212 << "----------------------------------------------------------\n"; 00213 std::ifstream in("/proc/self/status"); 00214 std::string line; 00215 while(getline(in, line) != NULL) 00216 { 00217 statusFile << line << std::endl; 00218 } 00219 00220 this->probe(); 00221 00222 if(in.eof() == false) 00223 { 00224 statusFile << "WARNING: /proc/self/status not read until EOF!!" << std::endl; 00225 } 00226 statusFile.close(); 00227 00228 // calculate and write progress: 00229 double progress = 0.0; 00230 if (this->maxSimTime > 0.0) 00231 { 00232 progress = curSimTime / this->maxSimTime; 00233 } 00234 progressFile << progress; 00235 progressFile.close(); 00236 } 00237 00238 00239 void 00240 StatusReport::probe() 00241 { 00242 if (memoryConsumption != NULL) 00243 { 00244 std::ifstream in( "/proc/self/statm"); 00245 unsigned long int sizeInPages(0); 00246 in >> sizeInPages; 00247 in.close(); 00248 unsigned long int pagesize = getpagesize(); // value from /proc/self/statm is in "pages" 00249 unsigned long int vmemUsage = pagesize * sizeInPages / 1024; // express in kB 00250 memoryConsumption->put(vmemUsage); 00251 } 00252 00253 if (simTimePerRealTime != NULL) 00254 { 00255 double curSimTime = wns::simulator::getEventScheduler()->getTime(); 00256 time_t curTime = time(NULL); 00257 double deltaSeconds = double(curTime - startTime); 00258 if(deltaSeconds > 0.0) 00259 simTimePerRealTime->put(curSimTime / deltaSeconds); 00260 } 00261 00262 }
1.5.5