Orocos Real-Time Toolkit  2.5.0
PeriodicActivity.cpp
00001 /***************************************************************************
00002   tag: Peter Soetens  Mon May 10 19:10:29 CEST 2004  PeriodicActivity.cxx
00003 
00004                         PeriodicActivity.cxx -  description
00005                            -------------------
00006     begin                : Mon May 10 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 #ifdef ORO_PRAGMA_INTERFACE
00039 #pragma implementation
00040 #endif
00041 #include "../Time.hpp"
00042 #include "PeriodicActivity.hpp"
00043 #include "../os/MutexLock.hpp"
00044 #include "../Logger.hpp"
00045 #include "TimerThread.hpp"
00046 #include <cmath>
00047 
00048 namespace RTT {
00049     using namespace extras;
00050     using namespace base;
00051 
00052     PeriodicActivity::PeriodicActivity(int priority, Seconds period, RunnableInterface* r )
00053         : ActivityInterface(r), running(false), active(false),
00054           thread_( TimerThread::Instance(priority,period) )
00055     {
00056         this->init();
00057     }
00058 
00059     PeriodicActivity::PeriodicActivity(int scheduler, int priority, Seconds period, RunnableInterface* r )
00060         : ActivityInterface(r), running(false), active(false),
00061           thread_( TimerThread::Instance(scheduler, priority,period) )
00062     {
00063         this->init();
00064     }
00065 
00066     PeriodicActivity::PeriodicActivity(int scheduler, int priority, Seconds period, unsigned cpu_affinity, RunnableInterface* r )
00067         : ActivityInterface(r), running(false), active(false),
00068           thread_( TimerThread::Instance(scheduler, priority, period, cpu_affinity) )
00069     {
00070         this->init();
00071     }
00072 
00073     PeriodicActivity::PeriodicActivity(TimerThreadPtr thread, RunnableInterface* r )
00074         : ActivityInterface(r), running(false), active(false),
00075           thread_( thread )
00076     {
00077         this->init();
00078     }
00079 
00080     PeriodicActivity::PeriodicActivity(Seconds period, TimerThreadPtr thread, RunnableInterface* r )
00081         : ActivityInterface(r), running(false), active(false),
00082           thread_(thread)
00083     {
00084         this->init();
00085     }
00086 
00087     PeriodicActivity::PeriodicActivity(secs s, nsecs ns, TimerThreadPtr thread, RunnableInterface* r )
00088         : ActivityInterface(r),
00089           running(false), active(false),
00090           thread_(thread)
00091     {
00092         this->init();
00093     }
00094 
00095     PeriodicActivity::~PeriodicActivity()
00096     {
00097         stop();
00098     }
00099 
00100     void PeriodicActivity::init() {
00101     }
00102 
00103     bool PeriodicActivity::start()
00104     {
00105         if ( isActive() || !thread_ ) {
00106             //Logger::log() << Logger::Error << "PeriodicActivity : already active or thread not running." << Logger::endl;
00107             return false;
00108         }
00109         // If thread is not yet running, try to start it.
00110         if ( !thread_->isRunning() && thread_->start() == false )
00111             return false;
00112 
00113         active = true;
00114         bool inError = !this->initialize();
00115         if ( inError ) {
00116             //Logger::log() << Logger::Error << "PeriodicActivity : initialize() returned false " << Logger::endl;
00117             active = false;
00118             return false;
00119         }
00120 
00121         bool res;
00122         res = thread_->addActivity( this );
00123         if ( res == false ) {
00124             //Logger::log() << Logger::Error << "PeriodicActivity : addActivity() returned false " << Logger::endl;
00125             this->finalize();
00126             active = false;
00127             return false;
00128         }
00129 
00130         running = true;
00131         return true;
00132     }
00133 
00134     bool PeriodicActivity::stop()
00135     {
00136         if ( !isActive() ) return false;
00137 
00138         // since removeActivity synchronises, we do not need to mutex-lock
00139         // stop()
00140         if ( thread_->removeActivity( this ) ) {
00141             running = false;
00142             this->finalize();
00143             active = false;
00144             return true;
00145         }
00146         return false;
00147     }
00148 
00149     bool PeriodicActivity::isRunning() const
00150     {
00151         return running;
00152     }
00153 
00154     bool PeriodicActivity::isActive() const
00155     {
00156         return active;
00157     }
00158 
00159     Seconds PeriodicActivity::getPeriod() const
00160     {
00161         return thread_->getPeriod();
00162     }
00163 
00164     bool PeriodicActivity::setPeriod(Seconds s) {
00165         return false;
00166     }
00167 
00168     unsigned PeriodicActivity::getCpuAffinity() const
00169     {
00170       return thread_->getCpuAffinity();
00171     }
00172 
00173     bool PeriodicActivity::setCpuAffinity(unsigned cpu)
00174     {
00175       return thread_->setCpuAffinity(cpu);
00176     }
00177 
00178     bool PeriodicActivity::initialize() {
00179         if (runner != 0)
00180             return runner->initialize();
00181         else
00182             return true;
00183     }
00184 
00185     bool PeriodicActivity::execute()
00186     {
00187         return false;
00188     }
00189 
00190     bool PeriodicActivity::trigger()
00191     {
00192         return false;
00193     }
00194 
00195     void PeriodicActivity::step()
00196     {
00197         // override this method to avoid running runner.
00198         if (runner != 0)
00199             runner->step();
00200     }
00201 
00202     void PeriodicActivity::finalize() {
00203         if (runner != 0)
00204             runner->finalize();
00205     }
00206 
00207     os::ThreadInterface* PeriodicActivity::thread() { return thread_.get(); }
00208 
00209     bool PeriodicActivity::isPeriodic() const {
00210         return true;
00211     }
00212 }