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 #ifndef CHRONO_HH
00026 #define CHRONO_HH
00027
00028
00029 #include <sys/time.h>
00030 #include <sys/resource.h>
00031 #include <string>
00032 #include <sstream>
00033 #include <iomanip>
00034 #include <iostream>
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00051 typedef enum { REEL_MODE, PUS_MODE, REEL_AND_PUS_MODE } TModeChrono;
00052
00053 class CChrono
00054 {
00055 public:
00056
00060 CChrono ( TModeChrono AMode=REEL_AND_PUS_MODE, bool ADisplayReal=true);
00061
00063 CChrono ( const CChrono& AChrono );
00064
00066 CChrono& operator=( const CChrono& AChrono );
00067
00071 CChrono& operator+=( const CChrono& AChrono );
00072
00076 CChrono operator+( const CChrono& AChrono ) const;
00077
00081 CChrono& operator-=( const CChrono& AChrono );
00082
00086 CChrono operator-( const CChrono& AChrono ) const;
00087
00090 void start ();
00091
00094 void stop ();
00095
00097 void reset();
00098
00103 std::string getTime ( const std::string& AMessage );
00104
00108 void display ( const std::string& AMessage );
00109
00114 void displayRealTime( bool AValue );
00115
00118 void setMode( TModeChrono AValue );
00119
00120 private:
00123 std::string convertTimeval( const struct timeval& ATimeval ) const;
00124
00126 void pickTimeReel( struct timeval& ATimeval ) const;
00127
00129 void pickTimePus( struct rusage& ARusage ) const;
00130
00131 struct rusage FBeforePus;
00132 struct rusage FAfterPus;
00133 struct rusage FTotalPus;
00134
00135
00136 struct timeval FBeforeReel;
00137 struct timeval FAfterReel;
00138 struct timeval FTotalReel;
00139
00140
00141 bool FDisplayReal;
00142
00143 TModeChrono FMode;
00144 bool FRun;
00145 };
00146
00147
00148
00149 inline
00150 CChrono::CChrono( TModeChrono AMode, bool ADisplayReal ) :
00151 FDisplayReal(ADisplayReal),
00152 FMode(AMode),
00153 FRun(false)
00154 {
00155 FTotalPus.ru_utime.tv_sec = 0; FTotalPus.ru_utime.tv_usec = 0;
00156
00157 FTotalPus.ru_stime.tv_sec = 0; FTotalPus.ru_stime.tv_usec = 0;
00158
00159 FTotalReel.tv_sec = 0; FTotalReel.tv_usec = 0;
00160 }
00161
00162 inline
00163 CChrono::CChrono( const CChrono& AChrono ) :
00164 FBeforePus (AChrono.FBeforePus),
00165 FAfterPus (AChrono.FAfterPus),
00166 FTotalPus (AChrono.FTotalPus),
00167 FBeforeReel (AChrono.FBeforeReel),
00168 FAfterReel (AChrono.FAfterReel),
00169 FTotalReel (AChrono.FTotalReel),
00170 FDisplayReal(AChrono.FDisplayReal),
00171 FMode (AChrono.FMode),
00172 FRun (AChrono.FRun)
00173 {}
00174
00175 inline
00176 void addTimeval( struct timeval& ATimeval, const struct timeval& ATimeval2)
00177 {
00178 ATimeval.tv_sec += ATimeval2.tv_sec;
00179 ATimeval.tv_usec += ATimeval2.tv_usec;
00180 if ( ATimeval.tv_usec >= 10000000 )
00181 {
00182 ++ATimeval.tv_sec;
00183 ATimeval.tv_usec -= 1000000;
00184 }
00185 }
00186
00187 inline
00188 void substractTimeval( struct timeval& ATimeval, const struct timeval& ATimeval2)
00189 {
00190 ATimeval.tv_sec -= ATimeval2.tv_sec;
00191 ATimeval.tv_usec -= ATimeval2.tv_usec;
00192 if ( ATimeval.tv_usec < 0 )
00193 {
00194 --ATimeval.tv_sec;
00195 ATimeval.tv_usec += 1000000;
00196 }
00197 }
00198
00199 inline
00200 void CChrono::pickTimeReel( struct timeval& ATimeval ) const
00201 {
00202 gettimeofday(&ATimeval,NULL);
00203 }
00204
00205 inline
00206 void CChrono::pickTimePus( struct rusage& ARusage ) const
00207 {
00208 getrusage(RUSAGE_SELF, &ARusage);
00209 }
00210
00211 inline
00212 CChrono& CChrono::operator=( const CChrono& AChrono )
00213 {
00214 FBeforePus = AChrono.FBeforePus;
00215 FAfterPus = AChrono.FAfterPus;
00216 FTotalPus = AChrono.FTotalPus;
00217
00218 FBeforeReel = AChrono.FBeforeReel;
00219 FAfterReel = AChrono.FAfterReel;
00220 FTotalReel = AChrono.FTotalReel;
00221
00222 FDisplayReal = AChrono.FDisplayReal;
00223 FMode = AChrono.FMode;
00224 FRun = AChrono.FRun;
00225
00226 return *this;
00227 }
00228
00229 inline
00230 CChrono& CChrono::operator+=( const CChrono& AChrono )
00231 {
00232 addTimeval( FTotalPus.ru_utime, AChrono.FTotalPus.ru_utime );
00233 addTimeval( FTotalPus.ru_stime, AChrono.FTotalPus.ru_stime );
00234 addTimeval( FTotalReel, AChrono.FTotalReel );
00235
00236 return *this;
00237 }
00238
00239 inline
00240 CChrono CChrono::operator+( const CChrono& AChrono ) const
00241 {
00242 CChrono res(*this);
00243 res += AChrono;
00244
00245 return res;
00246 }
00247
00248 inline
00249 CChrono& CChrono::operator-=( const CChrono& AChrono )
00250 {
00251 substractTimeval( FTotalPus.ru_utime, AChrono.FTotalPus.ru_utime );
00252 substractTimeval( FTotalPus.ru_stime, AChrono.FTotalPus.ru_stime );
00253 substractTimeval( FTotalReel, AChrono.FTotalReel );
00254
00255 return *this;
00256 }
00257
00258 inline
00259 CChrono CChrono::operator-( const CChrono& AChrono ) const
00260 {
00261 CChrono res(*this);
00262 res -= AChrono;
00263
00264 return res;
00265 }
00266
00267 inline
00268 void CChrono::start ()
00269 {
00270 if ( !FRun )
00271 {
00272 pickTimePus ( FBeforePus );
00273 pickTimeReel( FBeforeReel );
00274 FRun = true;
00275 }
00276 }
00277
00278 inline
00279 void CChrono::stop ()
00280 {
00281 if ( FRun )
00282 {
00283
00284 pickTimeReel( FAfterReel );
00285 pickTimePus ( FAfterPus );
00286
00287
00288 substractTimeval( FAfterPus.ru_utime, FBeforePus.ru_utime );
00289 substractTimeval( FAfterPus.ru_stime, FBeforePus.ru_stime );
00290 substractTimeval( FAfterReel, FBeforeReel );
00291
00292
00293 addTimeval( FTotalPus.ru_utime, FAfterPus.ru_utime );
00294 addTimeval( FTotalPus.ru_stime, FAfterPus.ru_stime );
00295 addTimeval( FTotalReel, FAfterReel );
00296
00297 FRun = false;
00298 }
00299 }
00300
00301 inline
00302 void CChrono::reset()
00303 {
00304 FTotalPus.ru_utime.tv_sec = 0; FTotalPus.ru_utime.tv_usec = 0;
00305
00306 FTotalPus.ru_stime.tv_sec = 0; FTotalPus.ru_stime.tv_usec = 0;
00307
00308 FTotalReel.tv_sec = 0; FTotalReel.tv_usec = 0;
00309
00310 FRun = false;
00311 }
00312
00313 inline
00314 void CChrono::setMode( TModeChrono AMode )
00315 {
00316 FMode = AMode;
00317 if ( FRun )
00318 {
00319 stop();
00320 reset();
00321 }
00322 }
00323
00324 inline
00325 void CChrono::displayRealTime( bool AValue )
00326 { FDisplayReal = AValue; }
00327
00328 inline
00329 std::string CChrono::convertTimeval ( const struct timeval & ATimeval ) const
00330 {
00331 std::ostringstream res;
00332
00333 if ( FDisplayReal )
00334 {
00335 res<<ATimeval.tv_sec<<'.'
00336 <<std::setw(6)<<std::setfill('0')<<ATimeval.tv_usec<<" s";
00337 }
00338 else
00339 {
00340
00341 if ( ATimeval.tv_sec!=0 || ATimeval.tv_usec>=150000 )
00342 res<<ATimeval.tv_sec<<'.'
00343 <<std::setw(2)<<std::setfill('0')
00344 <<(int)(ATimeval.tv_usec/10000)<<" s";
00345 {
00346 if ( ATimeval.tv_usec>1500 )
00347 res<<std::setprecision(2)<<std::fixed
00348 <<ATimeval.tv_usec/1000.<<" ms (10-3 s)";
00349 else
00350 res<<ATimeval.tv_usec<<" us (10-6 s)";
00351 }
00352 }
00353
00354 return res.str();
00355 }
00356
00357 inline
00358 std::string CChrono::getTime ( const std::string& AMessage )
00359 {
00360 bool rerun = false;
00361 std::ostringstream res;
00362
00363 if ( FRun )
00364 {
00365 rerun = true;
00366 stop();
00367 }
00368
00369 res<<AMessage<<" : ";
00370 if ( FMode==PUS_MODE || FMode==REEL_AND_PUS_MODE )
00371 {
00372 res<<convertTimeval(FTotalPus.ru_utime)<<" user, ";
00373 res<<convertTimeval(FTotalPus.ru_stime)<<" sys";
00374 }
00375
00376 if ( FMode==REEL_AND_PUS_MODE ) res<<", ";
00377
00378 if ( FMode==REEL_MODE || FMode==REEL_AND_PUS_MODE )
00379 res<<convertTimeval(FTotalReel)<<" reel";
00380
00381 if ( rerun )
00382 start();
00383
00384 return res.str();
00385 }
00386
00387 inline
00388 void CChrono::display ( const std::string& AMessage )
00389 { std::cout<<getTime(AMessage)<<std::endl; }
00390
00391 #endif // CHRONO_HH
00392
00393