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 * <https://shark-ml.github.io/Shark/>
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
47namespace 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).
56class Timer
57{
58public:
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
123private:
124 double m_lastLap;
125 double m_startTime;
126 bool m_measureWallclockTime;
127};
128
129
130}
131#endif
132