1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_BASE_PLATFORM_ELAPSED_TIMER_H_ 6 #define V8_BASE_PLATFORM_ELAPSED_TIMER_H_ 7 8 #include "src/base/logging.h" 9 #include "src/base/platform/time.h" 10 11 namespace v8 { 12 namespace base { 13 14 class ElapsedTimer final { 15 public: 16 #ifdef DEBUG ElapsedTimer()17 ElapsedTimer() : started_(false) {} 18 #endif 19 20 // Starts this timer. Once started a timer can be checked with 21 // |Elapsed()| or |HasExpired()|, and may be restarted using |Restart()|. 22 // This method must not be called on an already started timer. Start()23 void Start() { 24 DCHECK(!IsStarted()); 25 start_ticks_ = Now(); 26 #ifdef DEBUG 27 started_ = true; 28 #endif 29 DCHECK(IsStarted()); 30 } 31 32 // Stops this timer. Must not be called on a timer that was not 33 // started before. Stop()34 void Stop() { 35 DCHECK(IsStarted()); 36 start_ticks_ = TimeTicks(); 37 #ifdef DEBUG 38 started_ = false; 39 #endif 40 DCHECK(!IsStarted()); 41 } 42 43 // Returns |true| if this timer was started previously. IsStarted()44 bool IsStarted() const { 45 DCHECK(started_ || start_ticks_.IsNull()); 46 DCHECK(!started_ || !start_ticks_.IsNull()); 47 return !start_ticks_.IsNull(); 48 } 49 50 // Restarts the timer and returns the time elapsed since the previous start. 51 // This method is equivalent to obtaining the elapsed time with |Elapsed()| 52 // and then starting the timer again, but does so in one single operation, 53 // avoiding the need to obtain the clock value twice. It may only be called 54 // on a previously started timer. Restart()55 TimeDelta Restart() { 56 DCHECK(IsStarted()); 57 TimeTicks ticks = Now(); 58 TimeDelta elapsed = ticks - start_ticks_; 59 DCHECK(elapsed.InMicroseconds() >= 0); 60 start_ticks_ = ticks; 61 DCHECK(IsStarted()); 62 return elapsed; 63 } 64 65 // Returns the time elapsed since the previous start. This method may only 66 // be called on a previously started timer. Elapsed()67 TimeDelta Elapsed() const { 68 DCHECK(IsStarted()); 69 TimeDelta elapsed = Now() - start_ticks_; 70 DCHECK(elapsed.InMicroseconds() >= 0); 71 return elapsed; 72 } 73 74 // Returns |true| if the specified |time_delta| has elapsed since the 75 // previous start, or |false| if not. This method may only be called on 76 // a previously started timer. HasExpired(TimeDelta time_delta)77 bool HasExpired(TimeDelta time_delta) const { 78 DCHECK(IsStarted()); 79 return Elapsed() >= time_delta; 80 } 81 82 private: Now()83 static V8_INLINE TimeTicks Now() { 84 TimeTicks now = TimeTicks::HighResolutionNow(); 85 DCHECK(!now.IsNull()); 86 return now; 87 } 88 89 TimeTicks start_ticks_; 90 #ifdef DEBUG 91 bool started_; 92 #endif 93 }; 94 95 } // namespace base 96 } // namespace v8 97 98 #endif // V8_BASE_PLATFORM_ELAPSED_TIMER_H_ 99