1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/timer/lap_timer.h"
6*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
7*6777b538SAndroid Build Coastguard Worker
8*6777b538SAndroid Build Coastguard Worker namespace base {
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Worker namespace {
11*6777b538SAndroid Build Coastguard Worker
12*6777b538SAndroid Build Coastguard Worker // Default values.
13*6777b538SAndroid Build Coastguard Worker constexpr TimeDelta kDefaultTimeLimit = Seconds(3);
14*6777b538SAndroid Build Coastguard Worker constexpr int kDefaultWarmupRuns = 5;
15*6777b538SAndroid Build Coastguard Worker constexpr int kDefaultTimeCheckInterval = 10;
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker } // namespace
18*6777b538SAndroid Build Coastguard Worker
LapTimer(int warmup_laps,TimeDelta time_limit,int check_interval,LapTimer::TimerMethod method)19*6777b538SAndroid Build Coastguard Worker LapTimer::LapTimer(int warmup_laps,
20*6777b538SAndroid Build Coastguard Worker TimeDelta time_limit,
21*6777b538SAndroid Build Coastguard Worker int check_interval,
22*6777b538SAndroid Build Coastguard Worker LapTimer::TimerMethod method)
23*6777b538SAndroid Build Coastguard Worker : warmup_laps_(warmup_laps),
24*6777b538SAndroid Build Coastguard Worker time_limit_(time_limit),
25*6777b538SAndroid Build Coastguard Worker check_interval_(check_interval),
26*6777b538SAndroid Build Coastguard Worker method_(method) {
27*6777b538SAndroid Build Coastguard Worker DETACH_FROM_SEQUENCE(sequence_checker_);
28*6777b538SAndroid Build Coastguard Worker DCHECK_GT(check_interval, 0);
29*6777b538SAndroid Build Coastguard Worker Reset();
30*6777b538SAndroid Build Coastguard Worker }
31*6777b538SAndroid Build Coastguard Worker
LapTimer(LapTimer::TimerMethod method)32*6777b538SAndroid Build Coastguard Worker LapTimer::LapTimer(LapTimer::TimerMethod method)
33*6777b538SAndroid Build Coastguard Worker : LapTimer(kDefaultWarmupRuns,
34*6777b538SAndroid Build Coastguard Worker kDefaultTimeLimit,
35*6777b538SAndroid Build Coastguard Worker kDefaultTimeCheckInterval,
36*6777b538SAndroid Build Coastguard Worker method) {}
37*6777b538SAndroid Build Coastguard Worker
Reset()38*6777b538SAndroid Build Coastguard Worker void LapTimer::Reset() {
39*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
40*6777b538SAndroid Build Coastguard Worker if (ThreadTicks::IsSupported() && method_ == TimerMethod::kUseThreadTicks)
41*6777b538SAndroid Build Coastguard Worker ThreadTicks::WaitUntilInitialized();
42*6777b538SAndroid Build Coastguard Worker num_laps_ = 0;
43*6777b538SAndroid Build Coastguard Worker remaining_warmups_ = warmup_laps_;
44*6777b538SAndroid Build Coastguard Worker remaining_no_check_laps_ = check_interval_;
45*6777b538SAndroid Build Coastguard Worker Start();
46*6777b538SAndroid Build Coastguard Worker }
47*6777b538SAndroid Build Coastguard Worker
Start()48*6777b538SAndroid Build Coastguard Worker void LapTimer::Start() {
49*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
50*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(num_laps_, 0);
51*6777b538SAndroid Build Coastguard Worker // last_timed_ variables are initialized here (instead of in the constructor)
52*6777b538SAndroid Build Coastguard Worker // because not all platforms support ThreadTicks.
53*6777b538SAndroid Build Coastguard Worker if (method_ == TimerMethod::kUseThreadTicks) {
54*6777b538SAndroid Build Coastguard Worker start_thread_ticks_ = ThreadTicks::Now();
55*6777b538SAndroid Build Coastguard Worker last_timed_lap_end_thread_ticks_ = ThreadTicks::Now();
56*6777b538SAndroid Build Coastguard Worker } else {
57*6777b538SAndroid Build Coastguard Worker start_time_ticks_ = TimeTicks::Now();
58*6777b538SAndroid Build Coastguard Worker last_timed_lap_end_ticks_ = TimeTicks::Now();
59*6777b538SAndroid Build Coastguard Worker }
60*6777b538SAndroid Build Coastguard Worker }
61*6777b538SAndroid Build Coastguard Worker
IsWarmedUp() const62*6777b538SAndroid Build Coastguard Worker bool LapTimer::IsWarmedUp() const {
63*6777b538SAndroid Build Coastguard Worker return remaining_warmups_ <= 0;
64*6777b538SAndroid Build Coastguard Worker }
65*6777b538SAndroid Build Coastguard Worker
NextLap()66*6777b538SAndroid Build Coastguard Worker void LapTimer::NextLap() {
67*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
68*6777b538SAndroid Build Coastguard Worker DCHECK(!start_thread_ticks_.is_null() || !start_time_ticks_.is_null());
69*6777b538SAndroid Build Coastguard Worker if (!IsWarmedUp()) {
70*6777b538SAndroid Build Coastguard Worker --remaining_warmups_;
71*6777b538SAndroid Build Coastguard Worker if (IsWarmedUp()) {
72*6777b538SAndroid Build Coastguard Worker Start();
73*6777b538SAndroid Build Coastguard Worker }
74*6777b538SAndroid Build Coastguard Worker return;
75*6777b538SAndroid Build Coastguard Worker }
76*6777b538SAndroid Build Coastguard Worker ++num_laps_;
77*6777b538SAndroid Build Coastguard Worker --remaining_no_check_laps_;
78*6777b538SAndroid Build Coastguard Worker if (!remaining_no_check_laps_) {
79*6777b538SAndroid Build Coastguard Worker if (method_ == TimerMethod::kUseTimeTicks) {
80*6777b538SAndroid Build Coastguard Worker last_timed_lap_end_ticks_ = TimeTicks::Now();
81*6777b538SAndroid Build Coastguard Worker } else {
82*6777b538SAndroid Build Coastguard Worker last_timed_lap_end_thread_ticks_ = ThreadTicks::Now();
83*6777b538SAndroid Build Coastguard Worker }
84*6777b538SAndroid Build Coastguard Worker remaining_no_check_laps_ = check_interval_;
85*6777b538SAndroid Build Coastguard Worker }
86*6777b538SAndroid Build Coastguard Worker }
87*6777b538SAndroid Build Coastguard Worker
GetAccumulatedTime() const88*6777b538SAndroid Build Coastguard Worker TimeDelta LapTimer::GetAccumulatedTime() const {
89*6777b538SAndroid Build Coastguard Worker if (method_ == TimerMethod::kUseTimeTicks) {
90*6777b538SAndroid Build Coastguard Worker return last_timed_lap_end_ticks_ - start_time_ticks_;
91*6777b538SAndroid Build Coastguard Worker }
92*6777b538SAndroid Build Coastguard Worker return last_timed_lap_end_thread_ticks_ - start_thread_ticks_;
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker
HasTimeLimitExpired() const95*6777b538SAndroid Build Coastguard Worker bool LapTimer::HasTimeLimitExpired() const {
96*6777b538SAndroid Build Coastguard Worker return GetAccumulatedTime() >= time_limit_;
97*6777b538SAndroid Build Coastguard Worker }
98*6777b538SAndroid Build Coastguard Worker
HasTimedAllLaps() const99*6777b538SAndroid Build Coastguard Worker bool LapTimer::HasTimedAllLaps() const {
100*6777b538SAndroid Build Coastguard Worker return num_laps_ && !(num_laps_ % check_interval_);
101*6777b538SAndroid Build Coastguard Worker }
102*6777b538SAndroid Build Coastguard Worker
TimePerLap() const103*6777b538SAndroid Build Coastguard Worker TimeDelta LapTimer::TimePerLap() const {
104*6777b538SAndroid Build Coastguard Worker DCHECK(HasTimedAllLaps());
105*6777b538SAndroid Build Coastguard Worker DCHECK_GT(num_laps_, 0);
106*6777b538SAndroid Build Coastguard Worker return GetAccumulatedTime() / num_laps_;
107*6777b538SAndroid Build Coastguard Worker }
108*6777b538SAndroid Build Coastguard Worker
LapsPerSecond() const109*6777b538SAndroid Build Coastguard Worker float LapTimer::LapsPerSecond() const {
110*6777b538SAndroid Build Coastguard Worker DCHECK(HasTimedAllLaps());
111*6777b538SAndroid Build Coastguard Worker DCHECK_GT(num_laps_, 0);
112*6777b538SAndroid Build Coastguard Worker return num_laps_ / GetAccumulatedTime().InSecondsF();
113*6777b538SAndroid Build Coastguard Worker }
114*6777b538SAndroid Build Coastguard Worker
NumLaps() const115*6777b538SAndroid Build Coastguard Worker int LapTimer::NumLaps() const {
116*6777b538SAndroid Build Coastguard Worker return num_laps_;
117*6777b538SAndroid Build Coastguard Worker }
118*6777b538SAndroid Build Coastguard Worker } // namespace base
119