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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc

Issue 2540663002: Add the concept of QueueEnabledVoters to blink scheduler TaskQueue (Closed)
Patch Set: Fix test crashes and address feedback. Created 4 years 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/renderer/renderer_scheduler_impl.h" 5 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/stack_trace.h" 8 #include "base/debug/stack_trace.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 this, 88 this,
89 "renderer.scheduler", 89 "renderer.scheduler",
90 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 90 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
91 "RendererSchedulerIdlePeriod", 91 "RendererSchedulerIdlePeriod",
92 base::TimeDelta()), 92 base::TimeDelta()),
93 render_widget_scheduler_signals_(this), 93 render_widget_scheduler_signals_(this),
94 control_task_runner_(helper_.ControlTaskRunner()), 94 control_task_runner_(helper_.ControlTaskRunner()),
95 compositor_task_runner_( 95 compositor_task_runner_(
96 helper_.NewTaskQueue(TaskQueue::Spec(TaskQueue::QueueType::COMPOSITOR) 96 helper_.NewTaskQueue(TaskQueue::Spec(TaskQueue::QueueType::COMPOSITOR)
97 .SetShouldMonitorQuiescence(true))), 97 .SetShouldMonitorQuiescence(true))),
98 compositor_task_runner_enabled_voter_(
99 compositor_task_runner_->CreateQueueEnabledVoter()),
98 delayed_update_policy_runner_( 100 delayed_update_policy_runner_(
99 base::Bind(&RendererSchedulerImpl::UpdatePolicy, 101 base::Bind(&RendererSchedulerImpl::UpdatePolicy,
100 base::Unretained(this)), 102 base::Unretained(this)),
101 helper_.ControlTaskRunner()), 103 helper_.ControlTaskRunner()),
102 main_thread_only_(this, 104 main_thread_only_(this,
103 compositor_task_runner_, 105 compositor_task_runner_,
104 helper_.scheduler_tqm_delegate().get(), 106 helper_.scheduler_tqm_delegate().get(),
105 helper_.scheduler_tqm_delegate()->NowTicks()), 107 helper_.scheduler_tqm_delegate()->NowTicks()),
106 policy_may_need_update_(&any_thread_lock_), 108 policy_may_need_update_(&any_thread_lock_),
107 weak_factory_(this) { 109 weak_factory_(this) {
(...skipping 26 matching lines...) Expand all
134 base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver( 136 base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver(
135 weak_factory_.GetWeakPtr()); 137 weak_factory_.GetWeakPtr());
136 } 138 }
137 } 139 }
138 140
139 RendererSchedulerImpl::~RendererSchedulerImpl() { 141 RendererSchedulerImpl::~RendererSchedulerImpl() {
140 TRACE_EVENT_OBJECT_DELETED_WITH_ID( 142 TRACE_EVENT_OBJECT_DELETED_WITH_ID(
141 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 143 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
142 this); 144 this);
143 145
144 for (const scoped_refptr<TaskQueue>& loading_queue : loading_task_runners_) { 146 for (auto& pair : loading_task_runners_) {
145 loading_queue->RemoveTaskObserver( 147 pair.first->RemoveTaskObserver(
146 &MainThreadOnly().loading_task_cost_estimator); 148 &MainThreadOnly().loading_task_cost_estimator);
147 } 149 }
148 for (const scoped_refptr<TaskQueue>& timer_queue : timer_task_runners_) { 150 for (auto& pair : timer_task_runners_) {
149 timer_queue->RemoveTaskObserver( 151 pair.first->RemoveTaskObserver(&MainThreadOnly().timer_task_cost_estimator);
150 &MainThreadOnly().timer_task_cost_estimator);
151 } 152 }
152 153
153 if (virtual_time_domain_) 154 if (virtual_time_domain_)
154 UnregisterTimeDomain(virtual_time_domain_.get()); 155 UnregisterTimeDomain(virtual_time_domain_.get());
155 156
156 helper_.RemoveTaskTimeObserver(this); 157 helper_.RemoveTaskTimeObserver(this);
157 158
158 base::trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver( 159 base::trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver(
159 this); 160 this);
160 161
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 279
279 scoped_refptr<TaskQueue> RendererSchedulerImpl::NewLoadingTaskRunner( 280 scoped_refptr<TaskQueue> RendererSchedulerImpl::NewLoadingTaskRunner(
280 TaskQueue::QueueType queue_type) { 281 TaskQueue::QueueType queue_type) {
281 helper_.CheckOnValidThread(); 282 helper_.CheckOnValidThread();
282 scoped_refptr<TaskQueue> loading_task_queue( 283 scoped_refptr<TaskQueue> loading_task_queue(
283 helper_.NewTaskQueue(TaskQueue::Spec(queue_type) 284 helper_.NewTaskQueue(TaskQueue::Spec(queue_type)
284 .SetShouldMonitorQuiescence(true) 285 .SetShouldMonitorQuiescence(true)
285 .SetTimeDomain(MainThreadOnly().use_virtual_time 286 .SetTimeDomain(MainThreadOnly().use_virtual_time
286 ? GetVirtualTimeDomain() 287 ? GetVirtualTimeDomain()
287 : nullptr))); 288 : nullptr)));
288 loading_task_runners_.insert(loading_task_queue); 289 auto insert_result = loading_task_runners_.insert(std::make_pair(
289 loading_task_queue->SetQueueEnabled( 290 loading_task_queue, loading_task_queue->CreateQueueEnabledVoter()));
291 insert_result.first->second->SetQueueEnabled(
290 MainThreadOnly().current_policy.loading_queue_policy.is_enabled); 292 MainThreadOnly().current_policy.loading_queue_policy.is_enabled);
291 loading_task_queue->SetQueuePriority( 293 loading_task_queue->SetQueuePriority(
292 MainThreadOnly().current_policy.loading_queue_policy.priority); 294 MainThreadOnly().current_policy.loading_queue_policy.priority);
293 if (MainThreadOnly().current_policy.loading_queue_policy.time_domain_type == 295 if (MainThreadOnly().current_policy.loading_queue_policy.time_domain_type ==
294 TimeDomainType::THROTTLED) { 296 TimeDomainType::THROTTLED) {
295 task_queue_throttler_->IncreaseThrottleRefCount(loading_task_queue.get()); 297 task_queue_throttler_->IncreaseThrottleRefCount(loading_task_queue.get());
296 } 298 }
297 loading_task_queue->AddTaskObserver( 299 loading_task_queue->AddTaskObserver(
298 &MainThreadOnly().loading_task_cost_estimator); 300 &MainThreadOnly().loading_task_cost_estimator);
299 return loading_task_queue; 301 return loading_task_queue;
300 } 302 }
301 303
302 scoped_refptr<TaskQueue> RendererSchedulerImpl::NewTimerTaskRunner( 304 scoped_refptr<TaskQueue> RendererSchedulerImpl::NewTimerTaskRunner(
303 TaskQueue::QueueType queue_type) { 305 TaskQueue::QueueType queue_type) {
304 helper_.CheckOnValidThread(); 306 helper_.CheckOnValidThread();
305 // TODO(alexclarke): Consider using ApplyTaskQueuePolicy() for brevity. 307 // TODO(alexclarke): Consider using ApplyTaskQueuePolicy() for brevity.
306 scoped_refptr<TaskQueue> timer_task_queue( 308 scoped_refptr<TaskQueue> timer_task_queue(
307 helper_.NewTaskQueue(TaskQueue::Spec(queue_type) 309 helper_.NewTaskQueue(TaskQueue::Spec(queue_type)
308 .SetShouldMonitorQuiescence(true) 310 .SetShouldMonitorQuiescence(true)
309 .SetShouldReportWhenExecutionBlocked(true) 311 .SetShouldReportWhenExecutionBlocked(true)
310 .SetTimeDomain(MainThreadOnly().use_virtual_time 312 .SetTimeDomain(MainThreadOnly().use_virtual_time
311 ? GetVirtualTimeDomain() 313 ? GetVirtualTimeDomain()
312 : nullptr))); 314 : nullptr)));
313 timer_task_runners_.insert(timer_task_queue); 315 auto insert_result = timer_task_runners_.insert(std::make_pair(
314 timer_task_queue->SetQueueEnabled( 316 timer_task_queue, timer_task_queue->CreateQueueEnabledVoter()));
317 insert_result.first->second->SetQueueEnabled(
315 MainThreadOnly().current_policy.timer_queue_policy.is_enabled); 318 MainThreadOnly().current_policy.timer_queue_policy.is_enabled);
316 timer_task_queue->SetQueuePriority( 319 timer_task_queue->SetQueuePriority(
317 MainThreadOnly().current_policy.timer_queue_policy.priority); 320 MainThreadOnly().current_policy.timer_queue_policy.priority);
318 if (MainThreadOnly().current_policy.timer_queue_policy.time_domain_type == 321 if (MainThreadOnly().current_policy.timer_queue_policy.time_domain_type ==
319 TimeDomainType::THROTTLED) { 322 TimeDomainType::THROTTLED) {
320 task_queue_throttler_->IncreaseThrottleRefCount(timer_task_queue.get()); 323 task_queue_throttler_->IncreaseThrottleRefCount(timer_task_queue.get());
321 } 324 }
322 timer_task_queue->AddTaskObserver( 325 timer_task_queue->AddTaskObserver(
323 &MainThreadOnly().timer_task_cost_estimator); 326 &MainThreadOnly().timer_task_cost_estimator);
324 return timer_task_queue; 327 return timer_task_queue;
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 "RendererScheduler.timer_tasks_seem_expensive", 1089 "RendererScheduler.timer_tasks_seem_expensive",
1087 MainThreadOnly().timer_tasks_seem_expensive); 1090 MainThreadOnly().timer_tasks_seem_expensive);
1088 1091
1089 // TODO(alexclarke): Can we get rid of force update now? 1092 // TODO(alexclarke): Can we get rid of force update now?
1090 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED && 1093 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED &&
1091 new_policy == MainThreadOnly().current_policy) { 1094 new_policy == MainThreadOnly().current_policy) {
1092 return; 1095 return;
1093 } 1096 }
1094 1097
1095 ApplyTaskQueuePolicy(compositor_task_runner_.get(), 1098 ApplyTaskQueuePolicy(compositor_task_runner_.get(),
1099 compositor_task_runner_enabled_voter_.get(),
1096 MainThreadOnly().current_policy.compositor_queue_policy, 1100 MainThreadOnly().current_policy.compositor_queue_policy,
1097 new_policy.compositor_queue_policy); 1101 new_policy.compositor_queue_policy);
1098 1102
1099 for (const scoped_refptr<TaskQueue>& loading_queue : loading_task_runners_) { 1103 for (const auto& pair : loading_task_runners_) {
1100 ApplyTaskQueuePolicy(loading_queue.get(), 1104 ApplyTaskQueuePolicy(pair.first.get(), pair.second.get(),
1101 MainThreadOnly().current_policy.loading_queue_policy, 1105 MainThreadOnly().current_policy.loading_queue_policy,
1102 new_policy.loading_queue_policy); 1106 new_policy.loading_queue_policy);
1103 } 1107 }
1104 1108
1105 for (const scoped_refptr<TaskQueue>& timer_queue : timer_task_runners_) { 1109 for (const auto& pair : timer_task_runners_) {
1106 ApplyTaskQueuePolicy(timer_queue.get(), 1110 ApplyTaskQueuePolicy(pair.first.get(), pair.second.get(),
1107 MainThreadOnly().current_policy.timer_queue_policy, 1111 MainThreadOnly().current_policy.timer_queue_policy,
1108 new_policy.timer_queue_policy); 1112 new_policy.timer_queue_policy);
1109 } 1113 }
1110 MainThreadOnly().have_reported_blocking_intervention_in_current_policy = 1114 MainThreadOnly().have_reported_blocking_intervention_in_current_policy =
1111 false; 1115 false;
1112 1116
1113 // TODO(alexclarke): We shouldn't have to prioritize the default queue, but it 1117 // TODO(alexclarke): We shouldn't have to prioritize the default queue, but it
1114 // appears to be necessary since the order of loading tasks and IPCs (which 1118 // appears to be necessary since the order of loading tasks and IPCs (which
1115 // are mostly dispatched on the default queue) need to be preserved. 1119 // are mostly dispatched on the default queue) need to be preserved.
1116 ApplyTaskQueuePolicy(helper_.DefaultTaskRunner().get(), 1120 ApplyTaskQueuePolicy(helper_.DefaultTaskRunner().get(), nullptr,
1117 MainThreadOnly().current_policy.default_queue_policy, 1121 MainThreadOnly().current_policy.default_queue_policy,
1118 new_policy.default_queue_policy); 1122 new_policy.default_queue_policy);
1119 if (MainThreadOnly().rail_mode_observer && 1123 if (MainThreadOnly().rail_mode_observer &&
1120 new_policy.rail_mode != MainThreadOnly().current_policy.rail_mode) { 1124 new_policy.rail_mode != MainThreadOnly().current_policy.rail_mode) {
1121 MainThreadOnly().rail_mode_observer->OnRAILModeChanged( 1125 MainThreadOnly().rail_mode_observer->OnRAILModeChanged(
1122 new_policy.rail_mode); 1126 new_policy.rail_mode);
1123 } 1127 }
1124 1128
1125 if (new_policy.should_disable_throttling != 1129 if (new_policy.should_disable_throttling !=
1126 MainThreadOnly().current_policy.should_disable_throttling) { 1130 MainThreadOnly().current_policy.should_disable_throttling) {
1127 if (new_policy.should_disable_throttling) { 1131 if (new_policy.should_disable_throttling) {
1128 task_queue_throttler()->DisableThrottling(); 1132 task_queue_throttler()->DisableThrottling();
1129 } else { 1133 } else {
1130 task_queue_throttler()->EnableThrottling(); 1134 task_queue_throttler()->EnableThrottling();
1131 } 1135 }
1132 } 1136 }
1133 1137
1134 DCHECK(compositor_task_runner_->IsQueueEnabled()); 1138 DCHECK(compositor_task_runner_->IsQueueEnabled());
1135 MainThreadOnly().current_policy = new_policy; 1139 MainThreadOnly().current_policy = new_policy;
1136 } 1140 }
1137 1141
1138 void RendererSchedulerImpl::ApplyTaskQueuePolicy( 1142 void RendererSchedulerImpl::ApplyTaskQueuePolicy(
1139 TaskQueue* task_queue, 1143 TaskQueue* task_queue,
1144 TaskQueue::QueueEnabledVoter* task_queue_enabled_voter,
1140 const TaskQueuePolicy& old_task_queue_policy, 1145 const TaskQueuePolicy& old_task_queue_policy,
1141 const TaskQueuePolicy& new_task_queue_policy) const { 1146 const TaskQueuePolicy& new_task_queue_policy) const {
1142 if (old_task_queue_policy.is_enabled != new_task_queue_policy.is_enabled) { 1147 if (task_queue_enabled_voter &&
1143 task_queue->SetQueueEnabled(new_task_queue_policy.is_enabled); 1148 old_task_queue_policy.is_enabled != new_task_queue_policy.is_enabled) {
1149 task_queue_enabled_voter->SetQueueEnabled(new_task_queue_policy.is_enabled);
1144 } 1150 }
1145 1151
1152 // Make sure if there's no voter that the task queue is enabled.
1153 DCHECK(task_queue_enabled_voter || old_task_queue_policy.is_enabled);
1154
1146 if (old_task_queue_policy.priority != new_task_queue_policy.priority) 1155 if (old_task_queue_policy.priority != new_task_queue_policy.priority)
1147 task_queue->SetQueuePriority(new_task_queue_policy.priority); 1156 task_queue->SetQueuePriority(new_task_queue_policy.priority);
1148 1157
1149 if (old_task_queue_policy.time_domain_type != 1158 if (old_task_queue_policy.time_domain_type !=
1150 new_task_queue_policy.time_domain_type) { 1159 new_task_queue_policy.time_domain_type) {
1151 if (old_task_queue_policy.time_domain_type == TimeDomainType::THROTTLED) { 1160 if (old_task_queue_policy.time_domain_type == TimeDomainType::THROTTLED) {
1152 task_queue_throttler_->DecreaseThrottleRefCount(task_queue); 1161 task_queue_throttler_->DecreaseThrottleRefCount(task_queue);
1153 } else if (new_task_queue_policy.time_domain_type == 1162 } else if (new_task_queue_policy.time_domain_type ==
1154 TimeDomainType::THROTTLED) { 1163 TimeDomainType::THROTTLED) {
1155 task_queue_throttler_->IncreaseThrottleRefCount(task_queue); 1164 task_queue_throttler_->IncreaseThrottleRefCount(task_queue);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 IdleTimeEstimator* RendererSchedulerImpl::GetIdleTimeEstimatorForTesting() { 1276 IdleTimeEstimator* RendererSchedulerImpl::GetIdleTimeEstimatorForTesting() {
1268 return &MainThreadOnly().idle_time_estimator; 1277 return &MainThreadOnly().idle_time_estimator;
1269 } 1278 }
1270 1279
1271 void RendererSchedulerImpl::SuspendTimerQueue() { 1280 void RendererSchedulerImpl::SuspendTimerQueue() {
1272 MainThreadOnly().timer_queue_suspend_count++; 1281 MainThreadOnly().timer_queue_suspend_count++;
1273 ForceUpdatePolicy(); 1282 ForceUpdatePolicy();
1274 #ifndef NDEBUG 1283 #ifndef NDEBUG
1275 DCHECK(!default_timer_task_runner_->IsQueueEnabled()); 1284 DCHECK(!default_timer_task_runner_->IsQueueEnabled());
1276 for (const auto& runner : timer_task_runners_) { 1285 for (const auto& runner : timer_task_runners_) {
1277 DCHECK(!runner->IsQueueEnabled()); 1286 DCHECK(!runner.first->IsQueueEnabled());
1278 } 1287 }
1279 #endif 1288 #endif
1280 } 1289 }
1281 1290
1282 void RendererSchedulerImpl::ResumeTimerQueue() { 1291 void RendererSchedulerImpl::ResumeTimerQueue() {
1283 MainThreadOnly().timer_queue_suspend_count--; 1292 MainThreadOnly().timer_queue_suspend_count--;
1284 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); 1293 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0);
1285 ForceUpdatePolicy(); 1294 ForceUpdatePolicy();
1286 } 1295 }
1287 1296
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
1785 case TimeDomainType::VIRTUAL: 1794 case TimeDomainType::VIRTUAL:
1786 return "virtual"; 1795 return "virtual";
1787 default: 1796 default:
1788 NOTREACHED(); 1797 NOTREACHED();
1789 return nullptr; 1798 return nullptr;
1790 } 1799 }
1791 } 1800 }
1792 1801
1793 } // namespace scheduler 1802 } // namespace scheduler
1794 } // namespace blink 1803 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698