Chromium Code Reviews| 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()); |