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

Unified 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, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/renderer/render_thread_impl.h ('k') | content/renderer/render_view_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/render_thread_impl.cc
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 7562aec4bd25faf7d75ceb26c066df7178f0de13..50f010a7531975500f5ea51ea08351ed0223d070 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -102,6 +102,9 @@ using content::RenderProcessObserver;
namespace {
static const int64 kInitialIdleHandlerDelayMs = 1000;
+static const int64 kShortIdleHandlerDelayMs = 1000;
+static const int64 kLongIdleHandlerDelayMs = 30*1000;
+static const int kIdleCPUUsageThresholdInPercents = 3;
// Keep the global RenderThreadImpl in a TLS slot so it is impossible to access
// incorrectly from the wrong thread.
@@ -190,6 +193,15 @@ void RenderThreadImpl::Init() {
widget_count_ = 0;
hidden_widget_count_ = 0;
idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs;
+ idle_notifications_to_skip_ = 0;
+ base::ProcessHandle handle = base::GetCurrentProcessHandle();
+#if defined(OS_MACOSX)
+ process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle,
+ NULL));
+#else
+ process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle));
+#endif
+ process_metrics_->GetCPUUsage(); // Initialize CPU usage counters.
task_factory_.reset(new ScopedRunnableMethodFactory<RenderThreadImpl>(this));
appcache_dispatcher_.reset(new AppCacheDispatcher(Get()));
@@ -415,7 +427,7 @@ void RenderThreadImpl::WidgetRestored() {
return;
}
- idle_timer_.Stop();
+ ScheduleIdleHandler(kLongIdleHandlerDelayMs);
}
void RenderThreadImpl::EnsureWebKitInitialized() {
@@ -531,6 +543,11 @@ void RenderThreadImpl::EnsureWebKitInitialized() {
WebRuntimeFeatures::enableQuota(true);
FOR_EACH_OBSERVER(RenderProcessObserver, observers_, WebKitInitialized());
+
+ if (content::GetContentClient()->renderer()->
+ RunIdleHandlerWhenWidgetsHidden()) {
+ ScheduleIdleHandler(kLongIdleHandlerDelayMs);
+ }
}
void RenderThreadImpl::RecordUserMetrics(const std::string& action) {
@@ -564,7 +581,14 @@ void RenderThreadImpl::ScheduleIdleHandler(int64 initial_delay_ms) {
}
void RenderThreadImpl::IdleHandler() {
- #if !defined(OS_MACOSX) && defined(USE_TCMALLOC)
+ bool run_in_foreground_tab = (widget_count_ > hidden_widget_count_) &&
+ content::GetContentClient()->renderer()->
+ RunIdleHandlerWhenWidgetsHidden();
+ if (run_in_foreground_tab) {
+ IdleHandlerInForegroundTab();
+ return;
+ }
+#if !defined(OS_MACOSX) && defined(USE_TCMALLOC)
MallocExtension::instance()->ReleaseFreeMemory();
#endif
@@ -587,6 +611,29 @@ void RenderThreadImpl::IdleHandler() {
FOR_EACH_OBSERVER(RenderProcessObserver, observers_, IdleNotification());
}
+void RenderThreadImpl::IdleHandlerInForegroundTab() {
+ // Increase the delay in the same way as in IdleHandler,
+ // but make it periodic by reseting it once it is too big.
+ int64 new_delay_ms = idle_notification_delay_in_ms_ +
+ 1000000 / (idle_notification_delay_in_ms_ + 2000);
+ if (new_delay_ms >= kLongIdleHandlerDelayMs)
+ new_delay_ms = kShortIdleHandlerDelayMs;
+
+ // Sample the CPU usage on each timer event, so that it is more accurate.
+ double cpu_usage = process_metrics_->GetCPUUsage();
+
+ if (idle_notifications_to_skip_ > 0) {
+ idle_notifications_to_skip_--;
+ } else if (cpu_usage < kIdleCPUUsageThresholdInPercents) {
+ if (v8::V8::IdleNotification()) {
+ // V8 finished collecting garbage.
+ new_delay_ms = kLongIdleHandlerDelayMs;
+ }
+ }
+
+ ScheduleIdleHandler(new_delay_ms);
+}
+
int64 RenderThreadImpl::GetIdleNotificationDelayInMs() const {
return idle_notification_delay_in_ms_;
}
@@ -596,6 +643,10 @@ void RenderThreadImpl::SetIdleNotificationDelayInMs(
idle_notification_delay_in_ms_ = idle_notification_delay_in_ms;
}
+void RenderThreadImpl::PostponeIdleNotification() {
+ idle_notifications_to_skip_ = 2;
+}
+
#if defined(OS_WIN)
void RenderThreadImpl::PreCacheFont(const LOGFONT& log_font) {
Send(new ChildProcessHostMsg_PreCacheFont(log_font));
« 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