Index: content/renderer/render_thread_impl.cc |
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc |
index ea8f8fff168d37fd0bb6fc96a5b84a62e2221ca0..19677d640b862906d32591636c596fa91f14a262 100644 |
--- a/content/renderer/render_thread_impl.cc |
+++ b/content/renderer/render_thread_impl.cc |
@@ -100,7 +100,9 @@ using WebKit::WebView; |
using content::RenderProcessObserver; |
namespace { |
-static const int64 kInitialIdleHandlerDelayMs = 1000; |
+static const int64 kLongIdleDelayMs = 30000; |
+static const int64 kShortIdleDelayMs = 1000; |
+static const int kIdleCPUUsageThresholdInPercents = 3; |
ulan
2011/11/15 19:08:53
I have chosen these values based on GeneralMixMemo
|
#if defined(TOUCH_UI) |
static const int kPopupListBoxMinimumRowHeight = 60; |
@@ -192,7 +194,14 @@ void RenderThreadImpl::Init() { |
plugin_refresh_allowed_ = true; |
widget_count_ = 0; |
hidden_widget_count_ = 0; |
- idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs; |
+ idle_delay_ms_ = kLongIdleDelayMs; |
+ 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 |
task_factory_.reset(new ScopedRunnableMethodFactory<RenderThreadImpl>(this)); |
appcache_dispatcher_.reset(new AppCacheDispatcher(Get())); |
@@ -397,25 +406,13 @@ void RenderThreadImpl::SetResourceDispatcherDelegate( |
void RenderThreadImpl::WidgetHidden() { |
DCHECK(hidden_widget_count_ < widget_count_); |
hidden_widget_count_++; |
- |
- if (!content::GetContentClient()->renderer()-> |
- RunIdleHandlerWhenWidgetsHidden()) { |
- return; |
- } |
- |
if (widget_count_ && hidden_widget_count_ == widget_count_) |
- ScheduleIdleHandler(kInitialIdleHandlerDelayMs); |
+ ResetIdleTimer(); |
} |
void RenderThreadImpl::WidgetRestored() { |
DCHECK_GT(hidden_widget_count_, 0); |
hidden_widget_count_--; |
- if (!content::GetContentClient()->renderer()-> |
- RunIdleHandlerWhenWidgetsHidden()) { |
- return; |
- } |
- |
- idle_timer_.Stop(); |
} |
void RenderThreadImpl::EnsureWebKitInitialized() { |
@@ -524,6 +521,8 @@ void RenderThreadImpl::EnsureWebKitInitialized() { |
WebRuntimeFeatures::enableQuota(true); |
FOR_EACH_OBSERVER(RenderProcessObserver, observers_, WebKitInitialized()); |
+ |
+ ScheduleIdleHandler(kLongIdleDelayMs); |
} |
void RenderThreadImpl::RecordUserMetrics(const std::string& action) { |
@@ -548,45 +547,11 @@ bool RenderThreadImpl::IsRegisteredExtension( |
return v8_extensions_.find(v8_extension_name) != v8_extensions_.end(); |
} |
-void RenderThreadImpl::ScheduleIdleHandler(int64 initial_delay_ms) { |
- idle_notification_delay_in_ms_ = initial_delay_ms; |
- idle_timer_.Stop(); |
- idle_timer_.Start(FROM_HERE, |
- base::TimeDelta::FromMilliseconds(initial_delay_ms), |
- this, &RenderThreadImpl::IdleHandler); |
-} |
- |
-void RenderThreadImpl::IdleHandler() { |
- #if !defined(OS_MACOSX) && defined(USE_TCMALLOC) |
- MallocExtension::instance()->ReleaseFreeMemory(); |
-#endif |
- |
- v8::V8::IdleNotification(); |
- |
- // Schedule next invocation. |
- // Dampen the delay using the algorithm (if delay is in seconds): |
- // delay = delay + 1 / (delay + 2) |
- // Using floor(delay) has a dampening effect such as: |
- // 1s, 1, 1, 2, 2, 2, 2, 3, 3, ... |
- // If the delay is in milliseconds, the above formula is equivalent to: |
- // delay_ms / 1000 = delay_ms / 1000 + 1 / (delay_ms / 1000 + 2) |
- // which is equivalent to |
- // delay_ms = delay_ms + 1000*1000 / (delay_ms + 2000). |
- // Note that idle_notification_delay_in_ms_ would be reset to |
- // kInitialIdleHandlerDelayMs in RenderThreadImpl::WidgetHidden. |
- ScheduleIdleHandler(idle_notification_delay_in_ms_ + |
- 1000000 / (idle_notification_delay_in_ms_ + 2000)); |
- |
- FOR_EACH_OBSERVER(RenderProcessObserver, observers_, IdleNotification()); |
-} |
- |
-int64 RenderThreadImpl::GetIdleNotificationDelayInMs() const { |
- return idle_notification_delay_in_ms_; |
-} |
- |
-void RenderThreadImpl::SetIdleNotificationDelayInMs( |
- int64 idle_notification_delay_in_ms) { |
- idle_notification_delay_in_ms_ = idle_notification_delay_in_ms; |
+void RenderThreadImpl::ResetIdleTimer() { |
+ if (idle_delay_ms_ > kShortIdleDelayMs) { |
+ idle_timer_.Stop(); |
+ ScheduleIdleHandler(kShortIdleDelayMs); |
+ } |
} |
#if defined(OS_WIN) |
@@ -623,6 +588,32 @@ void RenderThreadImpl::DoNotNotifyWebKitOfModalLoop() { |
notify_webkit_of_modal_loop_ = false; |
} |
+void RenderThreadImpl::IdleHandler() { |
+ // Dampen the delay using the algorithm (if delay is in seconds): |
+ // new_delay = delay + 1 / (delay + 2) |
+ // Using floor(delay) has a dampening effect such as: |
+ // 1s, 1, 1, 2, 2, 2, 2, 3, 3, ... |
+ // If the delay is in milliseconds, the above formula is equivalent to: |
+ // new_delay_ms / 1000 = delay_ms / 1000 + 1 / (delay_ms / 1000 + 2) |
+ // which is equivalent to |
+ // new_delay_ms = delay_ms + 1000*1000 / (delay_ms + 2000). |
+ int64 new_delay_ms = idle_delay_ms_ + 1000000 / (idle_delay_ms_ + 2000); |
+ if (process_metrics_->GetCPUUsage() < kIdleCPUUsageThresholdInPercents) { |
+ new_delay_ms = kShortIdleDelayMs; |
+ // Make sure that CPU usage was sampled for short delay, not long delay. |
+ if (idle_delay_ms_ == kShortIdleDelayMs) { |
+#if !defined(OS_MACOSX) && defined(USE_TCMALLOC) |
+ MallocExtension::instance()->ReleaseFreeMemory(); |
+#endif |
+ if (v8::V8::IdleNotification()) { |
+ // V8 finished collecting garbage. |
+ new_delay_ms = kLongIdleDelayMs; |
+ } |
+ } |
+ } |
+ ScheduleIdleHandler(new_delay_ms); |
+} |
+ |
void RenderThreadImpl::OnSetZoomLevelForCurrentURL(const GURL& url, |
double zoom_level) { |
RenderViewZoomer zoomer(url, zoom_level); |
@@ -783,6 +774,12 @@ void RenderThreadImpl::OnTempCrashWithData(const GURL& data) { |
CHECK(false); |
} |
+void RenderThreadImpl::ScheduleIdleHandler(int64 delay_ms) { |
+ idle_delay_ms_ = delay_ms; |
+ idle_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(delay_ms), |
+ this, &RenderThreadImpl::IdleHandler); |
+} |
+ |
scoped_refptr<base::MessageLoopProxy> |
RenderThreadImpl::GetFileThreadMessageLoopProxy() { |
DCHECK(message_loop() == MessageLoop::current()); |