Chromium Code Reviews| Index: chrome/browser/oom_priority_manager.cc |
| =================================================================== |
| --- chrome/browser/oom_priority_manager.cc (revision 101722) |
| +++ chrome/browser/oom_priority_manager.cc (working copy) |
| @@ -20,6 +20,7 @@ |
| #include "chrome/common/chrome_constants.h" |
| #include "content/browser/browser_thread.h" |
| #include "content/browser/renderer_host/render_process_host.h" |
| +#include "content/browser/renderer_host/render_widget_host.h" |
| #include "content/browser/tab_contents/tab_contents.h" |
| #include "content/browser/zygote_host_linux.h" |
| #include "content/common/notification_service.h" |
| @@ -43,6 +44,10 @@ |
| // "equal". |
| #define BUCKET_INTERVAL_MINUTES 10 |
| +// The default interval in milliseconds to wait before setting the score of |
| +// currently focused tab. |
| +#define FOCUSED_TAB_SCORE_ADJUST_INTERVAL_MS 500 |
| + |
| OomPriorityManager::RendererStats::RendererStats() |
| : is_pinned(false), |
| is_selected(false), |
| @@ -58,7 +63,8 @@ |
| return Singleton<OomPriorityManager>::get(); |
| } |
| -OomPriorityManager::OomPriorityManager() { |
| +OomPriorityManager::OomPriorityManager() |
| + : focused_tab_pid_(0) { |
| renderer_stats_.reserve(32); // 99% of users have < 30 tabs open |
| registrar_.Add(this, |
| content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| @@ -66,6 +72,9 @@ |
| registrar_.Add(this, |
| content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| NotificationService::AllSources()); |
| + registrar_.Add(this, |
| + content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, |
| + NotificationService::AllSources()); |
| } |
| OomPriorityManager::~OomPriorityManager() { |
| @@ -124,6 +133,19 @@ |
| return first.memory_used < second.memory_used; |
| } |
| +void OomPriorityManager::AdjustFocusedTabScore() { |
| + base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_); |
| + ZygoteHost::GetInstance()->AdjustRendererOOMScore( |
| + focused_tab_pid_, chrome::kLowestRendererOomScore); |
| + pid_to_oom_score_[focused_tab_pid_] = chrome::kLowestRendererOomScore; |
| +} |
| + |
| +void OomPriorityManager::FocusTabScoreAdjustmentTimeout() { |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + NewRunnableMethod(this, &OomPriorityManager::AdjustFocusedTabScore)); |
| +} |
| + |
| void OomPriorityManager::Observe(int type, const NotificationSource& source, |
| const NotificationDetails& details) { |
| base::ProcessHandle handle = 0; |
| @@ -135,6 +157,33 @@ |
| pid_to_oom_score_.erase(handle); |
| break; |
| } |
| + case content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED: { |
| + bool visible = *Details<bool>(details).ptr(); |
| + if (visible) { |
| + focused_tab_pid_ = |
| + Source<RenderWidgetHost>(source).ptr()->process()->GetHandle(); |
| + |
| + // If the currently focused tab already has a lower score, do not |
| + // set it. This can happen in case the newly focused tab is script |
| + // connected to the previous tab. |
| + ProcessScoreMap::iterator it; |
| + it = pid_to_oom_score_.find(focused_tab_pid_); |
| + if (it != pid_to_oom_score_.end() |
| + && it->second == chrome::kLowestRendererOomScore) |
| + break; |
|
James Cook
2011/09/20 17:08:03
break needs to be indented, or reverse the if() co
amruthraj
2011/09/21 04:25:01
Done.
|
| + |
| + // By starting a timer we guarantee that the tab is focused for certain |
| + // amount of time. Secondly, it also does not add overhead to the tab |
| + // switching time. |
| + if (focus_tab_score_adjust_timer_.IsRunning()) |
| + focus_tab_score_adjust_timer_.Reset(); |
|
James Cook
2011/09/20 17:08:03
Good idea - it won't adjust scores while tab focus
|
| + else |
| + focus_tab_score_adjust_timer_.Start(FROM_HERE, |
| + TimeDelta::FromMilliseconds(FOCUSED_TAB_SCORE_ADJUST_INTERVAL_MS), |
| + this, &OomPriorityManager::FocusTabScoreAdjustmentTimeout); |
| + } |
| + break; |
| + } |
| default: |
| NOTREACHED() << L"Received unexpected notification"; |
| break; |