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

Side by Side Diff: components/scheduler/renderer/renderer_scheduler_impl.cc

Issue 1898233002: Report expected task queueing time via UMA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: RenderSchedulerImpl owns all the things. Created 4 years, 5 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 "components/scheduler/renderer/renderer_scheduler_impl.h" 5 #include "components/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"
11 #include "base/metrics/histogram_macros.h"
11 #include "base/trace_event/trace_event.h" 12 #include "base/trace_event/trace_event.h"
12 #include "base/trace_event/trace_event_argument.h" 13 #include "base/trace_event/trace_event_argument.h"
13 #include "cc/output/begin_frame_args.h" 14 #include "cc/output/begin_frame_args.h"
14 #include "components/scheduler/base/task_queue_impl.h" 15 #include "components/scheduler/base/task_queue_impl.h"
15 #include "components/scheduler/base/task_queue_selector.h" 16 #include "components/scheduler/base/task_queue_selector.h"
16 #include "components/scheduler/base/virtual_time_domain.h" 17 #include "components/scheduler/base/virtual_time_domain.h"
17 #include "components/scheduler/child/scheduler_tqm_delegate.h" 18 #include "components/scheduler/child/scheduler_tqm_delegate.h"
18 #include "components/scheduler/renderer/web_view_scheduler_impl.h" 19 #include "components/scheduler/renderer/web_view_scheduler_impl.h"
19 #include "components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h" 20 #include "components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h"
20 21
21 namespace scheduler { 22 namespace scheduler {
22 namespace { 23 namespace {
23 // The run time of loading tasks is strongly bimodal. The vast majority are 24 // The run time of loading tasks is strongly bimodal. The vast majority are
24 // very cheap, but there are usually a handful of very expensive tasks (e.g ~1 25 // very cheap, but there are usually a handful of very expensive tasks (e.g ~1
25 // second on a mobile device) so we take a very pesimistic view when estimating 26 // second on a mobile device) so we take a very pessimistic view when estimating
26 // the cost of loading tasks. 27 // the cost of loading tasks.
27 const int kLoadingTaskEstimationSampleCount = 1000; 28 const int kLoadingTaskEstimationSampleCount = 1000;
28 const double kLoadingTaskEstimationPercentile = 99; 29 const double kLoadingTaskEstimationPercentile = 99;
29 const int kTimerTaskEstimationSampleCount = 1000; 30 const int kTimerTaskEstimationSampleCount = 1000;
30 const double kTimerTaskEstimationPercentile = 99; 31 const double kTimerTaskEstimationPercentile = 99;
31 const int kShortIdlePeriodDurationSampleCount = 10; 32 const int kShortIdlePeriodDurationSampleCount = 10;
32 const double kShortIdlePeriodDurationPercentile = 50; 33 const double kShortIdlePeriodDurationPercentile = 50;
33 // Amount of idle time left in a frame (as a ratio of the vsync interval) above 34 // Amount of idle time left in a frame (as a ratio of the vsync interval) above
34 // which main thread compositing can be considered fast. 35 // which main thread compositing can be considered fast.
35 const double kFastCompositingIdleTimeThreshold = .2; 36 const double kFastCompositingIdleTimeThreshold = .2;
36 } // namespace 37 } // namespace
37 38
38 RendererSchedulerImpl::RendererSchedulerImpl( 39 RendererSchedulerImpl::RendererSchedulerImpl(
39 scoped_refptr<SchedulerTqmDelegate> main_task_runner) 40 scoped_refptr<SchedulerTqmDelegate> main_task_runner)
40 : helper_(main_task_runner, 41 : helper_(main_task_runner,
41 "renderer.scheduler", 42 "renderer.scheduler",
42 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 43 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
43 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), 44 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")),
44 idle_helper_(&helper_, 45 idle_helper_(&helper_,
45 this, 46 this,
46 "renderer.scheduler", 47 "renderer.scheduler",
47 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 48 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
48 "RendererSchedulerIdlePeriod", 49 "RendererSchedulerIdlePeriod",
49 base::TimeDelta()), 50 base::TimeDelta()),
51 task_time_tracker_(this),
50 render_widget_scheduler_signals_(this), 52 render_widget_scheduler_signals_(this),
51 control_task_runner_(helper_.ControlTaskRunner()), 53 control_task_runner_(helper_.ControlTaskRunner()),
52 compositor_task_runner_( 54 compositor_task_runner_(helper_.NewTaskQueue(
53 helper_.NewTaskQueue(TaskQueue::Spec("compositor_tq") 55 TaskQueue::Spec("compositor_tq").SetShouldMonitorQuiescence(true))),
54 .SetShouldMonitorQuiescence(true))),
55 delayed_update_policy_runner_( 56 delayed_update_policy_runner_(
56 base::Bind(&RendererSchedulerImpl::UpdatePolicy, 57 base::Bind(&RendererSchedulerImpl::UpdatePolicy,
57 base::Unretained(this)), 58 base::Unretained(this)),
58 helper_.ControlTaskRunner()), 59 helper_.ControlTaskRunner()),
59 main_thread_only_(compositor_task_runner_, 60 main_thread_only_(this,
61 compositor_task_runner_,
60 helper_.scheduler_tqm_delegate().get()), 62 helper_.scheduler_tqm_delegate().get()),
61 policy_may_need_update_(&any_thread_lock_), 63 policy_may_need_update_(&any_thread_lock_),
62 weak_factory_(this) { 64 weak_factory_(this) {
63 throttling_helper_.reset(new ThrottlingHelper(this, "renderer.scheduler")); 65 throttling_helper_.reset(new ThrottlingHelper(this, "renderer.scheduler"));
64 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, 66 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
65 weak_factory_.GetWeakPtr()); 67 weak_factory_.GetWeakPtr());
66 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( 68 end_renderer_hidden_idle_period_closure_.Reset(base::Bind(
67 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); 69 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr()));
68 70
69 suspend_timers_when_backgrounded_closure_.Reset( 71 suspend_timers_when_backgrounded_closure_.Reset(
70 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, 72 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded,
71 weak_factory_.GetWeakPtr())); 73 weak_factory_.GetWeakPtr()));
72 74
73 default_loading_task_runner_ = NewLoadingTaskRunner("default_loading_tq"); 75 default_loading_task_runner_ = NewLoadingTaskRunner("default_loading_tq");
74 default_timer_task_runner_ = NewTimerTaskRunner("default_timer_tq"); 76 default_timer_task_runner_ = NewTimerTaskRunner("default_timer_tq");
75 77
76 TRACE_EVENT_OBJECT_CREATED_WITH_ID( 78 TRACE_EVENT_OBJECT_CREATED_WITH_ID(
77 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 79 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
78 this); 80 this);
79 81
80 helper_.SetObserver(this); 82 helper_.SetObserver(this);
83 helper_.SetTaskTimeTracker(&task_time_tracker_);
81 } 84 }
82 85
83 RendererSchedulerImpl::~RendererSchedulerImpl() { 86 RendererSchedulerImpl::~RendererSchedulerImpl() {
84 TRACE_EVENT_OBJECT_DELETED_WITH_ID( 87 TRACE_EVENT_OBJECT_DELETED_WITH_ID(
85 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 88 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
86 this); 89 this);
87 90
88 for (const scoped_refptr<TaskQueue>& loading_queue : loading_task_runners_) { 91 for (const scoped_refptr<TaskQueue>& loading_queue : loading_task_runners_) {
89 loading_queue->RemoveTaskObserver( 92 loading_queue->RemoveTaskObserver(
90 &MainThreadOnly().loading_task_cost_estimator); 93 &MainThreadOnly().loading_task_cost_estimator);
91 } 94 }
92 for (const scoped_refptr<TaskQueue>& timer_queue : timer_task_runners_) { 95 for (const scoped_refptr<TaskQueue>& timer_queue : timer_task_runners_) {
93 timer_queue->RemoveTaskObserver( 96 timer_queue->RemoveTaskObserver(
94 &MainThreadOnly().timer_task_cost_estimator); 97 &MainThreadOnly().timer_task_cost_estimator);
95 } 98 }
96 99
97 // Ensure the renderer scheduler was shut down explicitly, because otherwise 100 // Ensure the renderer scheduler was shut down explicitly, because otherwise
98 // we could end up having stale pointers to the Blink heap which has been 101 // we could end up having stale pointers to the Blink heap which has been
99 // terminated by this point. 102 // terminated by this point.
100 DCHECK(MainThreadOnly().was_shutdown); 103 DCHECK(MainThreadOnly().was_shutdown);
101 } 104 }
102 105
103 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly( 106 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly(
107 RendererSchedulerImpl* renderer_scheduler_impl,
104 const scoped_refptr<TaskQueue>& compositor_task_runner, 108 const scoped_refptr<TaskQueue>& compositor_task_runner,
105 base::TickClock* time_source) 109 base::TickClock* time_source)
106 : loading_task_cost_estimator(time_source, 110 : loading_task_cost_estimator(time_source,
107 kLoadingTaskEstimationSampleCount, 111 kLoadingTaskEstimationSampleCount,
108 kLoadingTaskEstimationPercentile), 112 kLoadingTaskEstimationPercentile),
109 timer_task_cost_estimator(time_source, 113 timer_task_cost_estimator(time_source,
110 kTimerTaskEstimationSampleCount, 114 kTimerTaskEstimationSampleCount,
111 kTimerTaskEstimationPercentile), 115 kTimerTaskEstimationPercentile),
116 queueing_time_estimator(renderer_scheduler_impl,
117 base::TimeDelta::FromSeconds(1)),
112 idle_time_estimator(compositor_task_runner, 118 idle_time_estimator(compositor_task_runner,
113 time_source, 119 time_source,
114 kShortIdlePeriodDurationSampleCount, 120 kShortIdlePeriodDurationSampleCount,
115 kShortIdlePeriodDurationPercentile), 121 kShortIdlePeriodDurationPercentile),
116 current_use_case(UseCase::NONE), 122 current_use_case(UseCase::NONE),
117 timer_queue_suspend_count(0), 123 timer_queue_suspend_count(0),
118 navigation_task_expected_count(0), 124 navigation_task_expected_count(0),
119 expensive_task_policy(ExpensiveTaskPolicy::RUN), 125 expensive_task_policy(ExpensiveTaskPolicy::RUN),
120 renderer_hidden(false), 126 renderer_hidden(false),
121 renderer_backgrounded(false), 127 renderer_backgrounded(false),
(...skipping 1254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 true; 1382 true;
1377 BroadcastConsoleWarning( 1383 BroadcastConsoleWarning(
1378 "Blink deferred a task in order to make scrolling smoother. " 1384 "Blink deferred a task in order to make scrolling smoother. "
1379 "Your timer and network tasks should take less than 50ms to run " 1385 "Your timer and network tasks should take less than 50ms to run "
1380 "to avoid this. Please see " 1386 "to avoid this. Please see "
1381 "https://developers.google.com/web/tools/chrome-devtools/profile/evaluat e-performance/rail" 1387 "https://developers.google.com/web/tools/chrome-devtools/profile/evaluat e-performance/rail"
1382 " and https://crbug.com/574343#c40 for more information."); 1388 " and https://crbug.com/574343#c40 for more information.");
1383 } 1389 }
1384 } 1390 }
1385 1391
1392 void RendererSchedulerImpl::ReportTaskTime(base::TimeTicks start_time,
1393 base::TimeTicks end_time) {
1394 MainThreadOnly().queueing_time_estimator.OnToplevelTaskCompleted(start_time,
1395 end_time);
1396 }
1397
1398 void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated(
1399 base::TimeDelta queueing_time) {
1400 UMA_HISTOGRAM_TIMES("RendererScheduler.ExpectedTaskQueueingDuration",
1401 queueing_time);
1402 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
1403 "estimated_queueing_time_for_window",
1404 queueing_time.InMillisecondsF());
1405 }
1406
1386 // static 1407 // static
1387 const char* RendererSchedulerImpl::UseCaseToString(UseCase use_case) { 1408 const char* RendererSchedulerImpl::UseCaseToString(UseCase use_case) {
1388 switch (use_case) { 1409 switch (use_case) {
1389 case UseCase::NONE: 1410 case UseCase::NONE:
1390 return "none"; 1411 return "none";
1391 case UseCase::COMPOSITOR_GESTURE: 1412 case UseCase::COMPOSITOR_GESTURE:
1392 return "compositor_gesture"; 1413 return "compositor_gesture";
1393 case UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING: 1414 case UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING:
1394 return "main_thread_custom_input_handling"; 1415 return "main_thread_custom_input_handling";
1395 case UseCase::SYNCHRONIZED_GESTURE: 1416 case UseCase::SYNCHRONIZED_GESTURE:
(...skipping 21 matching lines...) Expand all
1417 return "idle"; 1438 return "idle";
1418 case v8::PERFORMANCE_LOAD: 1439 case v8::PERFORMANCE_LOAD:
1419 return "load"; 1440 return "load";
1420 default: 1441 default:
1421 NOTREACHED(); 1442 NOTREACHED();
1422 return nullptr; 1443 return nullptr;
1423 } 1444 }
1424 } 1445 }
1425 1446
1426 } // namespace scheduler 1447 } // namespace scheduler
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698