Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(749)

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/base/queueing_time_estimator.cc

Issue 2273703002: Force events to be non blocking if main thread is unresponsive. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Dave's comments. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698