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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.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 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 18 matching lines...) Expand all
29 // the cost of loading tasks. 29 // the cost of loading tasks.
30 const int kLoadingTaskEstimationSampleCount = 1000; 30 const int kLoadingTaskEstimationSampleCount = 1000;
31 const double kLoadingTaskEstimationPercentile = 99; 31 const double kLoadingTaskEstimationPercentile = 99;
32 const int kTimerTaskEstimationSampleCount = 1000; 32 const int kTimerTaskEstimationSampleCount = 1000;
33 const double kTimerTaskEstimationPercentile = 99; 33 const double kTimerTaskEstimationPercentile = 99;
34 const int kShortIdlePeriodDurationSampleCount = 10; 34 const int kShortIdlePeriodDurationSampleCount = 10;
35 const double kShortIdlePeriodDurationPercentile = 50; 35 const double kShortIdlePeriodDurationPercentile = 50;
36 // Amount of idle time left in a frame (as a ratio of the vsync interval) above 36 // Amount of idle time left in a frame (as a ratio of the vsync interval) above
37 // which main thread compositing can be considered fast. 37 // which main thread compositing can be considered fast.
38 const double kFastCompositingIdleTimeThreshold = .2; 38 const double kFastCompositingIdleTimeThreshold = .2;
39 // Maximum task queueing time before the main thread is considered unresponsive.
40 const base::TimeDelta kMainThreadUnresponsiveQueueingTime =
41 base::TimeDelta::FromMilliseconds(1000);
39 } // namespace 42 } // namespace
40 43
41 RendererSchedulerImpl::RendererSchedulerImpl( 44 RendererSchedulerImpl::RendererSchedulerImpl(
42 scoped_refptr<SchedulerTqmDelegate> main_task_runner) 45 scoped_refptr<SchedulerTqmDelegate> main_task_runner)
43 : helper_(main_task_runner, 46 : helper_(main_task_runner,
44 "renderer.scheduler", 47 "renderer.scheduler",
45 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 48 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
46 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), 49 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")),
47 idle_helper_(&helper_, 50 idle_helper_(&helper_,
48 this, 51 this,
49 "renderer.scheduler", 52 "renderer.scheduler",
50 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 53 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
51 "RendererSchedulerIdlePeriod", 54 "RendererSchedulerIdlePeriod",
52 base::TimeDelta()), 55 base::TimeDelta()),
53 render_widget_scheduler_signals_(this), 56 render_widget_scheduler_signals_(this),
54 control_task_runner_(helper_.ControlTaskRunner()), 57 control_task_runner_(helper_.ControlTaskRunner()),
55 compositor_task_runner_(helper_.NewTaskQueue( 58 compositor_task_runner_(helper_.NewTaskQueue(
56 TaskQueue::Spec("compositor_tq").SetShouldMonitorQuiescence(true))), 59 TaskQueue::Spec("compositor_tq").SetShouldMonitorQuiescence(true))),
57 delayed_update_policy_runner_( 60 delayed_update_policy_runner_(
58 base::Bind(&RendererSchedulerImpl::UpdatePolicy, 61 base::Bind(&RendererSchedulerImpl::UpdatePolicy,
59 base::Unretained(this)), 62 base::Unretained(this)),
60 helper_.ControlTaskRunner()), 63 helper_.ControlTaskRunner()),
61 main_thread_only_(this, 64 main_thread_only_(compositor_task_runner_,
62 compositor_task_runner_,
63 helper_.scheduler_tqm_delegate().get()), 65 helper_.scheduler_tqm_delegate().get()),
66 any_thread_(this),
64 policy_may_need_update_(&any_thread_lock_), 67 policy_may_need_update_(&any_thread_lock_),
65 weak_factory_(this) { 68 weak_factory_(this) {
66 throttling_helper_.reset(new ThrottlingHelper(this, "renderer.scheduler")); 69 throttling_helper_.reset(new ThrottlingHelper(this, "renderer.scheduler"));
67 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, 70 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
68 weak_factory_.GetWeakPtr()); 71 weak_factory_.GetWeakPtr());
69 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( 72 end_renderer_hidden_idle_period_closure_.Reset(base::Bind(
70 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); 73 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr()));
71 74
72 suspend_timers_when_backgrounded_closure_.Reset( 75 suspend_timers_when_backgrounded_closure_.Reset(
73 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, 76 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded,
(...skipping 27 matching lines...) Expand all
101 if (virtual_time_domain_) 104 if (virtual_time_domain_)
102 UnregisterTimeDomain(virtual_time_domain_.get()); 105 UnregisterTimeDomain(virtual_time_domain_.get());
103 106
104 // Ensure the renderer scheduler was shut down explicitly, because otherwise 107 // Ensure the renderer scheduler was shut down explicitly, because otherwise
105 // we could end up having stale pointers to the Blink heap which has been 108 // we could end up having stale pointers to the Blink heap which has been
106 // terminated by this point. 109 // terminated by this point.
107 DCHECK(MainThreadOnly().was_shutdown); 110 DCHECK(MainThreadOnly().was_shutdown);
108 } 111 }
109 112
110 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly( 113 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly(
111 RendererSchedulerImpl* renderer_scheduler_impl,
112 const scoped_refptr<TaskQueue>& compositor_task_runner, 114 const scoped_refptr<TaskQueue>& compositor_task_runner,
113 base::TickClock* time_source) 115 base::TickClock* time_source)
114 : loading_task_cost_estimator(time_source, 116 : loading_task_cost_estimator(time_source,
115 kLoadingTaskEstimationSampleCount, 117 kLoadingTaskEstimationSampleCount,
116 kLoadingTaskEstimationPercentile), 118 kLoadingTaskEstimationPercentile),
117 timer_task_cost_estimator(time_source, 119 timer_task_cost_estimator(time_source,
118 kTimerTaskEstimationSampleCount, 120 kTimerTaskEstimationSampleCount,
119 kTimerTaskEstimationPercentile), 121 kTimerTaskEstimationPercentile),
120 queueing_time_estimator(renderer_scheduler_impl,
121 base::TimeDelta::FromSeconds(1)),
122 idle_time_estimator(compositor_task_runner, 122 idle_time_estimator(compositor_task_runner,
123 time_source, 123 time_source,
124 kShortIdlePeriodDurationSampleCount, 124 kShortIdlePeriodDurationSampleCount,
125 kShortIdlePeriodDurationPercentile), 125 kShortIdlePeriodDurationPercentile),
126 current_use_case(UseCase::NONE), 126 current_use_case(UseCase::NONE),
127 timer_queue_suspend_count(0), 127 timer_queue_suspend_count(0),
128 navigation_task_expected_count(0), 128 navigation_task_expected_count(0),
129 expensive_task_policy(ExpensiveTaskPolicy::RUN), 129 expensive_task_policy(ExpensiveTaskPolicy::RUN),
130 renderer_hidden(false), 130 renderer_hidden(false),
131 renderer_backgrounded(false), 131 renderer_backgrounded(false),
132 renderer_suspended(false), 132 renderer_suspended(false),
133 timer_queue_suspension_when_backgrounded_enabled(false), 133 timer_queue_suspension_when_backgrounded_enabled(false),
134 timer_queue_suspended_when_backgrounded(false), 134 timer_queue_suspended_when_backgrounded(false),
135 was_shutdown(false), 135 was_shutdown(false),
136 loading_tasks_seem_expensive(false), 136 loading_tasks_seem_expensive(false),
137 timer_tasks_seem_expensive(false), 137 timer_tasks_seem_expensive(false),
138 touchstart_expected_soon(false), 138 touchstart_expected_soon(false),
139 have_seen_a_begin_main_frame(false), 139 have_seen_a_begin_main_frame(false),
140 have_reported_blocking_intervention_in_current_policy(false), 140 have_reported_blocking_intervention_in_current_policy(false),
141 have_reported_blocking_intervention_since_navigation(false), 141 have_reported_blocking_intervention_since_navigation(false),
142 has_visible_render_widget_with_touch_handler(false), 142 has_visible_render_widget_with_touch_handler(false),
143 begin_frame_not_expected_soon(false), 143 begin_frame_not_expected_soon(false),
144 in_idle_period_for_testing(false), 144 in_idle_period_for_testing(false),
145 use_virtual_time(false), 145 use_virtual_time(false),
146 rail_mode_observer(nullptr) {} 146 rail_mode_observer(nullptr) {}
147 147
148 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} 148 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {}
149 149
150 RendererSchedulerImpl::AnyThread::AnyThread() 150 RendererSchedulerImpl::AnyThread::AnyThread(
151 : awaiting_touch_start_response(false), 151 RendererSchedulerImpl* renderer_scheduler_impl)
152 : queueing_time_estimator(renderer_scheduler_impl,
153 base::TimeDelta::FromSeconds(1)),
154 awaiting_touch_start_response(false),
152 in_idle_period(false), 155 in_idle_period(false),
153 begin_main_frame_on_critical_path(false), 156 begin_main_frame_on_critical_path(false),
154 last_gesture_was_compositor_driven(false), 157 last_gesture_was_compositor_driven(false),
155 default_gesture_prevented(true), 158 default_gesture_prevented(true),
156 have_seen_touchstart(false) {} 159 have_seen_touchstart(false) {}
157 160
158 RendererSchedulerImpl::AnyThread::~AnyThread() {} 161 RendererSchedulerImpl::AnyThread::~AnyThread() {}
159 162
160 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() 163 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly()
161 : last_input_type(blink::WebInputEvent::Undefined) {} 164 : last_input_type(blink::WebInputEvent::Undefined) {}
(...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 default_loading_task_runner_->SetBlameContext(blame_context); 1334 default_loading_task_runner_->SetBlameContext(blame_context);
1332 default_timer_task_runner_->SetBlameContext(blame_context); 1335 default_timer_task_runner_->SetBlameContext(blame_context);
1333 compositor_task_runner_->SetBlameContext(blame_context); 1336 compositor_task_runner_->SetBlameContext(blame_context);
1334 idle_helper_.IdleTaskRunner()->SetBlameContext(blame_context); 1337 idle_helper_.IdleTaskRunner()->SetBlameContext(blame_context);
1335 } 1338 }
1336 1339
1337 void RendererSchedulerImpl::SetRAILModeObserver(RAILModeObserver* observer) { 1340 void RendererSchedulerImpl::SetRAILModeObserver(RAILModeObserver* observer) {
1338 MainThreadOnly().rail_mode_observer = observer; 1341 MainThreadOnly().rail_mode_observer = observer;
1339 } 1342 }
1340 1343
1344 bool RendererSchedulerImpl::
1345 ShouldForceEventsNonBlockingForUnresponsiveMainThread() const {
1346 base::TimeTicks now = base::TimeTicks::Now();
1347 base::TimeDelta estimated_queueing_time;
1348
1349 {
1350 base::AutoLock lock(any_thread_lock_);
1351
1352 estimated_queueing_time =
1353 AnyThread()
1354 .queueing_time_estimator.EstimateQueueingTimeIncludingCurrentTask(
1355 now);
1356 }
1357
1358 return estimated_queueing_time > kMainThreadUnresponsiveQueueingTime;
1359 }
1360
1341 void RendererSchedulerImpl::RegisterTimeDomain(TimeDomain* time_domain) { 1361 void RendererSchedulerImpl::RegisterTimeDomain(TimeDomain* time_domain) {
1342 helper_.RegisterTimeDomain(time_domain); 1362 helper_.RegisterTimeDomain(time_domain);
1343 } 1363 }
1344 1364
1345 void RendererSchedulerImpl::UnregisterTimeDomain(TimeDomain* time_domain) { 1365 void RendererSchedulerImpl::UnregisterTimeDomain(TimeDomain* time_domain) {
1346 helper_.UnregisterTimeDomain(time_domain); 1366 helper_.UnregisterTimeDomain(time_domain);
1347 } 1367 }
1348 1368
1349 base::TickClock* RendererSchedulerImpl::tick_clock() const { 1369 base::TickClock* RendererSchedulerImpl::tick_clock() const {
1350 return helper_.scheduler_tqm_delegate().get(); 1370 return helper_.scheduler_tqm_delegate().get();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 true; 1420 true;
1401 BroadcastIntervention( 1421 BroadcastIntervention(
1402 "Blink deferred a task in order to make scrolling smoother. " 1422 "Blink deferred a task in order to make scrolling smoother. "
1403 "Your timer and network tasks should take less than 50ms to run " 1423 "Your timer and network tasks should take less than 50ms to run "
1404 "to avoid this. Please see " 1424 "to avoid this. Please see "
1405 "https://developers.google.com/web/tools/chrome-devtools/profile/evaluat e-performance/rail" 1425 "https://developers.google.com/web/tools/chrome-devtools/profile/evaluat e-performance/rail"
1406 " and https://crbug.com/574343#c40 for more information."); 1426 " and https://crbug.com/574343#c40 for more information.");
1407 } 1427 }
1408 } 1428 }
1409 1429
1430 void RendererSchedulerImpl::ReportTaskStartTime(base::TimeTicks start_time) {
1431 base::AutoLock lock(any_thread_lock_);
Sami 2016/08/24 14:56:01 This makes us take two locks for every task we exe
tdresser 2016/08/24 17:22:50 I think there are basically two options here: The
Sami 2016/08/25 12:48:44 Do you think this happens often enough that we act
tdresser 2016/08/25 15:27:12 One of the biggest cases we want to address with t
1432 AnyThread().queueing_time_estimator.OnTopLevelTaskStarted(start_time);
1433 }
1434
1410 void RendererSchedulerImpl::ReportTaskTime(base::TimeTicks start_time, 1435 void RendererSchedulerImpl::ReportTaskTime(base::TimeTicks start_time,
1411 base::TimeTicks end_time) { 1436 base::TimeTicks end_time) {
1412 MainThreadOnly().queueing_time_estimator.OnToplevelTaskCompleted(start_time, 1437 {
1413 end_time); 1438 base::AutoLock lock(any_thread_lock_);
1414 MainThreadOnly().long_task_tracker.RecordLongTask( 1439 AnyThread().queueing_time_estimator.OnTopLevelTaskCompleted(start_time,
1415 start_time, end_time - start_time); 1440 end_time);
1441 }
1442 MainThreadOnly().long_task_tracker.RecordLongTask(start_time,
1443 end_time - start_time);
1444
1416 UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.TaskTime", 1445 UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.TaskTime",
1417 (end_time - start_time).InMicroseconds(), 1, 1446 (end_time - start_time).InMicroseconds(), 1,
1418 1000000, 50); 1447 1000000, 50);
1419 } 1448 }
1420 1449
1421 LongTaskTracker::LongTaskTiming RendererSchedulerImpl::GetLongTaskTiming() { 1450 LongTaskTracker::LongTaskTiming RendererSchedulerImpl::GetLongTaskTiming() {
1422 return MainThreadOnly().long_task_tracker.GetLongTaskTiming(); 1451 return MainThreadOnly().long_task_tracker.GetLongTaskTiming();
1423 } 1452 }
1424 1453
1425 void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated( 1454 void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated(
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 case v8::PERFORMANCE_LOAD: 1517 case v8::PERFORMANCE_LOAD:
1489 return "load"; 1518 return "load";
1490 default: 1519 default:
1491 NOTREACHED(); 1520 NOTREACHED();
1492 return nullptr; 1521 return nullptr;
1493 } 1522 }
1494 } 1523 }
1495 1524
1496 } // namespace scheduler 1525 } // namespace scheduler
1497 } // namespace blink 1526 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698