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