Moka kernel
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
chrono.hh
Go to the documentation of this file.
1 /*
2  * lib-gmapkernel : Un noyau de 3-G-cartes et des opérations.
3  * Copyright (C) 2004, Moka Team, Université de Poitiers, Laboratoire SIC
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * Copyright (C) 2009, Guillaume Damiand, CNRS, LIRIS,
6  * guillaume.damiand@liris.cnrs.fr, http://liris.cnrs.fr/
7  *
8  * This file is part of lib-gmapkernel
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 //******************************************************************************
25 #ifndef CHRONO_HH
26 #define CHRONO_HH
27 //******************************************************************************
28 //#include <sys/types.h>
29 #include <sys/time.h>
30 #include <sys/resource.h>
31 #include <string>
32 #include <sstream>
33 #include <iomanip>
34 #include <iostream>
35 //******************************************************************************
36 /* Classe pour chronométrer. Le chrono est initialisé à 0 et
37  * additionne les temps entre des start() et des stop(). reset()
38  * permet de remettre le chrono à zéro.
39  * La méthode displayRealTime permet de choisir si l'affichage du temps
40  * est en mode réel (i.e. en 10-6 secondes) ou utilisateur (affichage
41  * dépendant du temps passé s, ms ou us). Par défaut utilisateur.
42  * La méthode setMode permet de choisir le mode de chronométrage :
43  * REEL_MODE : horloge temps réel (temps réel écoulé depuis le start)
44  * PUS_MODE : horloge processus (temps consommé par le processus)
45  * REEL_AND_PUS_MODE : les 2 en même temps, mode par défaut.
46  */
47 //******************************************************************************
52 //******************************************************************************
53 class CChrono
54 {
55 public:
56 
60  CChrono ( TModeChrono AMode=REEL_AND_PUS_MODE, bool ADisplayReal=true);
61 
63  CChrono ( const CChrono& AChrono );
64 
66  CChrono& operator=( const CChrono& AChrono );
67 
71  CChrono& operator+=( const CChrono& AChrono );
72 
76  CChrono operator+( const CChrono& AChrono ) const;
77 
81  CChrono& operator-=( const CChrono& AChrono );
82 
86  CChrono operator-( const CChrono& AChrono ) const;
87 
90  void start ();
91 
94  void stop ();
95 
97  void reset();
98 
103  std::string getTime ( const std::string& AMessage );
104 
108  void display ( const std::string& AMessage );
109 
114  void displayRealTime( bool AValue );
115 
118  void setMode( TModeChrono AValue );
119 
120 private:
123  std::string convertTimeval( const struct timeval& ATimeval ) const;
124 
126  void pickTimeReel( struct timeval& ATimeval ) const;
127 
129  void pickTimePus( struct rusage& ARusage ) const;
130 
131  struct rusage FBeforePus;
132  struct rusage FAfterPus;
133  struct rusage FTotalPus;
134 
135 
136  struct timeval FBeforeReel;
137  struct timeval FAfterReel;
138  struct timeval FTotalReel;
139 
140 
141  bool FDisplayReal;
142 
143  TModeChrono FMode;
144  bool FRun;
145 };
146 //******************************************************************************
147 //* Ici le code, tout est en inline. *******************************************
148 //******************************************************************************
149 inline
150 CChrono::CChrono( TModeChrono AMode, bool ADisplayReal ) :
151  FDisplayReal(ADisplayReal),
152  FMode(AMode),
153  FRun(false)
154 {
155  FTotalPus.ru_utime.tv_sec = 0; FTotalPus.ru_utime.tv_usec = 0;
156 
157  FTotalPus.ru_stime.tv_sec = 0; FTotalPus.ru_stime.tv_usec = 0;
158 
159  FTotalReel.tv_sec = 0; FTotalReel.tv_usec = 0;
160 }
161 //------------------------------------------------------------------------------
162 inline
163 CChrono::CChrono( const CChrono& AChrono ) :
164  FBeforePus (AChrono.FBeforePus),
165  FAfterPus (AChrono.FAfterPus),
166  FTotalPus (AChrono.FTotalPus),
167  FBeforeReel (AChrono.FBeforeReel),
168  FAfterReel (AChrono.FAfterReel),
169  FTotalReel (AChrono.FTotalReel),
170  FDisplayReal(AChrono.FDisplayReal),
171  FMode (AChrono.FMode),
172  FRun (AChrono.FRun)
173 {}
174 //******************************************************************************
175 inline
176 void addTimeval( struct timeval& ATimeval, const struct timeval& ATimeval2)
177 {
178  ATimeval.tv_sec += ATimeval2.tv_sec;
179  ATimeval.tv_usec += ATimeval2.tv_usec;
180  if ( ATimeval.tv_usec >= 10000000 )
181  {
182  ++ATimeval.tv_sec;
183  ATimeval.tv_usec -= 1000000;
184  }
185 }
186 //------------------------------------------------------------------------------
187 inline
188 void substractTimeval( struct timeval& ATimeval, const struct timeval& ATimeval2)
189 {
190  ATimeval.tv_sec -= ATimeval2.tv_sec;
191  ATimeval.tv_usec -= ATimeval2.tv_usec;
192  if ( ATimeval.tv_usec < 0 )
193  {
194  --ATimeval.tv_sec;
195  ATimeval.tv_usec += 1000000;
196  }
197 }
198 //------------------------------------------------------------------------------
199 inline
200 void CChrono::pickTimeReel( struct timeval& ATimeval ) const
201 {
202  gettimeofday(&ATimeval,NULL);
203 }
204 //------------------------------------------------------------------------------
205 inline
206 void CChrono::pickTimePus( struct rusage& ARusage ) const
207 {
208  getrusage(RUSAGE_SELF, &ARusage);
209 }
210 //******************************************************************************
211 inline
213 {
214  FBeforePus = AChrono.FBeforePus;
215  FAfterPus = AChrono.FAfterPus;
216  FTotalPus = AChrono.FTotalPus;
217 
218  FBeforeReel = AChrono.FBeforeReel;
219  FAfterReel = AChrono.FAfterReel;
220  FTotalReel = AChrono.FTotalReel;
221 
222  FDisplayReal = AChrono.FDisplayReal;
223  FMode = AChrono.FMode;
224  FRun = AChrono.FRun;
225 
226  return *this;
227 }
228 //------------------------------------------------------------------------------
229 inline
231 {
232  addTimeval( FTotalPus.ru_utime, AChrono.FTotalPus.ru_utime );
233  addTimeval( FTotalPus.ru_stime, AChrono.FTotalPus.ru_stime );
234  addTimeval( FTotalReel, AChrono.FTotalReel );
235 
236  return *this;
237 }
238 //------------------------------------------------------------------------------
239 inline
240 CChrono CChrono::operator+( const CChrono& AChrono ) const
241 {
242  CChrono res(*this);
243  res += AChrono;
244 
245  return res;
246 }
247 //******************************************************************************
248 inline
250 {
251  substractTimeval( FTotalPus.ru_utime, AChrono.FTotalPus.ru_utime );
252  substractTimeval( FTotalPus.ru_stime, AChrono.FTotalPus.ru_stime );
253  substractTimeval( FTotalReel, AChrono.FTotalReel );
254 
255  return *this;
256 }
257 //------------------------------------------------------------------------------
258 inline
259 CChrono CChrono::operator-( const CChrono& AChrono ) const
260 {
261  CChrono res(*this);
262  res -= AChrono;
263 
264  return res;
265 }
266 //******************************************************************************
267 inline
269 {
270  if ( !FRun )
271  {
272  pickTimePus ( FBeforePus );
273  pickTimeReel( FBeforeReel );
274  FRun = true;
275  }
276 }
277 //------------------------------------------------------------------------------
278 inline
280 {
281  if ( FRun )
282  {
283  // Récupération de l'horloge courante.
284  pickTimeReel( FAfterReel );
285  pickTimePus ( FAfterPus );
286 
287  // Calcul de FAfter = FAfter-FBefore
288  substractTimeval( FAfterPus.ru_utime, FBeforePus.ru_utime );
289  substractTimeval( FAfterPus.ru_stime, FBeforePus.ru_stime );
290  substractTimeval( FAfterReel, FBeforeReel );
291 
292  // Ajout dans FTotal
293  addTimeval( FTotalPus.ru_utime, FAfterPus.ru_utime );
294  addTimeval( FTotalPus.ru_stime, FAfterPus.ru_stime );
295  addTimeval( FTotalReel, FAfterReel );
296 
297  FRun = false;
298  }
299 }
300 //------------------------------------------------------------------------------
301 inline
303 {
304  FTotalPus.ru_utime.tv_sec = 0; FTotalPus.ru_utime.tv_usec = 0;
305 
306  FTotalPus.ru_stime.tv_sec = 0; FTotalPus.ru_stime.tv_usec = 0;
307 
308  FTotalReel.tv_sec = 0; FTotalReel.tv_usec = 0;
309 
310  FRun = false;
311 }
312 //******************************************************************************
313 inline
315 {
316  FMode = AMode;
317  if ( FRun )
318  {
319  stop();
320  reset();
321  }
322 }
323 //------------------------------------------------------------------------------
324 inline
325 void CChrono::displayRealTime( bool AValue )
326 { FDisplayReal = AValue; }
327 //******************************************************************************
328 inline
329 std::string CChrono::convertTimeval ( const struct timeval & ATimeval ) const
330 {
331  std::ostringstream res;
332 
333  if ( FDisplayReal )
334  { // Mode réel.
335  res<<ATimeval.tv_sec<<'.'
336  <<std::setw(6)<<std::setfill('0')<<ATimeval.tv_usec<<" s";
337  }
338  else
339  {
340  // Mode utilisateur cad on prend l'unité appropriée.
341  if ( ATimeval.tv_sec!=0 || ATimeval.tv_usec>=150000 )
342  res<<ATimeval.tv_sec<<'.'
343  <<std::setw(2)<<std::setfill('0')
344  <<(int)(ATimeval.tv_usec/10000)<<" s";
345  { // Ici il y a 0 secondes
346  if ( ATimeval.tv_usec>1500 )
347  res<<std::setprecision(2)<<std::fixed
348  <<ATimeval.tv_usec/1000.<<" ms (10-3 s)";
349  else
350  res<<ATimeval.tv_usec<<" us (10-6 s)";
351  }
352  }
353 
354  return res.str();
355 }
356 //******************************************************************************
357 inline
358 std::string CChrono::getTime ( const std::string& AMessage )
359 {
360  bool rerun = false;
361  std::ostringstream res;
362 
363  if ( FRun )
364  {
365  rerun = true;
366  stop();
367  }
368 
369  res<<AMessage<<" : ";
370  if ( FMode==PUS_MODE || FMode==REEL_AND_PUS_MODE )
371  {
372  res<<convertTimeval(FTotalPus.ru_utime)<<" user, ";
373  res<<convertTimeval(FTotalPus.ru_stime)<<" sys";
374  }
375 
376  if ( FMode==REEL_AND_PUS_MODE ) res<<", ";
377 
378  if ( FMode==REEL_MODE || FMode==REEL_AND_PUS_MODE )
379  res<<convertTimeval(FTotalReel)<<" reel";
380 
381  if ( rerun )
382  start();
383 
384  return res.str();
385 }
386 //------------------------------------------------------------------------------
387 inline
388 void CChrono::display ( const std::string& AMessage )
389 { std::cout<<getTime(AMessage)<<std::endl; }
390 //******************************************************************************
391 #endif // CHRONO_HH
392 //******************************************************************************
393