00001
00002
00003 #ifndef DUNE_TIMER_HH
00004 #define DUNE_TIMER_HH
00005
00006 #ifndef TIMER_USE_STD_CLOCK
00007
00008 #include <chrono>
00009 #else
00010
00011 #include <ctime>
00012 #endif
00013
00014
00015 #include <cstring>
00016
00017
00018 #include <cerrno>
00019
00020 #include "exceptions.hh"
00021
00022 namespace Dune {
00023
00033 class TimerError : public SystemError {} ;
00034
00035
00051 class Timer
00052 {
00053 public:
00054
00059 Timer (bool startImmediately=true) throw(TimerError)
00060 {
00061 isRunning_ = startImmediately;
00062 reset();
00063 }
00064
00066 void reset() throw (TimerError)
00067 {
00068 sumElapsed_ = 0.0;
00069 storedLastElapsed_ = 0.0;
00070 rawReset();
00071 }
00072
00073
00075 void start() throw (TimerError)
00076 {
00077 if (not (isRunning_))
00078 {
00079 rawReset();
00080 isRunning_ = true;
00081 }
00082 }
00083
00084
00086 double elapsed () const throw (TimerError)
00087 {
00088
00089 if (isRunning_)
00090 return sumElapsed_ + lastElapsed();
00091
00092 return sumElapsed_;
00093 }
00094
00095
00097 double lastElapsed () const throw (TimerError)
00098 {
00099
00100 if (isRunning_)
00101 return rawElapsed();
00102
00103
00104 return storedLastElapsed_;
00105 }
00106
00107
00109 double stop() throw (TimerError)
00110 {
00111 if (isRunning_)
00112 {
00113
00114 storedLastElapsed_ = lastElapsed();
00115 sumElapsed_ += storedLastElapsed_;
00116 isRunning_ = false;
00117 }
00118 return elapsed();
00119 }
00120
00121
00122 private:
00123
00124 bool isRunning_;
00125 double sumElapsed_;
00126 double storedLastElapsed_;
00127
00128
00129 #ifdef TIMER_USE_STD_CLOCK
00130 void rawReset() throw (TimerError)
00131 {
00132 cstart = std::clock();
00133 }
00134
00135 double rawElapsed () const throw (TimerError)
00136 {
00137 return (std::clock()-cstart) / static_cast<double>(CLOCKS_PER_SEC);
00138 }
00139
00140 std::clock_t cstart;
00141 #else
00142 void rawReset() throw (TimerError)
00143 {
00144 cstart = std::chrono::high_resolution_clock::now();
00145 }
00146
00147 double rawElapsed () const throw (TimerError)
00148 {
00149 std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now();
00150 std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double> >(now - cstart);
00151 return time_span.count();
00152 }
00153
00154 std::chrono::high_resolution_clock::time_point cstart;
00155 #endif
00156 };
00157
00160 }
00161
00162 #endif