dune-common  2.2.1
timer.hh
Go to the documentation of this file.
1 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set ts=8 sw=2 et sts=2:
3 #ifndef DUNE_TIMER_HH
4 #define DUNE_TIMER_HH
5 
6 #ifndef TIMER_USE_STD_CLOCK
7 // headers for getrusage(2)
8 #include <sys/resource.h>
9 #endif
10 
11 #include <ctime>
12 
13 // headers for stderror(3)
14 #include <cstring>
15 
16 // access to errno in C++
17 #include <cerrno>
18 
19 #include "exceptions.hh"
20 
21 namespace Dune {
22 
32  class TimerError : public SystemError {} ;
33 
34 
45  class Timer
46  {
47  public:
48 
53  Timer (bool startImmediately=true) throw(TimerError)
54  {
55  isRunning_ = startImmediately;
56  reset();
57  }
58 
60  void reset() throw (TimerError)
61  {
62  sumElapsed_ = 0.0;
63  storedLastElapsed_ = 0.0;
64  rawReset();
65  }
66 
67 
69  void start() throw (TimerError)
70  {
71  if (not(isRunning_))
72  {
73  rawReset();
74  isRunning_ = true;
75  }
76  }
77 
78 
80  double elapsed () const throw (TimerError)
81  {
82  // if timer is running add the time elapsed since last start to sum
83  if (isRunning_)
84  return sumElapsed_ + lastElapsed();
85 
86  return sumElapsed_;
87  }
88 
89 
91  double lastElapsed () const throw (TimerError)
92  {
93  // if timer is running return the current value
94  if (isRunning_)
95  return rawElapsed();
96 
97  // if timer is not running return stored value from last run
98  return storedLastElapsed_;
99  }
100 
101 
103  double stop() throw (TimerError)
104  {
105  if (isRunning_)
106  {
107  // update storedLastElapsed_ and sumElapsed_ and stop timer
108  storedLastElapsed_ = lastElapsed();
109  sumElapsed_ += storedLastElapsed_;
110  isRunning_ = false;
111  }
112  return elapsed();
113  }
114 
115 
116  private:
117 
118  bool isRunning_;
119  double sumElapsed_;
120  double storedLastElapsed_;
121 
122 
123 #ifdef TIMER_USE_STD_CLOCK
124  void rawReset() throw (TimerError)
125  {
126  cstart = std::clock();
127  }
128 
129  double rawElapsed () const throw (TimerError)
130  {
131  return (std::clock()-cstart) / static_cast<double>(CLOCKS_PER_SEC);
132  }
133 
134  std::clock_t cstart;
135 #else
136  void rawReset() throw (TimerError)
137  {
138  rusage ru;
139  if (getrusage(RUSAGE_SELF, &ru))
140  DUNE_THROW(TimerError, strerror(errno));
141  cstart = ru.ru_utime;
142  }
143 
144  double rawElapsed () const throw (TimerError)
145  {
146  rusage ru;
147  if (getrusage(RUSAGE_SELF, &ru))
148  DUNE_THROW(TimerError, strerror(errno));
149  return 1.0 * (ru.ru_utime.tv_sec - cstart.tv_sec) + (ru.ru_utime.tv_usec - cstart.tv_usec) / (1000.0 * 1000.0);
150  }
151 
152  struct timeval cstart;
153 #endif
154  }; // end class Timer
155 
158 } // end namespace
159 
160 #endif