OpenImageIO
 All Classes Files Friends Macros Pages
timer.h
Go to the documentation of this file.
1 /*
2  Copyright 2008 Larry Gritz and the other authors and contributors.
3  All Rights Reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8  * Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13  * Neither the name of the software's owners nor the names of its
14  contributors may be used to endorse or promote products derived from
15  this software without specific prior written permission.
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28  (This is the Modified BSD License)
29 */
30 
31 
34 
35 
36 #ifndef OPENIMAGEIO_TIMER_H
37 #define OPENIMAGEIO_TIMER_H
38 
39 #include "version.h"
40 
41 #ifdef _WIN32
42 # include "osdep.h"
43 #elif defined(__APPLE__)
44 # include <mach/mach_time.h>
45 #else
46 #include <sys/time.h>
47 #include <cstdlib> // Just for NULL definition
48 #endif
49 
50 OIIO_NAMESPACE_ENTER
51 {
52 
80 class Timer {
81 public:
82 #ifdef _WIN32
83  typedef LARGE_INTEGER value_t;
84  // Sheesh, why can't they use a standard type like stdint's int64_t?
85 #elif defined(__APPLE__)
86  typedef unsigned long long value_t;
87 #else
88  typedef struct timeval value_t;
89 #endif
90 
93  Timer (bool startnow=true) : m_ticking(false), m_elapsed(0)
94  {
95  if (startnow)
96  start();
97  else {
98  // Initialize m_starttime to avoid warnings
99 #ifdef _WIN32
100  m_starttime.QuadPart = 0;
101 #elif defined(__APPLE__)
102  m_starttime = 0;
103 #else
104  m_starttime.tv_sec = 0;
105  m_starttime.tv_usec = 0;
106 #endif
107  }
108  }
109 
112  ~Timer () { }
113 
116  void start () {
117  if (! m_ticking) {
118  m_starttime = now();
119  m_ticking = true;
120  }
121  }
122 
126  double stop () {
127  if (m_ticking) {
128  value_t n = now();
129  m_elapsed += diff (m_starttime, n);
130  m_ticking = false;
131  }
132  return m_elapsed;
133  }
134 
137  void reset (void) {
138  m_elapsed = 0;
139  m_ticking = false;
140  }
141 
145  double lap () {
146  value_t n = now();
147  double r = m_ticking ? diff (m_starttime, n) : 0.0;
148  m_elapsed += r;
149  m_starttime = n;
150  m_ticking = true;
151  return r;
152  }
153 
156  double operator() (void) const {
157  return m_elapsed + time_since_start();
158  }
159 
162  double time_since_start (void) const {
163  if (m_ticking) {
164  value_t n = now();
165  return diff (m_starttime, n);
166  } else {
167  return 0;
168  }
169  }
170 
171 private:
172  bool m_ticking;
173  value_t m_starttime;
174  double m_elapsed;
175 
178  value_t now (void) const {
179  value_t n;
180 #ifdef _WIN32
181  QueryPerformanceCounter (&n); // From MSDN web site
182 #elif defined(__APPLE__)
183  n = mach_absolute_time();
184 #else
185  gettimeofday (&n, NULL);
186 #endif
187  return n;
188  }
189 
192  static double diff (const value_t &then, const value_t &now) {
193 #ifdef _WIN32
194  // From MSDN web site
195  value_t freq;
196  QueryPerformanceFrequency (&freq);
197  return (double)(now.QuadPart - then.QuadPart) / (double)freq.QuadPart;
198 #elif defined(__APPLE__)
199  // NOTE(boulos): Both this value and that of the windows
200  // counterpart above only need to be calculated once. In
201  // Manta, we stored this on the side as a scaling factor but
202  // that would require a .cpp file (meaning timer.h can't just
203  // be used as a header). It is also claimed that since
204  // Leopard, Apple returns 1 for both numer and denom.
205  mach_timebase_info_data_t time_info;
206  mach_timebase_info(&time_info);
207  double seconds_per_tick = (1e-9*static_cast<double>(time_info.numer))/
208  static_cast<double>(time_info.denom);
209  value_t d = (now>then) ? now-then : then-now;
210  return d * seconds_per_tick;
211 #else
212  return fabs (static_cast<double>(now.tv_sec - then.tv_sec) +
213  static_cast<double>(now.tv_usec - then.tv_usec) / 1e6);
214 #endif
215  }
216 };
217 
218 
219 
222 template <class TIMER=Timer>
223 class ScopedTimer {
224 public:
227  ScopedTimer (TIMER &t) : m_timer(t) { start(); }
228 
231  ~ScopedTimer () { stop(); }
232 
235  void start () { m_timer.start(); }
236 
239  void stop () { m_timer.stop(); }
240 
243  void reset () { m_timer.reset(); }
244 
245 private:
246  TIMER &m_timer;
247 };
248 
249 
250 
255 template<class FUNC>
256 double
257 time_trial (FUNC func, int n=1, double *range=NULL)
258 {
259  double mintime = 1.0e30, maxtime = 0.0;
260  while (n-- > 0) {
261  Timer timer;
262  func ();
263  double t = timer();
264  if (t < mintime)
265  mintime = t;
266  if (t > maxtime)
267  maxtime = t;
268  }
269  if (range)
270  *range = maxtime-mintime;
271  return mintime;
272 }
273 
274 
275 
276 }
277 OIIO_NAMESPACE_EXIT
278 
279 #endif // OPENIMAGEIO_TIMER_H