Timer.h
Go to the documentation of this file.
1 /*!
2  *
3  *
4  * \brief Timer abstraction with microsecond resolution
5  *
6  *
7  *
8  * \author T. Voss, M. Tuma
9  * \date 2010
10  *
11  *
12  * \par Copyright 1995-2017 Shark Development Team
13  *
14  * <BR><HR>
15  * This file is part of Shark.
16  * <http://shark-ml.org/>
17  *
18  * Shark is free software: you can redistribute it and/or modify
19  * it under the terms of the GNU Lesser General Public License as published
20  * by the Free Software Foundation, either version 3 of the License, or
21  * (at your option) any later version.
22  *
23  * Shark is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26  * GNU Lesser General Public License for more details.
27  *
28  * You should have received a copy of the GNU Lesser General Public License
29  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
30  *
31  */
32 
33 #ifndef SHARK_CORE_TIMER_H
34 #define SHARK_CORE_TIMER_H
35 
36 
37 #ifdef _WIN32
38 #define WIN32_LEAN_AND_MEAN
39 #include <Windows.h>
40 #include <ctime>
41 #else
42 #include <sys/resource.h>
43 #include <sys/time.h>
44 #endif
45 
46 
47 namespace shark {
48 
49 
50 /// \brief Timer abstraction with microsecond resolution
51 ///
52 /// \par
53 /// Use start() to start the timer and stop() to retrive the
54 /// elapsed time in seconds (guaranteed/forced to be >= 0 ).
55 /// Use now() to get the current time (may in rare cases give decreasing values).
56 class Timer
57 {
58 public:
59  Timer(bool measureWallclockTime = true)
60  : m_lastLap( 0.0 )
61  , m_startTime( 0.0 )
62  , m_measureWallclockTime(measureWallclockTime)
63  { start();}
64 
65  /// \brief Returns the current time in a microsecond resolution. Att: may in rare cases give decreasing values.
66  static double now(bool measureWallclockTime = true) {
67 #ifdef _WIN32
68  if(measureWallclockTime){
69  return static_cast<double>(std::clock()) / CLOCKS_PER_SEC;
70  }
71  else{
72  LARGE_INTEGER tick, tps;
73  QueryPerformanceFrequency(&tps);
74  QueryPerformanceCounter(&tick);
75  return( static_cast<double>( tick.QuadPart ) / static_cast<double>( tps.QuadPart ) );
76  }
77 #else
78  if(measureWallclockTime){
79  timeval time;
80  if (gettimeofday(&time,0)){
81  // Handle error
82  return 0;
83  }
84  return time.tv_sec +1e-6 *time.tv_usec;
85  }
86  else
87  {
88  rusage res;
89  getrusage(RUSAGE_SELF, &res);
90  return(res.ru_utime.tv_sec + res.ru_stime.tv_sec)
91  + 1e-6 * (res.ru_utime.tv_usec + res.ru_stime.tv_usec);
92  }
93 #endif
94  }
95 
96  /// \brief Stores the current time in m_startTime.
97  void start() {
98  m_startTime = now(m_measureWallclockTime);
99  }
100 
101  /// \brief Returns the difference between current time and the start time.
102  ///
103  /// The time is meeasured since the last time start() was called. Thus several consecutive
104  /// calls to stop() will return ascending numbers. start() is called automatically at construction time.
105  double stop() {
106  double stop = now(m_measureWallclockTime);
107  m_lastLap = stop - m_startTime;
108 
109  // avoid rare cases of non-increasing timer values (cf. eg. http://www.linuxmisc.com/8-freebsd/d4c6ddc8fbfbd523.htm)
110 
111  if ( m_lastLap < 0.0 ) {
112  m_lastLap = 0.0;
113  }
114 
115  return m_lastLap;
116  }
117 
118  /// \brief Returns the last value of stop().
119  double lastLap() {
120  return m_lastLap;
121  }
122 
123 private:
124  double m_lastLap;
125  double m_startTime;
126  bool m_measureWallclockTime;
127 };
128 
129 
130 }
131 #endif
132