OLD | NEW |
| (Empty) |
1 // Copyright 2003-2009 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 // | |
16 // Timing | |
17 | |
18 #ifndef OMAHA_BASE_TIMER_H_ | |
19 #define OMAHA_BASE_TIMER_H_ | |
20 | |
21 #include "omaha/base/time.h" | |
22 | |
23 namespace omaha { | |
24 | |
25 // Low resolution timer which can be used to time loops. The resolution depends | |
26 // on the platform and can be expected to be about 10 ms on Windows 2000 and up. | |
27 class LowResTimer { | |
28 public: | |
29 explicit LowResTimer(bool running); | |
30 ~LowResTimer(); | |
31 | |
32 // LowResTimer keeps track of elapsed time, which can consist of multiple | |
33 // Start()-Stop() intervals. | |
34 void Start(); | |
35 | |
36 // Returns time between Start and Stop call and increments the time elapsed. | |
37 uint32 Stop(); | |
38 void Reset(); | |
39 | |
40 // Return time in seconds, milliseconds. | |
41 double GetSeconds() const; | |
42 uint32 GetMilliseconds() const; | |
43 | |
44 // Gets the number of iteration this timer was started/stopped. | |
45 uint32 GetIterations() const { return iterations_; } | |
46 bool IsRunning() const { return running_; } | |
47 | |
48 private: | |
49 | |
50 bool running_; | |
51 uint32 start_; | |
52 uint32 elapsed_; | |
53 uint32 iterations_; | |
54 | |
55 DISALLOW_EVIL_CONSTRUCTORS(LowResTimer); | |
56 }; | |
57 | |
58 inline double LowResTimer::GetSeconds() const { | |
59 return static_cast<double>(GetMilliseconds()) / 1000; | |
60 } | |
61 | |
62 // WARNING - Timer is implemented on top of RDTSC and | |
63 // QueryPerformanceCounter which have undefined behavior when running | |
64 // on multi-core, speedstep, bugs in HAL, certain chipsets, etc. | |
65 // Do not use the Timer in production code where the execution flow | |
66 // depends on timing. Timer is primarily intended to be used for | |
67 // code profiling and performance measurements. | |
68 class Timer { | |
69 public: | |
70 explicit Timer(bool running); | |
71 ~Timer(); | |
72 | |
73 // Timer keeps track of elapsed time, which can consist of multiple | |
74 // Start()-Stop() intervals. | |
75 void Start(); | |
76 | |
77 // returns time for last split (elapsed time since Start() or time since | |
78 // last Split(), whichever came last) as well as total elapsed time. | |
79 void Split(double* split_time_ms, double* total_time_ms); | |
80 | |
81 // returns time elapsed (in hi-res perf-counts) between Start and Stop call | |
82 // and increments the time elapsed_ | |
83 time64 Stop(); | |
84 void Reset(); | |
85 | |
86 // return time in seconds, milliseconds, etc. | |
87 double GetSeconds() const; | |
88 double GetMilliseconds() const; | |
89 double GetMicroseconds() const; | |
90 double GetNanoseconds() const; | |
91 time64 Get100Nanoseconds() const; | |
92 | |
93 // TODO(omaha): Probably should have been a static method, or even | |
94 // standalone func convert the high-perf counter to nano-seconds | |
95 double PerfCountToNanoSeconds(time64 perf_count) const; | |
96 | |
97 // get the number of iteration this timer was started/stopped | |
98 uint32 GetIterations() const { return iterations_; } | |
99 bool IsRunning() const { return running_; } | |
100 | |
101 // useful funcs beyond just the Timer class | |
102 static time64 GetRdtscCounter(); // return perf-counter value | |
103 static time64 GetRdtscFrequency(); // return perf-counter frequency | |
104 | |
105 // outputs total time, number of iterations, and the average time | |
106 #ifdef _DEBUG | |
107 CString DebugString() const; | |
108 #endif | |
109 | |
110 private: | |
111 | |
112 bool running_; | |
113 time64 start_; | |
114 time64 split_; | |
115 time64 elapsed_; | |
116 uint32 iterations_; | |
117 static time64 count_freq_; | |
118 | |
119 DISALLOW_EVIL_CONSTRUCTORS(Timer); | |
120 }; | |
121 | |
122 // lint -e{533} Function should return a value | |
123 // lint -e{31} Redefinition of symbol | |
124 __forceinline time64 Timer::GetRdtscCounter() { __asm rdtsc } | |
125 | |
126 inline double Timer::PerfCountToNanoSeconds(time64 perf_count) const { | |
127 return (static_cast<double>(perf_count) / static_cast<double>(count_freq_)) * | |
128 static_cast<double>(1000000000.0); | |
129 } | |
130 | |
131 inline double Timer::GetSeconds() const { | |
132 return GetNanoseconds() / 1000000000; | |
133 } | |
134 | |
135 inline double Timer::GetMilliseconds() const { | |
136 return GetNanoseconds() / 1000000; | |
137 } | |
138 | |
139 inline double Timer::GetMicroseconds() const { | |
140 return GetNanoseconds() / 1000; | |
141 } | |
142 | |
143 inline time64 Timer::Get100Nanoseconds() const { | |
144 return (time64) GetNanoseconds() / 100; | |
145 } | |
146 | |
147 // Helper class which starts the timer in its constructor and stops it | |
148 // in its destructor. This prevents accidentally leaving the timer running | |
149 // if a function has an early exit. | |
150 // | |
151 // Usage: | |
152 // | |
153 // class A { | |
154 // Timer timer_; | |
155 // | |
156 // void foo(){ | |
157 // TimerScope (timer_); | |
158 // ...... | |
159 // } // end foo | |
160 // | |
161 // Everything is timed till the end of the function or when it returns | |
162 // from any place. | |
163 | |
164 class TimerScope { | |
165 public: | |
166 explicit TimerScope(Timer *timer) : timer_(timer) { | |
167 if (timer_) { | |
168 timer_->Start(); | |
169 } | |
170 } | |
171 | |
172 ~TimerScope() { | |
173 if (timer_ && timer_->IsRunning()) { | |
174 timer_->Stop(); | |
175 } | |
176 } | |
177 | |
178 private: | |
179 Timer *timer_; | |
180 DISALLOW_EVIL_CONSTRUCTORS(TimerScope); | |
181 }; | |
182 | |
183 } // namespace omaha | |
184 | |
185 #endif // OMAHA_BASE_TIMER_H_ | |
186 | |
OLD | NEW |