Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "TimerThread.hpp"
00039 #include "PeriodicActivity.hpp"
00040
00041 #include "rtt-config.h"
00042
00043 #include "../Time.hpp"
00044 #include "../Logger.hpp"
00045 #include <algorithm>
00046 #include "../os/MutexLock.hpp"
00047
00048 namespace RTT {
00049 using namespace extras;
00050 using namespace base;
00051 using os::MutexLock;
00052 using namespace std;
00053
00054 TimerThread::TimerThreadList TimerThread::TimerThreads;
00055
00056 TimerThreadPtr TimerThread::Instance(int pri, double per)
00057 {
00058 return Instance(ORO_SCHED_RT, pri, per);
00059 }
00060
00061 TimerThreadPtr TimerThread::Instance(int scheduler, int pri, double per)
00062 {
00063 return Instance(scheduler, pri, per, ~0);
00064 }
00065
00066 TimerThreadPtr TimerThread::Instance(int scheduler, int pri, double per, unsigned cpu_affinity)
00067 {
00068
00069
00070 os::CheckPriority(scheduler, pri);
00071 TimerThreadList::iterator it = TimerThreads.begin();
00072 while ( it != TimerThreads.end() ) {
00073 TimerThreadPtr tptr = it->lock();
00074
00075 if ( !tptr ) {
00076 TimerThreads.erase(it);
00077 it = TimerThreads.begin();
00078 continue;
00079 }
00080 if ( tptr->getScheduler() == scheduler && tptr->getPriority() == pri && tptr->getPeriodNS() == Seconds_to_nsecs(per) ) {
00081 return tptr;
00082 }
00083 ++it;
00084 }
00085 TimerThreadPtr ret( new TimerThread(scheduler, pri, "TimerThreadInstance", per, cpu_affinity) );
00086 TimerThreads.push_back( ret );
00087 return ret;
00088 }
00089
00090 TimerThread::TimerThread(int priority, const std::string& name, double periodicity, unsigned cpu_affinity)
00091 : Thread( ORO_SCHED_RT, priority, periodicity, cpu_affinity, name), cleanup(false)
00092 {
00093 tasks.reserve(MAX_ACTIVITIES);
00094 }
00095
00096 TimerThread::TimerThread(int scheduler, int priority, const std::string& name, double periodicity, unsigned cpu_affinity)
00097 : Thread(scheduler, priority, periodicity, cpu_affinity, name), cleanup(false)
00098 {
00099 tasks.reserve(MAX_ACTIVITIES);
00100 }
00101
00102 TimerThread::~TimerThread()
00103 {
00104
00105 this->stop();
00106 }
00107
00108 bool TimerThread::addActivity( PeriodicActivity* t ) {
00109 MutexLock lock(mutex);
00110 if ( tasks.size() == MAX_ACTIVITIES ) {
00111
00112 return false;
00113 }
00114 tasks.push_back( t );
00115
00116 return true;
00117 }
00118
00119 bool TimerThread::removeActivity( PeriodicActivity* t ) {
00120 MutexLock lock(mutex);
00121 ActivityList::iterator it = find(tasks.begin(), tasks.end(), t);
00122 if ( it != tasks.end() ) {
00123 *it = 0;
00124 cleanup = true;
00125 return true;
00126 }
00127
00128 return false;
00129 }
00130
00131 bool TimerThread::initialize() {
00132 return true;
00133 }
00134
00135 void TimerThread::finalize() {
00136 MutexLock lock(mutex);
00137
00138 for( ActivityList::iterator t_iter = tasks.begin(); t_iter != tasks.end(); ++t_iter)
00139 if ( *t_iter )
00140 (*t_iter)->stop();
00141 if ( cleanup )
00142 this->reorderList();
00143 }
00144
00145 void TimerThread::step() {
00146 MutexLock lock(mutex);
00147
00148
00149
00150 for( ActivityList::iterator t_iter = tasks.begin(); t_iter != tasks.end(); ++t_iter)
00151 if ( *t_iter )
00152 (*t_iter)->step();
00153
00154 if ( cleanup )
00155 this->reorderList();
00156 }
00157
00158 void TimerThread::reorderList() {
00159
00160 ActivityList::iterator begin = tasks.begin();
00161
00162 PeriodicActivity* nullActivity = 0;
00163 ActivityList::iterator it = tasks.begin();
00164
00165 it = find( tasks.begin(), tasks.end(), nullActivity);
00166 begin = it+1;
00167 while ( it != tasks.end() ) {
00168
00169 while ( begin != tasks.end() && *begin == 0 )
00170 ++begin;
00171 if ( begin == tasks.end() ) {
00172
00173 tasks.resize( it - tasks.begin() );
00174
00175 break;
00176 }
00177
00178 ActivityList::iterator end = find ( begin, tasks.end(), nullActivity);
00179
00180
00181 while ( begin != end ) {
00182 *it = *begin;
00183 ++begin;
00184 ++it;
00185 }
00186 }
00187
00188 cleanup = false;
00189 }
00190
00191
00192 }