00001 /*************************************************************************** 00002 tag: Peter Soetens Tue Dec 21 22:43:07 CET 2004 SimulationThread.cxx 00003 00004 SimulationThread.cxx - description 00005 ------------------- 00006 begin : Tue December 21 2004 00007 copyright : (C) 2004 Peter Soetens 00008 email : peter.soetens@mech.kuleuven.ac.be 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; * 00014 * version 2 of the License. * 00015 * * 00016 * As a special exception, you may use this file as part of a free * 00017 * software library without restriction. Specifically, if other files * 00018 * instantiate templates or use macros or inline functions from this * 00019 * file, or you compile this file and link it with other files to * 00020 * produce an executable, this file does not by itself cause the * 00021 * resulting executable to be covered by the GNU General Public * 00022 * License. This exception does not however invalidate any other * 00023 * reasons why the executable file might be covered by the GNU General * 00024 * Public License. * 00025 * * 00026 * This library is distributed in the hope that it will be useful, * 00027 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00029 * Lesser General Public License for more details. * 00030 * * 00031 * You should have received a copy of the GNU General Public * 00032 * License along with this library; if not, write to the Free Software * 00033 * Foundation, Inc., 59 Temple Place, * 00034 * Suite 330, Boston, MA 02111-1307 USA * 00035 * * 00036 ***************************************************************************/ 00037 00038 00039 00040 #include "SimulationThread.hpp" 00041 #include "TimeService.hpp" 00042 #include "SimulationActivity.hpp" 00043 #include "Logger.hpp" 00044 #include <os/threads.hpp> 00045 00046 #include <os/StartStopManager.hpp> 00047 namespace RTT 00048 { 00049 namespace 00050 { 00051 // Stop it before the application quits. 00052 void stopSIMThread() 00053 { 00054 SimulationThread::Release(); 00055 } 00056 00057 OS::CleanupFunction SIMCleanup( &stopSIMThread ); 00058 } 00059 } 00060 00061 namespace RTT 00062 { 00063 00064 // The static class variables 00065 SimulationThreadPtr SimulationThread::_instance; 00066 00067 SimulationThreadPtr SimulationThread::Instance(double period) 00068 { 00069 if ( !_instance ) 00070 { 00071 _instance.reset( new SimulationThread(period) ); 00072 } 00073 00074 return _instance; 00075 } 00076 00077 bool SimulationThread::Release() 00078 { 00079 _instance.reset(); 00080 return true; 00081 } 00082 00083 00084 SimulationThread::SimulationThread(double period) 00085 : TimerThread( OS::LowestPriority, 00086 "SimulationThread", 00087 period), 00088 beat( TimeService::Instance() ), maxsteps_(0), sim_running(false) 00089 { 00090 this->setScheduler(ORO_SCHED_OTHER); 00091 this->continuousStepping( true ); 00092 Logger::log() << Logger::Info << this->getName() <<" created with "<< this->getPeriod() <<"s periodicity"; 00093 Logger::log() << Logger::Info << " and priority " << this->getPriority() << Logger::endl; 00094 } 00095 00096 SimulationThread::~SimulationThread() 00097 { 00098 } 00099 00100 bool SimulationThread::isRunning() const 00101 { 00102 return sim_running || PeriodicThread::isRunning(); 00103 } 00104 00105 bool SimulationThread::start() 00106 { 00107 maxsteps_ = 0; 00108 return OS::PeriodicThread::start(); 00109 } 00110 00111 bool SimulationThread::start(unsigned int maxsteps) 00112 { 00113 if (maxsteps == 0) 00114 return false; 00115 maxsteps_ = maxsteps; 00116 return OS::PeriodicThread::start(); 00117 } 00118 00119 bool SimulationThread::run(unsigned int ms) 00120 { 00121 if ( ms == 0 || this->isRunning() || this->initialize() == false ) 00122 return false; 00123 unsigned int cur = 0; 00124 this->sim_running = true; 00125 while( cur != ms ) { 00126 ++cur; 00127 TimerThread::step(); 00128 beat->secondsChange(this->getPeriod()); 00129 } 00130 this->sim_running = false; 00131 this->finalize(); 00132 return true; 00133 } 00134 00135 bool SimulationThread::initialize() 00136 { 00137 Logger::log() << Logger::Info << "SimulationThread takes over system time."<<Logger::nl; 00138 Logger::log() << Logger::Info << "System time will increase significantly faster."<<Logger::endl; 00139 00140 // we will update the clock in step() 00141 beat->enableSystemClock( false ); 00142 00143 cursteps = 0; 00144 // No TimerThread::initialize() to allow 'freeze' 00145 return true; 00146 } 00147 00148 void SimulationThread::finalize() 00149 { 00150 Logger::log() << Logger::Info << "SimulationThread releases system time."<<Logger::endl; 00151 // release systemclock again. 00152 beat->enableSystemClock( true ); 00153 00154 // DO NOT CALL TimerThread::finalize(), since we want to be able to start/stop the 00155 // SimulationThread and inspect the activities still running. 00156 } 00157 00158 void SimulationThread::step() 00159 { 00160 ++cursteps; 00161 00162 if ( maxsteps_ == 0 || cursteps < maxsteps_ + 1 ) { 00163 TimerThread::step(); 00164 beat->secondsChange(this->getPeriod()); 00165 } 00166 00167 // call stop once : 00168 if ( cursteps == maxsteps_ ) { // if maxsteps == 0, will never call stop(). 00169 this->setToStop(); 00170 } 00171 } 00172 00173 }
1.5.3