diff options
Diffstat (limited to 'chrome/browser/oom_priority_manager.cc')
-rw-r--r-- | chrome/browser/oom_priority_manager.cc | 176 |
1 files changed, 0 insertions, 176 deletions
diff --git a/chrome/browser/oom_priority_manager.cc b/chrome/browser/oom_priority_manager.cc deleted file mode 100644 index f841570..0000000 --- a/chrome/browser/oom_priority_manager.cc +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/oom_priority_manager.h" - -#include <list> - -#include "base/process.h" -#include "base/process_util.h" -#include "base/thread.h" -#include "build/build_config.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/renderer_host/render_process_host.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents_wrapper.h" -#include "chrome/browser/tabs/tab_strip_model.h" -#include "chrome/browser/zygote_host_linux.h" - -#if !defined(OS_CHROMEOS) -#error This file only meant to be compiled on ChromeOS -#endif - -using base::TimeDelta; -using base::TimeTicks; -using base::ProcessHandle; -using base::ProcessMetrics; - -namespace browser { - -// The default interval in seconds after which to adjust the oom_adj -// value. -#define ADJUSTMENT_INTERVAL_SECONDS 10 - -// The default interval in minutes for considering activation times -// "equal". -#define BUCKET_INTERVAL_MINUTES 10 - -OomPriorityManager::OomPriorityManager() { - StartTimer(); -} - -OomPriorityManager::~OomPriorityManager() { - StopTimer(); -} - -void OomPriorityManager::StartTimer() { - if (!timer_.IsRunning()) { - timer_.Start(TimeDelta::FromSeconds(ADJUSTMENT_INTERVAL_SECONDS), - this, - &OomPriorityManager::AdjustOomPriorities); - } -} - -void OomPriorityManager::StopTimer() { - timer_.Stop(); -} - -// Returns true if |first| is considered less desirable to be killed -// than |second|. -bool OomPriorityManager::CompareRendererStats(RendererStats first, - RendererStats second) { - // The size of the slop in comparing activation times. [This is - // allocated here to avoid static initialization at startup time.] - static const int64 kTimeBucketInterval = - TimeDelta::FromMinutes(BUCKET_INTERVAL_MINUTES).ToInternalValue(); - - // Being pinned is most important. - if (first.is_pinned != second.is_pinned) - return first.is_pinned == true; - - // We want to be a little "fuzzy" when we compare these, because - // it's not really possible for the times to be identical, but if - // the user selected two tabs at about the same time, we still want - // to take the one that uses more memory. - if (abs((first.last_selected - second.last_selected).ToInternalValue()) < - kTimeBucketInterval) - return first.last_selected < second.last_selected; - - return first.memory_used < second.memory_used; -} - -// Here we collect most of the information we need to sort the -// existing renderers in priority order, and hand out oom_adj scores -// based on that sort order. -// -// Things we need to collect on the browser thread (because -// TabStripModel isn't thread safe): -// 1) whether or not a tab is pinned -// 2) last time a tab was selected -// -// We also need to collect: -// 3) size in memory of a tab -// But we do that in DoAdjustOomPriorities on the FILE thread so that -// we avoid jank, because it accesses /proc. -void OomPriorityManager::AdjustOomPriorities() { - if (BrowserList::size() == 0) - return; - - StatsList renderer_stats; - for (BrowserList::const_iterator browser_iterator = BrowserList::begin(); - browser_iterator != BrowserList::end(); ++browser_iterator) { - Browser* browser = *browser_iterator; - const TabStripModel* model = browser->tabstrip_model(); - for (int i = 0; i < model->count(); i++) { - TabContents* contents = model->GetTabContentsAt(i)->tab_contents(); - RendererStats stats; - stats.last_selected = contents->last_selected_time(); - stats.renderer_handle = contents->GetRenderProcessHost()->GetHandle(); - stats.is_pinned = model->IsTabPinned(i); - renderer_stats.push_back(stats); - } - } - - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - NewRunnableMethod(this, &OomPriorityManager::DoAdjustOomPriorities, - renderer_stats)); -} - -void OomPriorityManager::DoAdjustOomPriorities(StatsList renderer_stats) { - for (StatsList::iterator stats_iter = renderer_stats.begin(); - stats_iter != renderer_stats.end(); ++stats_iter) { - scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics( - stats_iter->renderer_handle)); - - base::WorkingSetKBytes working_set_kbytes; - if (metrics->GetWorkingSetKBytes(&working_set_kbytes)) { - // We use the proportional set size (PSS) to calculate memory - // usage "badness" on Linux. - stats_iter->memory_used = working_set_kbytes.shared * 1024; - } else { - // and if for some reason we can't get PSS, we revert to using - // resident set size (RSS). This will be zero if the process - // has already gone away, but we can live with that, since the - // process is gone anyhow. - stats_iter->memory_used = metrics->GetWorkingSetSize(); - } - } - - // Now we sort the data we collected so that least desirable to be - // killed is first, most desirable is last. - renderer_stats.sort(OomPriorityManager::CompareRendererStats); - - // Now we assign priorities based on the sorted list. We're - // assigning priorities in the range of 5 to 10. oom_adj takes - // values from -17 to 15. Negative values are reserved for system - // processes, and we want to give some room on either side of the - // range we're using to allow for things that want to be above or - // below the renderers in priority, so 5 to 10 gives us some - // variation in priority without taking up the whole range. In the - // end, however, it's a pretty arbitrary range to use. Higher - // values are more likely to be killed by the OOM killer. We also - // remove any duplicate PIDs, leaving the most important of the - // duplicates. - const int kMinPriority = 5; - const int kMaxPriority = 10; - const int kPriorityRange = kMaxPriority - kMinPriority; - float priority_increment = - static_cast<float>(kPriorityRange) / renderer_stats.size(); - float priority = kMinPriority; - std::set<base::ProcessHandle> already_seen; - for (StatsList::iterator iterator = renderer_stats.begin(); - iterator != renderer_stats.end(); ++iterator) { - if (already_seen.find(iterator->renderer_handle) == already_seen.end()) { - already_seen.insert(iterator->renderer_handle); - Singleton<ZygoteHost>::get()->AdjustRendererOOMScore( - iterator->renderer_handle, - static_cast<int>(priority + 0.5f)); - priority += priority_increment; - } - } -} - -} // namespace browser |