Home | History | Annotate | Download | only in platform
      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
     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.
     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.
     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.
     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.
     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.
     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.
     77   bool HasExpired(TimeDelta time_delta) const {
     78     DCHECK(IsStarted());
     79     return Elapsed() >= time_delta;
     80   }
     81 
     82  private:
     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