dune-common  2.3.0
timer.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 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 
50  class Timer
51  {
52  public:
53 
58  Timer (bool startImmediately=true) throw(TimerError)
59  {
60  isRunning_ = startImmediately;
61  reset();
62  }
63 
65  void reset() throw (TimerError)
66  {
67  sumElapsed_ = 0.0;
68  storedLastElapsed_ = 0.0;
69  rawReset();
70  }
71 
72 
74  void start() throw (TimerError)
75  {
76  if (not (isRunning_))
77  {
78  rawReset();
79  isRunning_ = true;
80  }
81  }
82 
83 
85  double elapsed () const throw (TimerError)
86  {
87  // if timer is running add the time elapsed since last start to sum
88  if (isRunning_)
89  return sumElapsed_ + lastElapsed();
90 
91  return sumElapsed_;
92  }
93 
94 
96  double lastElapsed () const throw (TimerError)
97  {
98  // if timer is running return the current value
99  if (isRunning_)
100  return rawElapsed();
101 
102  // if timer is not running return stored value from last run
103  return storedLastElapsed_;
104  }
105 
106 
108  double stop() throw (TimerError)
109  {
110  if (isRunning_)
111  {
112  // update storedLastElapsed_ and sumElapsed_ and stop timer
113  storedLastElapsed_ = lastElapsed();
114  sumElapsed_ += storedLastElapsed_;
115  isRunning_ = false;
116  }
117  return elapsed();
118  }
119 
120 
121  private:
122 
123  bool isRunning_;
124  double sumElapsed_;
125  double storedLastElapsed_;
126 
127 
128 #ifdef TIMER_USE_STD_CLOCK
129  void rawReset() throw (TimerError)
130  {
131  cstart = std::clock();
132  }
133 
134  double rawElapsed () const throw (TimerError)
135  {
136  return (std::clock()-cstart) / static_cast<double>(CLOCKS_PER_SEC);
137  }
138 
139  std::clock_t cstart;
140 #else
141  void rawReset() throw (TimerError)
142  {
143  rusage ru;
144  if (getrusage(RUSAGE_SELF, &ru))
145  DUNE_THROW(TimerError, strerror(errno));
146  cstart = ru.ru_utime;
147  }
148 
149  double rawElapsed () const throw (TimerError)
150  {
151  rusage ru;
152  if (getrusage(RUSAGE_SELF, &ru))
153  DUNE_THROW(TimerError, strerror(errno));
154  return 1.0 * (ru.ru_utime.tv_sec - cstart.tv_sec) + (ru.ru_utime.tv_usec - cstart.tv_usec) / (1000.0 * 1000.0);
155  }
156 
157  struct timeval cstart;
158 #endif
159  }; // end class Timer
160 
163 } // end namespace
164 
165 #endif