Chromium Code Reviews| 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 |