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
00039 #include "Timer.hpp"
00040 #include "MutexLock.hpp"
00041 #include "../Activity.hpp"
00042 #include "../Logger.hpp"
00043
00044 namespace RTT {
00045 using namespace base;
00046 using namespace os;
00047
00048 bool Timer::initialize() {
00049
00050 return this->getThread()->getPeriod() == 0;
00051 }
00052 void Timer::finalize() {}
00053
00054 void Timer::step() {
00055
00056 }
00057
00058 void Timer::loop()
00059 {
00060
00061 while (!mdo_quit) {
00062 Time wake_up_time;
00063 TimerId next_timer_id = 0;
00064
00065
00066 {
00067
00068
00069 MutexLock locker(m);
00070
00071
00072 wake_up_time = (TimeService::InfiniteNSecs/4)-1;
00073 for (TimerIds::iterator it = mtimers.begin(); it != mtimers.end(); ++it) {
00074 if ( it->first != 0 && it->first < wake_up_time ) {
00075 wake_up_time = it->first;
00076 next_timer_id = it - mtimers.begin();
00077 }
00078 }
00079 }
00080
00081
00082 int ret = 0;
00083 if ( wake_up_time > mTimeserv->getNSecs() )
00084 ret = msem.waitUntil( wake_up_time );
00085 else
00086 ret = -1;
00087
00088
00089 if (ret == -1) {
00090
00091
00092 {
00093 MutexLock locker(m);
00094
00095 if ( next_timer_id < int(mtimers.size()) ) {
00096
00097 TimerIds::iterator tim = mtimers.begin() + next_timer_id;
00098 if ( tim->second ) {
00099
00100 tim->first += tim->second;
00101 } else {
00102
00103 tim->first = 0;
00104 }
00105 }
00106 }
00107
00108
00109
00110
00111 timeout( next_timer_id );
00112 }
00113 }
00114 }
00115
00116 bool Timer::breakLoop()
00117 {
00118 mdo_quit = true;
00119 msem.signal();
00120 return true;
00121 }
00122
00123 Timer::Timer(TimerId max_timers, int scheduler, int priority)
00124 : mThread(0), msem(0), mdo_quit(false)
00125 {
00126 mTimeserv = TimeService::Instance();
00127 mtimers.resize(max_timers);
00128 if (scheduler != -1) {
00129 mThread = new Activity(scheduler, priority, 0.0, this, "Timer");
00130 mThread->start();
00131 }
00132 }
00133
00134 Timer::~Timer()
00135 {
00136 delete mThread;
00137 }
00138
00139
00140 void Timer::timeout(TimerId timer_id)
00141 {
00142
00143 }
00144
00145 void Timer::setMaxTimers(TimerId max)
00146 {
00147 MutexLock locker(m);
00148 mtimers.resize(max, std::make_pair(Time(0), Time(0)) );
00149 }
00150
00151 bool Timer::startTimer(TimerId timer_id, double period)
00152 {
00153 if ( timer_id < 0 || timer_id > int(mtimers.size()) || period < 0.0)
00154 {
00155 log(Error) << "Invalid timer id or period" << endlog();
00156 return false;
00157 }
00158
00159 Time due_time = mTimeserv->getNSecs() + Seconds_to_nsecs( period );
00160
00161 {
00162 MutexLock locker(m);
00163 mtimers[timer_id].first = due_time;
00164 mtimers[timer_id].second = Seconds_to_nsecs( period );
00165 }
00166 msem.signal();
00167 return true;
00168 }
00169
00170 bool Timer::arm(TimerId timer_id, double wait_time)
00171 {
00172 if ( timer_id < 0 || timer_id > int(mtimers.size()) || wait_time < 0.0)
00173 {
00174 log(Error) << "Invalid timer id or wait time" << endlog();
00175 return false;
00176 }
00177
00178 Time now = mTimeserv->getNSecs();
00179 Time due_time = now + Seconds_to_nsecs( wait_time );
00180
00181 {
00182 MutexLock locker(m);
00183 mtimers[timer_id].first = due_time;
00184 mtimers[timer_id].second = 0;
00185 }
00186 msem.signal();
00187 return true;
00188 }
00189
00190 bool Timer::isArmed(TimerId timer_id) const
00191 {
00192 MutexLock locker(m);
00193 if (timer_id < 0 || timer_id > int(mtimers.size()) )
00194 {
00195 log(Error) << "Invalid timer id" << endlog();
00196 return false;
00197 }
00198 return mtimers[timer_id].first != 0;
00199 }
00200
00201 double Timer::timeRemaining(TimerId timer_id) const
00202 {
00203 MutexLock locker(m);
00204 if (timer_id < 0 || timer_id > int(mtimers.size()) )
00205 {
00206 log(Error) << "Invalid timer id" << endlog();
00207 return 0.0;
00208 }
00209 Time now = mTimeserv->getNSecs();
00210 Time result = mtimers[timer_id].first - now;
00211
00212 if ( result < 0 )
00213 return 0.0;
00214 return nsecs_to_Seconds( result );
00215 }
00216
00217 bool Timer::killTimer(TimerId timer_id)
00218 {
00219 MutexLock locker(m);
00220 if (timer_id < 0 || timer_id > int(mtimers.size()) )
00221 {
00222 log(Error) << "Invalid timer id" << endlog();
00223 return false;
00224 }
00225 mtimers[timer_id].first = 0;
00226 mtimers[timer_id].second = 0;
00227 return true;
00228 }
00229
00230
00231
00232 }