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

Side by Side Diff: content/renderer/render_thread_impl.cc

Issue 8513008: Schedule idle handler in the foreground tab based on CPU usage and user activity. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Remove redundant 'using' and rebase Created 9 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 | Annotate | Revision Log
« no previous file with comments | « content/renderer/render_thread_impl.h ('k') | content/renderer/render_view_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "content/renderer/render_thread_impl.h" 5 #include "content/renderer/render_thread_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <map> 9 #include <map>
10 #include <vector> 10 #include <vector>
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 using WebKit::WebNetworkStateNotifier; 95 using WebKit::WebNetworkStateNotifier;
96 using WebKit::WebRuntimeFeatures; 96 using WebKit::WebRuntimeFeatures;
97 using WebKit::WebScriptController; 97 using WebKit::WebScriptController;
98 using WebKit::WebString; 98 using WebKit::WebString;
99 using WebKit::WebStorageEventDispatcher; 99 using WebKit::WebStorageEventDispatcher;
100 using WebKit::WebView; 100 using WebKit::WebView;
101 using content::RenderProcessObserver; 101 using content::RenderProcessObserver;
102 102
103 namespace { 103 namespace {
104 static const int64 kInitialIdleHandlerDelayMs = 1000; 104 static const int64 kInitialIdleHandlerDelayMs = 1000;
105 static const int64 kShortIdleHandlerDelayMs = 1000;
106 static const int64 kLongIdleHandlerDelayMs = 30*1000;
107 static const int kIdleCPUUsageThresholdInPercents = 3;
105 108
106 // Keep the global RenderThreadImpl in a TLS slot so it is impossible to access 109 // Keep the global RenderThreadImpl in a TLS slot so it is impossible to access
107 // incorrectly from the wrong thread. 110 // incorrectly from the wrong thread.
108 static base::LazyInstance<base::ThreadLocalPointer<RenderThreadImpl> > 111 static base::LazyInstance<base::ThreadLocalPointer<RenderThreadImpl> >
109 lazy_tls = LAZY_INSTANCE_INITIALIZER; 112 lazy_tls = LAZY_INSTANCE_INITIALIZER;
110 113
111 class RenderViewZoomer : public content::RenderViewVisitor { 114 class RenderViewZoomer : public content::RenderViewVisitor {
112 public: 115 public:
113 RenderViewZoomer(const GURL& url, double zoom_level) 116 RenderViewZoomer(const GURL& url, double zoom_level)
114 : zoom_level_(zoom_level) { 117 : zoom_level_(zoom_level) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 initialize_com_.reset(new base::win::ScopedCOMInitializer()); 186 initialize_com_.reset(new base::win::ScopedCOMInitializer());
184 #endif 187 #endif
185 188
186 // In single process the single process is all there is. 189 // In single process the single process is all there is.
187 suspend_webkit_shared_timer_ = true; 190 suspend_webkit_shared_timer_ = true;
188 notify_webkit_of_modal_loop_ = true; 191 notify_webkit_of_modal_loop_ = true;
189 plugin_refresh_allowed_ = true; 192 plugin_refresh_allowed_ = true;
190 widget_count_ = 0; 193 widget_count_ = 0;
191 hidden_widget_count_ = 0; 194 hidden_widget_count_ = 0;
192 idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs; 195 idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs;
196 idle_notifications_to_skip_ = 0;
197 base::ProcessHandle handle = base::GetCurrentProcessHandle();
198 #if defined(OS_MACOSX)
199 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle,
200 NULL));
201 #else
202 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle));
203 #endif
204 process_metrics_->GetCPUUsage(); // Initialize CPU usage counters.
193 task_factory_.reset(new ScopedRunnableMethodFactory<RenderThreadImpl>(this)); 205 task_factory_.reset(new ScopedRunnableMethodFactory<RenderThreadImpl>(this));
194 206
195 appcache_dispatcher_.reset(new AppCacheDispatcher(Get())); 207 appcache_dispatcher_.reset(new AppCacheDispatcher(Get()));
196 indexed_db_dispatcher_.reset(new IndexedDBDispatcher()); 208 indexed_db_dispatcher_.reset(new IndexedDBDispatcher());
197 209
198 db_message_filter_ = new DBMessageFilter(); 210 db_message_filter_ = new DBMessageFilter();
199 AddFilter(db_message_filter_.get()); 211 AddFilter(db_message_filter_.get());
200 212
201 vc_manager_ = new VideoCaptureImplManager(); 213 vc_manager_ = new VideoCaptureImplManager();
202 AddFilter(vc_manager_->video_capture_message_filter()); 214 AddFilter(vc_manager_->video_capture_message_filter());
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 } 420 }
409 421
410 void RenderThreadImpl::WidgetRestored() { 422 void RenderThreadImpl::WidgetRestored() {
411 DCHECK_GT(hidden_widget_count_, 0); 423 DCHECK_GT(hidden_widget_count_, 0);
412 hidden_widget_count_--; 424 hidden_widget_count_--;
413 if (!content::GetContentClient()->renderer()-> 425 if (!content::GetContentClient()->renderer()->
414 RunIdleHandlerWhenWidgetsHidden()) { 426 RunIdleHandlerWhenWidgetsHidden()) {
415 return; 427 return;
416 } 428 }
417 429
418 idle_timer_.Stop(); 430 ScheduleIdleHandler(kLongIdleHandlerDelayMs);
419 } 431 }
420 432
421 void RenderThreadImpl::EnsureWebKitInitialized() { 433 void RenderThreadImpl::EnsureWebKitInitialized() {
422 if (webkit_platform_support_.get()) 434 if (webkit_platform_support_.get())
423 return; 435 return;
424 436
425 v8::V8::SetCounterFunction(base::StatsTable::FindLocation); 437 v8::V8::SetCounterFunction(base::StatsTable::FindLocation);
426 v8::V8::SetCreateHistogramFunction(CreateHistogram); 438 v8::V8::SetCreateHistogramFunction(CreateHistogram);
427 v8::V8::SetAddHistogramSampleFunction(AddHistogramSample); 439 v8::V8::SetAddHistogramSampleFunction(AddHistogramSample);
428 440
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 536
525 WebRuntimeFeatures::enableFileSystem( 537 WebRuntimeFeatures::enableFileSystem(
526 !command_line.HasSwitch(switches::kDisableFileSystem)); 538 !command_line.HasSwitch(switches::kDisableFileSystem));
527 539
528 WebRuntimeFeatures::enableJavaScriptI18NAPI( 540 WebRuntimeFeatures::enableJavaScriptI18NAPI(
529 !command_line.HasSwitch(switches::kDisableJavaScriptI18NAPI)); 541 !command_line.HasSwitch(switches::kDisableJavaScriptI18NAPI));
530 542
531 WebRuntimeFeatures::enableQuota(true); 543 WebRuntimeFeatures::enableQuota(true);
532 544
533 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, WebKitInitialized()); 545 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, WebKitInitialized());
546
547 if (content::GetContentClient()->renderer()->
548 RunIdleHandlerWhenWidgetsHidden()) {
549 ScheduleIdleHandler(kLongIdleHandlerDelayMs);
550 }
534 } 551 }
535 552
536 void RenderThreadImpl::RecordUserMetrics(const std::string& action) { 553 void RenderThreadImpl::RecordUserMetrics(const std::string& action) {
537 Send(new ViewHostMsg_UserMetricsRecordAction(action)); 554 Send(new ViewHostMsg_UserMetricsRecordAction(action));
538 } 555 }
539 556
540 base::SharedMemoryHandle RenderThreadImpl::HostAllocateSharedMemoryBuffer( 557 base::SharedMemoryHandle RenderThreadImpl::HostAllocateSharedMemoryBuffer(
541 uint32 buffer_size) { 558 uint32 buffer_size) {
542 base::SharedMemoryHandle mem_handle; 559 base::SharedMemoryHandle mem_handle;
543 Send(new ChildProcessHostMsg_SyncAllocateSharedMemory( 560 Send(new ChildProcessHostMsg_SyncAllocateSharedMemory(
(...skipping 13 matching lines...) Expand all
557 574
558 void RenderThreadImpl::ScheduleIdleHandler(int64 initial_delay_ms) { 575 void RenderThreadImpl::ScheduleIdleHandler(int64 initial_delay_ms) {
559 idle_notification_delay_in_ms_ = initial_delay_ms; 576 idle_notification_delay_in_ms_ = initial_delay_ms;
560 idle_timer_.Stop(); 577 idle_timer_.Stop();
561 idle_timer_.Start(FROM_HERE, 578 idle_timer_.Start(FROM_HERE,
562 base::TimeDelta::FromMilliseconds(initial_delay_ms), 579 base::TimeDelta::FromMilliseconds(initial_delay_ms),
563 this, &RenderThreadImpl::IdleHandler); 580 this, &RenderThreadImpl::IdleHandler);
564 } 581 }
565 582
566 void RenderThreadImpl::IdleHandler() { 583 void RenderThreadImpl::IdleHandler() {
567 #if !defined(OS_MACOSX) && defined(USE_TCMALLOC) 584 bool run_in_foreground_tab = (widget_count_ > hidden_widget_count_) &&
585 content::GetContentClient()->renderer()->
586 RunIdleHandlerWhenWidgetsHidden();
587 if (run_in_foreground_tab) {
588 IdleHandlerInForegroundTab();
589 return;
590 }
591 #if !defined(OS_MACOSX) && defined(USE_TCMALLOC)
568 MallocExtension::instance()->ReleaseFreeMemory(); 592 MallocExtension::instance()->ReleaseFreeMemory();
569 #endif 593 #endif
570 594
571 v8::V8::IdleNotification(); 595 v8::V8::IdleNotification();
572 596
573 // Schedule next invocation. 597 // Schedule next invocation.
574 // Dampen the delay using the algorithm (if delay is in seconds): 598 // Dampen the delay using the algorithm (if delay is in seconds):
575 // delay = delay + 1 / (delay + 2) 599 // delay = delay + 1 / (delay + 2)
576 // Using floor(delay) has a dampening effect such as: 600 // Using floor(delay) has a dampening effect such as:
577 // 1s, 1, 1, 2, 2, 2, 2, 3, 3, ... 601 // 1s, 1, 1, 2, 2, 2, 2, 3, 3, ...
578 // If the delay is in milliseconds, the above formula is equivalent to: 602 // If the delay is in milliseconds, the above formula is equivalent to:
579 // delay_ms / 1000 = delay_ms / 1000 + 1 / (delay_ms / 1000 + 2) 603 // delay_ms / 1000 = delay_ms / 1000 + 1 / (delay_ms / 1000 + 2)
580 // which is equivalent to 604 // which is equivalent to
581 // delay_ms = delay_ms + 1000*1000 / (delay_ms + 2000). 605 // delay_ms = delay_ms + 1000*1000 / (delay_ms + 2000).
582 // Note that idle_notification_delay_in_ms_ would be reset to 606 // Note that idle_notification_delay_in_ms_ would be reset to
583 // kInitialIdleHandlerDelayMs in RenderThreadImpl::WidgetHidden. 607 // kInitialIdleHandlerDelayMs in RenderThreadImpl::WidgetHidden.
584 ScheduleIdleHandler(idle_notification_delay_in_ms_ + 608 ScheduleIdleHandler(idle_notification_delay_in_ms_ +
585 1000000 / (idle_notification_delay_in_ms_ + 2000)); 609 1000000 / (idle_notification_delay_in_ms_ + 2000));
586 610
587 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, IdleNotification()); 611 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, IdleNotification());
588 } 612 }
589 613
614 void RenderThreadImpl::IdleHandlerInForegroundTab() {
615 // Increase the delay in the same way as in IdleHandler,
616 // but make it periodic by reseting it once it is too big.
617 int64 new_delay_ms = idle_notification_delay_in_ms_ +
618 1000000 / (idle_notification_delay_in_ms_ + 2000);
619 if (new_delay_ms >= kLongIdleHandlerDelayMs)
620 new_delay_ms = kShortIdleHandlerDelayMs;
621
622 // Sample the CPU usage on each timer event, so that it is more accurate.
623 double cpu_usage = process_metrics_->GetCPUUsage();
624
625 if (idle_notifications_to_skip_ > 0) {
626 idle_notifications_to_skip_--;
627 } else if (cpu_usage < kIdleCPUUsageThresholdInPercents) {
628 if (v8::V8::IdleNotification()) {
629 // V8 finished collecting garbage.
630 new_delay_ms = kLongIdleHandlerDelayMs;
631 }
632 }
633
634 ScheduleIdleHandler(new_delay_ms);
635 }
636
590 int64 RenderThreadImpl::GetIdleNotificationDelayInMs() const { 637 int64 RenderThreadImpl::GetIdleNotificationDelayInMs() const {
591 return idle_notification_delay_in_ms_; 638 return idle_notification_delay_in_ms_;
592 } 639 }
593 640
594 void RenderThreadImpl::SetIdleNotificationDelayInMs( 641 void RenderThreadImpl::SetIdleNotificationDelayInMs(
595 int64 idle_notification_delay_in_ms) { 642 int64 idle_notification_delay_in_ms) {
596 idle_notification_delay_in_ms_ = idle_notification_delay_in_ms; 643 idle_notification_delay_in_ms_ = idle_notification_delay_in_ms;
597 } 644 }
598 645
646 void RenderThreadImpl::PostponeIdleNotification() {
647 idle_notifications_to_skip_ = 2;
648 }
649
599 #if defined(OS_WIN) 650 #if defined(OS_WIN)
600 void RenderThreadImpl::PreCacheFont(const LOGFONT& log_font) { 651 void RenderThreadImpl::PreCacheFont(const LOGFONT& log_font) {
601 Send(new ChildProcessHostMsg_PreCacheFont(log_font)); 652 Send(new ChildProcessHostMsg_PreCacheFont(log_font));
602 } 653 }
603 654
604 void RenderThreadImpl::ReleaseCachedFonts() { 655 void RenderThreadImpl::ReleaseCachedFonts() {
605 Send(new ChildProcessHostMsg_ReleaseCachedFonts()); 656 Send(new ChildProcessHostMsg_ReleaseCachedFonts());
606 } 657 }
607 658
608 #endif // OS_WIN 659 #endif // OS_WIN
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 847
797 scoped_refptr<base::MessageLoopProxy> 848 scoped_refptr<base::MessageLoopProxy>
798 RenderThreadImpl::GetFileThreadMessageLoopProxy() { 849 RenderThreadImpl::GetFileThreadMessageLoopProxy() {
799 DCHECK(message_loop() == MessageLoop::current()); 850 DCHECK(message_loop() == MessageLoop::current());
800 if (!file_thread_.get()) { 851 if (!file_thread_.get()) {
801 file_thread_.reset(new base::Thread("Renderer::FILE")); 852 file_thread_.reset(new base::Thread("Renderer::FILE"));
802 file_thread_->Start(); 853 file_thread_->Start();
803 } 854 }
804 return file_thread_->message_loop_proxy(); 855 return file_thread_->message_loop_proxy();
805 } 856 }
OLDNEW
« no previous file with comments | « content/renderer/render_thread_impl.h ('k') | content/renderer/render_view_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698