| Index: third_party/WebKit/Source/platform/scheduler/base/queueing_time_estimator.cc
|
| diff --git a/third_party/WebKit/Source/platform/scheduler/base/queueing_time_estimator.cc b/third_party/WebKit/Source/platform/scheduler/base/queueing_time_estimator.cc
|
| index a8efe8d5d6b551286fa30c46fa604bd55904976c..620ed1eab17c9b60eb1f3851cc2271de70382e4f 100644
|
| --- a/third_party/WebKit/Source/platform/scheduler/base/queueing_time_estimator.cc
|
| +++ b/third_party/WebKit/Source/platform/scheduler/base/queueing_time_estimator.cc
|
| @@ -4,7 +4,7 @@
|
|
|
| #include "platform/scheduler/base/queueing_time_estimator.h"
|
|
|
| -#include "base/time/default_tick_clock.h"
|
| +#include "base/memory/ptr_util.h"
|
|
|
| #include <algorithm>
|
|
|
| @@ -55,35 +55,97 @@ base::TimeDelta ExpectedQueueingTimeFromTask(base::TimeTicks task_start,
|
| QueueingTimeEstimator::QueueingTimeEstimator(
|
| QueueingTimeEstimator::Client* client,
|
| base::TimeDelta window_duration)
|
| - : client_(client),
|
| - window_duration_(window_duration),
|
| - window_start_time_() {}
|
| + : client_(client) {
|
| + state_.window_duration = window_duration;
|
| +}
|
| +
|
| +QueueingTimeEstimator::QueueingTimeEstimator(const State& state)
|
| + : client_(nullptr), state_(state) {}
|
| +
|
| +void QueueingTimeEstimator::OnTopLevelTaskStarted(
|
| + base::TimeTicks task_start_time) {
|
| + state_.OnTopLevelTaskStarted(task_start_time);
|
| +}
|
|
|
| -void QueueingTimeEstimator::OnToplevelTaskCompleted(
|
| - base::TimeTicks task_start_time,
|
| +void QueueingTimeEstimator::OnTopLevelTaskCompleted(
|
| base::TimeTicks task_end_time) {
|
| - if (window_start_time_.is_null())
|
| - window_start_time_ = task_start_time;
|
| + state_.OnTopLevelTaskCompleted(client_, task_end_time);
|
| +}
|
| +
|
| +void QueueingTimeEstimator::State::OnTopLevelTaskStarted(
|
| + base::TimeTicks task_start_time) {
|
| + current_task_start_time = task_start_time;
|
| +}
|
| +
|
| +void QueueingTimeEstimator::State::OnTopLevelTaskCompleted(
|
| + QueueingTimeEstimator::Client* client,
|
| + base::TimeTicks task_end_time) {
|
| + if (window_start_time.is_null())
|
| + window_start_time = current_task_start_time;
|
|
|
| while (TimePastWindowEnd(task_end_time)) {
|
| - if (!TimePastWindowEnd(task_start_time)) {
|
| + if (!TimePastWindowEnd(current_task_start_time)) {
|
| // Include the current task in this window.
|
| - current_expected_queueing_time_ += ExpectedQueueingTimeFromTask(
|
| - task_start_time, task_end_time, window_start_time_,
|
| - window_start_time_ + window_duration_);
|
| + current_expected_queueing_time += ExpectedQueueingTimeFromTask(
|
| + current_task_start_time, task_end_time, window_start_time,
|
| + window_start_time + window_duration);
|
| }
|
| - client_->OnQueueingTimeForWindowEstimated(current_expected_queueing_time_);
|
| - window_start_time_ += window_duration_;
|
| - current_expected_queueing_time_ = base::TimeDelta();
|
| + client->OnQueueingTimeForWindowEstimated(current_expected_queueing_time);
|
| + window_start_time += window_duration;
|
| + current_expected_queueing_time = base::TimeDelta();
|
| }
|
|
|
| - current_expected_queueing_time_ += ExpectedQueueingTimeFromTask(
|
| - task_start_time, task_end_time, window_start_time_,
|
| - window_start_time_ + window_duration_);
|
| + current_expected_queueing_time += ExpectedQueueingTimeFromTask(
|
| + current_task_start_time, task_end_time, window_start_time,
|
| + window_start_time + window_duration);
|
| +
|
| + current_task_start_time = base::TimeTicks();
|
| }
|
|
|
| -bool QueueingTimeEstimator::TimePastWindowEnd(base::TimeTicks time) {
|
| - return time > window_start_time_ + window_duration_;
|
| +bool QueueingTimeEstimator::State::TimePastWindowEnd(base::TimeTicks time) {
|
| + return time > window_start_time + window_duration;
|
| +}
|
| +
|
| +// Keeps track of the queueing time.
|
| +class RecordQueueingTimeClient : public QueueingTimeEstimator::Client {
|
| + public:
|
| + // QueueingTimeEstimator::Client implementation:
|
| + void OnQueueingTimeForWindowEstimated(
|
| + base::TimeDelta queueing_time) override {
|
| + queueing_time_ = queueing_time;
|
| + }
|
| +
|
| + base::TimeDelta queueing_time() { return queueing_time_; }
|
| +
|
| + RecordQueueingTimeClient() {}
|
| + ~RecordQueueingTimeClient() override {}
|
| +
|
| + private:
|
| + base::TimeDelta queueing_time_;
|
| + DISALLOW_COPY_AND_ASSIGN(RecordQueueingTimeClient);
|
| +};
|
| +
|
| +base::TimeDelta QueueingTimeEstimator::EstimateQueueingTimeIncludingCurrentTask(
|
| + base::TimeTicks now) const {
|
| + RecordQueueingTimeClient record_queueing_time_client;
|
| +
|
| + // Make a copy of this QueueingTimeEstimator. We'll use it to evaluate the
|
| + // estimated input latency, assuming that any active task ends now.
|
| + QueueingTimeEstimator::State temporary_queueing_time_estimator_state(state_);
|
| +
|
| + // If there's a task in progress, pretend it ends now, and include it in the
|
| + // computation. If there's no task in progress, add an empty task to flush any
|
| + // stale windows.
|
| + if (temporary_queueing_time_estimator_state.current_task_start_time.is_null())
|
| + temporary_queueing_time_estimator_state.OnTopLevelTaskStarted(now);
|
| + temporary_queueing_time_estimator_state.OnTopLevelTaskCompleted(
|
| + &record_queueing_time_client, now);
|
| +
|
| + // Report the max of the queueing time for the last full window, or the
|
| + // current partial window.
|
| + return std::max(
|
| + record_queueing_time_client.queueing_time(),
|
| + temporary_queueing_time_estimator_state.current_expected_queueing_time);
|
| }
|
|
|
| } // namespace scheduler
|
|
|