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

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

Issue 2668663002: Purge memory before suspending timer queues when backgrounded. (Closed)
Patch Set: Remove mainThreadOnly's timer_queue_suspended_when_backgrounded Created 3 years, 10 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 policy_may_need_update_(&any_thread_lock_), 116 policy_may_need_update_(&any_thread_lock_),
117 main_thread_responsiveness_threshold_(kMainThreadResponsivenessThreshold), 117 main_thread_responsiveness_threshold_(kMainThreadResponsivenessThreshold),
118 weak_factory_(this) { 118 weak_factory_(this) {
119 task_queue_throttler_.reset( 119 task_queue_throttler_.reset(
120 new TaskQueueThrottler(this, "renderer.scheduler")); 120 new TaskQueueThrottler(this, "renderer.scheduler"));
121 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, 121 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
122 weak_factory_.GetWeakPtr()); 122 weak_factory_.GetWeakPtr());
123 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( 123 end_renderer_hidden_idle_period_closure_.Reset(base::Bind(
124 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); 124 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr()));
125 125
126 suspend_timers_when_backgrounded_closure_.Reset(
127 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded,
128 weak_factory_.GetWeakPtr()));
129
130 default_loading_task_runner_ = 126 default_loading_task_runner_ =
131 NewLoadingTaskRunner(TaskQueue::QueueType::DEFAULT_LOADING); 127 NewLoadingTaskRunner(TaskQueue::QueueType::DEFAULT_LOADING);
132 default_timer_task_runner_ = 128 default_timer_task_runner_ =
133 NewTimerTaskRunner(TaskQueue::QueueType::DEFAULT_TIMER); 129 NewTimerTaskRunner(TaskQueue::QueueType::DEFAULT_TIMER);
134 130
135 TRACE_EVENT_OBJECT_CREATED_WITH_ID( 131 TRACE_EVENT_OBJECT_CREATED_WITH_ID(
136 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 132 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
137 this); 133 this);
138 134
139 helper_.SetObserver(this); 135 helper_.SetObserver(this);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 base::Bind(&ReportForegroundRendererTaskLoad), 195 base::Bind(&ReportForegroundRendererTaskLoad),
200 kThreadLoadTrackerReportingInterval, 196 kThreadLoadTrackerReportingInterval,
201 kThreadLoadTrackerWaitingPeriodBeforeReporting), 197 kThreadLoadTrackerWaitingPeriodBeforeReporting),
202 current_use_case(UseCase::NONE), 198 current_use_case(UseCase::NONE),
203 timer_queue_suspend_count(0), 199 timer_queue_suspend_count(0),
204 navigation_task_expected_count(0), 200 navigation_task_expected_count(0),
205 expensive_task_policy(ExpensiveTaskPolicy::RUN), 201 expensive_task_policy(ExpensiveTaskPolicy::RUN),
206 renderer_hidden(false), 202 renderer_hidden(false),
207 renderer_backgrounded(false), 203 renderer_backgrounded(false),
208 renderer_suspended(false), 204 renderer_suspended(false),
209 timer_queue_suspension_when_backgrounded_enabled(false),
210 timer_queue_suspended_when_backgrounded(false), 205 timer_queue_suspended_when_backgrounded(false),
211 was_shutdown(false), 206 was_shutdown(false),
212 loading_tasks_seem_expensive(false), 207 loading_tasks_seem_expensive(false),
213 timer_tasks_seem_expensive(false), 208 timer_tasks_seem_expensive(false),
214 touchstart_expected_soon(false), 209 touchstart_expected_soon(false),
215 have_seen_a_begin_main_frame(false), 210 have_seen_a_begin_main_frame(false),
216 have_reported_blocking_intervention_in_current_policy(false), 211 have_reported_blocking_intervention_in_current_policy(false),
217 have_reported_blocking_intervention_since_navigation(false), 212 have_reported_blocking_intervention_since_navigation(false),
218 has_visible_render_widget_with_touch_handler(false), 213 has_visible_render_widget_with_touch_handler(false),
219 begin_frame_not_expected_soon(false), 214 begin_frame_not_expected_soon(false),
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 if (helper_.IsShutdown() || MainThreadOnly().renderer_backgrounded) 488 if (helper_.IsShutdown() || MainThreadOnly().renderer_backgrounded)
494 return; 489 return;
495 490
496 MainThreadOnly().renderer_backgrounded = true; 491 MainThreadOnly().renderer_backgrounded = true;
497 492
498 UpdatePolicy(); 493 UpdatePolicy();
499 494
500 base::TimeTicks now = tick_clock()->NowTicks(); 495 base::TimeTicks now = tick_clock()->NowTicks();
501 MainThreadOnly().foreground_main_thread_load_tracker.Pause(now); 496 MainThreadOnly().foreground_main_thread_load_tracker.Pause(now);
502 MainThreadOnly().background_main_thread_load_tracker.Resume(now); 497 MainThreadOnly().background_main_thread_load_tracker.Resume(now);
503
504 if (!MainThreadOnly().timer_queue_suspension_when_backgrounded_enabled)
505 return;
506
507 suspend_timers_when_backgrounded_closure_.Cancel();
508 base::TimeDelta suspend_timers_when_backgrounded_delay =
509 base::TimeDelta::FromMilliseconds(
510 kSuspendTimersWhenBackgroundedDelayMillis);
511 control_task_runner_->PostDelayedTask(
512 FROM_HERE, suspend_timers_when_backgrounded_closure_.callback(),
513 suspend_timers_when_backgrounded_delay);
514 } 498 }
515 499
516 void RendererSchedulerImpl::OnRendererForegrounded() { 500 void RendererSchedulerImpl::OnRendererForegrounded() {
517 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 501 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
518 "RendererSchedulerImpl::OnRendererForegrounded"); 502 "RendererSchedulerImpl::OnRendererForegrounded");
519 helper_.CheckOnValidThread(); 503 helper_.CheckOnValidThread();
520 if (helper_.IsShutdown() || !MainThreadOnly().renderer_backgrounded) 504 if (helper_.IsShutdown() || !MainThreadOnly().renderer_backgrounded)
521 return; 505 return;
522 506
523 MainThreadOnly().renderer_backgrounded = false; 507 MainThreadOnly().renderer_backgrounded = false;
524 MainThreadOnly().renderer_suspended = false; 508 MainThreadOnly().renderer_suspended = false;
525 509
526 UpdatePolicy(); 510 UpdatePolicy();
527 511
528 base::TimeTicks now = tick_clock()->NowTicks(); 512 base::TimeTicks now = tick_clock()->NowTicks();
529 MainThreadOnly().foreground_main_thread_load_tracker.Resume(now); 513 MainThreadOnly().foreground_main_thread_load_tracker.Resume(now);
530 MainThreadOnly().background_main_thread_load_tracker.Pause(now); 514 MainThreadOnly().background_main_thread_load_tracker.Pause(now);
531 515
532 suspend_timers_when_backgrounded_closure_.Cancel();
533 ResumeTimerQueueWhenForegroundedOrResumed(); 516 ResumeTimerQueueWhenForegroundedOrResumed();
534 } 517 }
535 518
536 void RendererSchedulerImpl::OnAudioStateChanged() { 519 void RendererSchedulerImpl::OnAudioStateChanged() {
537 bool is_audio_playing = false; 520 bool is_audio_playing = false;
538 for (WebViewSchedulerImpl* web_view_scheduler : 521 for (WebViewSchedulerImpl* web_view_scheduler :
539 MainThreadOnly().web_view_schedulers) { 522 MainThreadOnly().web_view_schedulers) {
540 is_audio_playing = is_audio_playing || web_view_scheduler->IsAudioPlaying(); 523 is_audio_playing = is_audio_playing || web_view_scheduler->IsAudioPlaying();
541 } 524 }
542 525
543 if (is_audio_playing == MainThreadOnly().is_audio_playing) 526 if (is_audio_playing == MainThreadOnly().is_audio_playing)
544 return; 527 return;
545 528
546 MainThreadOnly().last_audio_state_change = 529 MainThreadOnly().last_audio_state_change =
547 helper_.scheduler_tqm_delegate()->NowTicks(); 530 helper_.scheduler_tqm_delegate()->NowTicks();
548 MainThreadOnly().is_audio_playing = is_audio_playing; 531 MainThreadOnly().is_audio_playing = is_audio_playing;
549 532
550 UpdatePolicy(); 533 UpdatePolicy();
551 } 534 }
552 535
553 void RendererSchedulerImpl::SuspendRenderer() { 536 void RendererSchedulerImpl::SuspendRenderer() {
554 helper_.CheckOnValidThread(); 537 helper_.CheckOnValidThread();
555 if (helper_.IsShutdown()) 538 if (helper_.IsShutdown())
556 return; 539 return;
557 if (!MainThreadOnly().renderer_backgrounded) 540 if (!MainThreadOnly().renderer_backgrounded)
558 return; 541 return;
559 suspend_timers_when_backgrounded_closure_.Cancel();
560 542
561 UMA_HISTOGRAM_COUNTS("PurgeAndSuspend.PendingTaskCount", 543 UMA_HISTOGRAM_COUNTS("PurgeAndSuspend.PendingTaskCount",
562 helper_.GetNumberOfPendingTasks()); 544 helper_.GetNumberOfPendingTasks());
563 545
564 // TODO(hajimehoshi): We might need to suspend not only timer queue but also 546 // TODO(hajimehoshi): We might need to suspend not only timer queue but also
565 // e.g. loading tasks or postMessage. 547 // e.g. loading tasks or postMessage.
566 MainThreadOnly().renderer_suspended = true; 548 MainThreadOnly().renderer_suspended = true;
567 SuspendTimerQueueWhenBackgrounded(); 549 SuspendTimerQueueWhenBackgrounded();
568 } 550 }
569 551
570 void RendererSchedulerImpl::ResumeRenderer() { 552 void RendererSchedulerImpl::ResumeRenderer() {
571 helper_.CheckOnValidThread(); 553 helper_.CheckOnValidThread();
572 if (helper_.IsShutdown()) 554 if (helper_.IsShutdown())
573 return; 555 return;
574 if (!MainThreadOnly().renderer_backgrounded) 556 if (!MainThreadOnly().renderer_backgrounded)
575 return; 557 return;
576 suspend_timers_when_backgrounded_closure_.Cancel(); 558
577 MainThreadOnly().renderer_suspended = false; 559 MainThreadOnly().renderer_suspended = false;
578 ResumeTimerQueueWhenForegroundedOrResumed(); 560 ResumeTimerQueueWhenForegroundedOrResumed();
579 } 561 }
580 562
581 void RendererSchedulerImpl::EndIdlePeriod() { 563 void RendererSchedulerImpl::EndIdlePeriod() {
582 if (MainThreadOnly().in_idle_period_for_testing) 564 if (MainThreadOnly().in_idle_period_for_testing)
583 return; 565 return;
584 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 566 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
585 "RendererSchedulerImpl::EndIdlePeriod"); 567 "RendererSchedulerImpl::EndIdlePeriod");
586 helper_.CheckOnValidThread(); 568 helper_.CheckOnValidThread();
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 } 1308 }
1327 #endif 1309 #endif
1328 } 1310 }
1329 1311
1330 void RendererSchedulerImpl::ResumeTimerQueue() { 1312 void RendererSchedulerImpl::ResumeTimerQueue() {
1331 MainThreadOnly().timer_queue_suspend_count--; 1313 MainThreadOnly().timer_queue_suspend_count--;
1332 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); 1314 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0);
1333 ForceUpdatePolicy(); 1315 ForceUpdatePolicy();
1334 } 1316 }
1335 1317
1336 void RendererSchedulerImpl::SetTimerQueueSuspensionWhenBackgroundedEnabled(
1337 bool enabled) {
1338 // Note that this will only take effect for the next backgrounded signal.
1339 MainThreadOnly().timer_queue_suspension_when_backgrounded_enabled = enabled;
1340 }
1341
1342 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> 1318 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
1343 RendererSchedulerImpl::AsValue(base::TimeTicks optional_now) const { 1319 RendererSchedulerImpl::AsValue(base::TimeTicks optional_now) const {
1344 base::AutoLock lock(any_thread_lock_); 1320 base::AutoLock lock(any_thread_lock_);
1345 return AsValueLocked(optional_now); 1321 return AsValueLocked(optional_now);
1346 } 1322 }
1347 1323
1348 void RendererSchedulerImpl::CreateTraceEventObjectSnapshot() const { 1324 void RendererSchedulerImpl::CreateTraceEventObjectSnapshot() const {
1349 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 1325 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
1350 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 1326 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
1351 this, AsValue(helper_.scheduler_tqm_delegate()->NowTicks())); 1327 this, AsValue(helper_.scheduler_tqm_delegate()->NowTicks()));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 state->SetBoolean("have_seen_input_since_navigation", 1382 state->SetBoolean("have_seen_input_since_navigation",
1407 AnyThread().have_seen_input_since_navigation); 1383 AnyThread().have_seen_input_since_navigation);
1408 state->SetBoolean( 1384 state->SetBoolean(
1409 "have_reported_blocking_intervention_in_current_policy", 1385 "have_reported_blocking_intervention_in_current_policy",
1410 MainThreadOnly().have_reported_blocking_intervention_in_current_policy); 1386 MainThreadOnly().have_reported_blocking_intervention_in_current_policy);
1411 state->SetBoolean( 1387 state->SetBoolean(
1412 "have_reported_blocking_intervention_since_navigation", 1388 "have_reported_blocking_intervention_since_navigation",
1413 MainThreadOnly().have_reported_blocking_intervention_since_navigation); 1389 MainThreadOnly().have_reported_blocking_intervention_since_navigation);
1414 state->SetBoolean("renderer_backgrounded", 1390 state->SetBoolean("renderer_backgrounded",
1415 MainThreadOnly().renderer_backgrounded); 1391 MainThreadOnly().renderer_backgrounded);
1416 state->SetBoolean("timer_queue_suspended_when_backgrounded",
1417 MainThreadOnly().timer_queue_suspended_when_backgrounded);
1418 state->SetInteger("timer_queue_suspend_count", 1392 state->SetInteger("timer_queue_suspend_count",
1419 MainThreadOnly().timer_queue_suspend_count); 1393 MainThreadOnly().timer_queue_suspend_count);
1420 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); 1394 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF());
1421 state->SetDouble( 1395 state->SetDouble(
1422 "fling_compositor_escalation_deadline", 1396 "fling_compositor_escalation_deadline",
1423 (AnyThread().fling_compositor_escalation_deadline - base::TimeTicks()) 1397 (AnyThread().fling_compositor_escalation_deadline - base::TimeTicks())
1424 .InMillisecondsF()); 1398 .InMillisecondsF());
1425 state->SetInteger("navigation_task_expected_count", 1399 state->SetInteger("navigation_task_expected_count",
1426 MainThreadOnly().navigation_task_expected_count); 1400 MainThreadOnly().navigation_task_expected_count);
1427 state->SetDouble("last_idle_period_end_time", 1401 state->SetDouble("last_idle_period_end_time",
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 case TimeDomainType::VIRTUAL: 1860 case TimeDomainType::VIRTUAL:
1887 return "virtual"; 1861 return "virtual";
1888 default: 1862 default:
1889 NOTREACHED(); 1863 NOTREACHED();
1890 return nullptr; 1864 return nullptr;
1891 } 1865 }
1892 } 1866 }
1893 1867
1894 } // namespace scheduler 1868 } // namespace scheduler
1895 } // namespace blink 1869 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698