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
5dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#ifndef V8_PLATFORM_ELAPSED_TIMER_H_
6dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#define V8_PLATFORM_ELAPSED_TIMER_H_
7dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/checks.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/platform/time.h"
10dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
11dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgnamespace v8 {
12dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgnamespace internal {
13dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
14dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgclass ElapsedTimer V8_FINAL BASE_EMBEDDED {
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() {
24dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(!IsStarted());
25dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    start_ticks_ = Now();
26dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#ifdef DEBUG
27dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    started_ = true;
28dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#endif
29dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(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() {
35dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(IsStarted());
36dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    start_ticks_ = TimeTicks();
37dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#ifdef DEBUG
38dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    started_ = false;
39dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#endif
40dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(!IsStarted());
41dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  }
42dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
43dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  // Returns |true| if this timer was started previously.
44dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  bool IsStarted() const {
45dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(started_ || start_ticks_.IsNull());
46dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(!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() {
56dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(IsStarted());
57dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    TimeTicks ticks = Now();
58dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    TimeDelta elapsed = ticks - start_ticks_;
59dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(elapsed.InMicroseconds() >= 0);
60dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    start_ticks_ = ticks;
61dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(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 {
68dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(IsStarted());
69dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    TimeDelta elapsed = Now() - start_ticks_;
70dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(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 {
78dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(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();
85dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    ASSERT(!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
95dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org} }  // namespace v8::internal
96dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
97dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#endif  // V8_PLATFORM_ELAPSED_TIMER_H_
98