OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "platform/scheduler/base/queueing_time_estimator.h" | 5 #include "platform/scheduler/base/queueing_time_estimator.h" |
6 | 6 |
7 #include "base/time/default_tick_clock.h" | 7 #include "base/memory/ptr_util.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 namespace blink { | 11 namespace blink { |
12 namespace scheduler { | 12 namespace scheduler { |
13 | 13 |
14 namespace { | 14 namespace { |
15 | 15 |
16 // This method computes the expected queueing time of a randomly distributed | 16 // This method computes the expected queueing time of a randomly distributed |
17 // task R within a window containing a single task T. Let T' be the time range | 17 // task R within a window containing a single task T. Let T' be the time range |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
52 | 52 |
53 } // namespace | 53 } // namespace |
54 | 54 |
55 QueueingTimeEstimator::QueueingTimeEstimator( | 55 QueueingTimeEstimator::QueueingTimeEstimator( |
56 QueueingTimeEstimator::Client* client, | 56 QueueingTimeEstimator::Client* client, |
57 base::TimeDelta window_duration) | 57 base::TimeDelta window_duration) |
58 : client_(client), | 58 : client_(client), |
59 window_duration_(window_duration), | 59 window_duration_(window_duration), |
60 window_start_time_() {} | 60 window_start_time_() {} |
61 | 61 |
62 void QueueingTimeEstimator::OnToplevelTaskCompleted( | 62 void QueueingTimeEstimator::OnTopLevelTaskStarted(base::TimeTicks task_start_tim e) { |
63 current_task_start_time_ = task_start_time; | |
64 } | |
65 | |
66 void QueueingTimeEstimator::OnTopLevelTaskCompleted( | |
63 base::TimeTicks task_start_time, | 67 base::TimeTicks task_start_time, |
64 base::TimeTicks task_end_time) { | 68 base::TimeTicks task_end_time) { |
69 current_task_start_time_ = base::TimeTicks(); | |
65 if (window_start_time_.is_null()) | 70 if (window_start_time_.is_null()) |
66 window_start_time_ = task_start_time; | 71 window_start_time_ = task_start_time; |
67 | 72 |
68 while (TimePastWindowEnd(task_end_time)) { | 73 while (TimePastWindowEnd(task_end_time)) { |
69 if (!TimePastWindowEnd(task_start_time)) { | 74 if (!TimePastWindowEnd(task_start_time)) { |
70 // Include the current task in this window. | 75 // Include the current task in this window. |
71 current_expected_queueing_time_ += ExpectedQueueingTimeFromTask( | 76 current_expected_queueing_time_ += ExpectedQueueingTimeFromTask( |
72 task_start_time, task_end_time, window_start_time_, | 77 task_start_time, task_end_time, window_start_time_, |
73 window_start_time_ + window_duration_); | 78 window_start_time_ + window_duration_); |
74 } | 79 } |
75 client_->OnQueueingTimeForWindowEstimated(current_expected_queueing_time_); | 80 client_->OnQueueingTimeForWindowEstimated(current_expected_queueing_time_); |
76 window_start_time_ += window_duration_; | 81 window_start_time_ += window_duration_; |
77 current_expected_queueing_time_ = base::TimeDelta(); | 82 current_expected_queueing_time_ = base::TimeDelta(); |
78 } | 83 } |
79 | 84 |
80 current_expected_queueing_time_ += ExpectedQueueingTimeFromTask( | 85 current_expected_queueing_time_ += ExpectedQueueingTimeFromTask( |
81 task_start_time, task_end_time, window_start_time_, | 86 task_start_time, task_end_time, window_start_time_, |
82 window_start_time_ + window_duration_); | 87 window_start_time_ + window_duration_); |
83 } | 88 } |
84 | 89 |
90 // Keeps track of the maximum queueing time. | |
91 class RecordMaxQueueingTimeClient : public QueueingTimeEstimator::Client { | |
92 public: | |
93 void OnQueueingTimeForWindowEstimated( | |
94 base::TimeDelta queueing_time) override { | |
95 worst_queueing_time_ = std::max(worst_queueing_time_, queueing_time); | |
96 } | |
97 | |
98 base::TimeDelta worst_queueing_time() { | |
Sami
2016/08/24 14:56:01
naming nit: "worst_queueing_time" is subjective bu
tdresser
2016/08/24 17:22:50
Done.
| |
99 return worst_queueing_time_; | |
100 } | |
101 | |
102 RecordMaxQueueingTimeClient() {} | |
103 ~RecordMaxQueueingTimeClient() override {} | |
104 | |
105 private: | |
106 base::TimeDelta worst_queueing_time_; | |
107 DISALLOW_COPY_AND_ASSIGN(RecordMaxQueueingTimeClient); | |
108 }; | |
109 | |
110 base::TimeDelta QueueingTimeEstimator::EstimateQueueingTimeIncludingCurrentTask( | |
111 base::TimeTicks now) const { | |
112 RecordMaxQueueingTimeClient record_max_queueing_time_client; | |
113 | |
114 // Make a copy of this QueueingTimeEstimator. We'll use it to evaluate the | |
115 // estimated input latency, assuming that any active task ends now. | |
116 std::unique_ptr<QueueingTimeEstimator> temporary_queueing_time_estimator = | |
117 CloneWithClient(&record_max_queueing_time_client); | |
118 | |
119 // Use a task of length zero to ensure we consider the most recent window | |
120 // (aligned to window intervals). | |
121 base::TimeTicks start_time = now; | |
122 base::TimeTicks end_time = now; | |
123 | |
124 // If there's a task in progress, pretend it ends now, and include it in the | |
125 // computation. | |
126 if (!current_task_start_time_.is_null()) | |
127 start_time = current_task_start_time_; | |
128 | |
129 temporary_queueing_time_estimator->OnTopLevelTaskCompleted(start_time, | |
130 end_time); | |
131 | |
132 // Report the worst queueing time, out of all windows spanned and the current | |
133 // window. | |
134 return std::max( | |
135 record_max_queueing_time_client.worst_queueing_time(), | |
136 temporary_queueing_time_estimator->current_expected_queueing_time_); | |
137 } | |
138 | |
139 std::unique_ptr<QueueingTimeEstimator> QueueingTimeEstimator::CloneWithClient( | |
140 Client* client) const { | |
141 auto queueing_time_estimator = | |
142 base::MakeUnique<QueueingTimeEstimator>(client, window_duration_); | |
143 queueing_time_estimator->current_expected_queueing_time_ = | |
144 current_expected_queueing_time_; | |
145 queueing_time_estimator->window_start_time_ = window_start_time_; | |
146 queueing_time_estimator->current_task_start_time_ = current_task_start_time_; | |
147 return queueing_time_estimator; | |
148 } | |
149 | |
85 bool QueueingTimeEstimator::TimePastWindowEnd(base::TimeTicks time) { | 150 bool QueueingTimeEstimator::TimePastWindowEnd(base::TimeTicks time) { |
86 return time > window_start_time_ + window_duration_; | 151 return time > window_start_time_ + window_duration_; |
87 } | 152 } |
88 | 153 |
89 } // namespace scheduler | 154 } // namespace scheduler |
90 } // namespace blink | 155 } // namespace blink |
OLD | NEW |