Index: base/process_linux.cc |
diff --git a/base/process_linux.cc b/base/process_linux.cc |
index 14c24240e38288251d925cca4c520695bb1a0da8..9764f02a0f58c52fed32a365736ca46b57ceb8b7 100644 |
--- a/base/process_linux.cc |
+++ b/base/process_linux.cc |
@@ -7,7 +7,20 @@ |
#include <errno.h> |
#include <sys/resource.h> |
+#include "base/file_util.h" |
#include "base/logging.h" |
+#include "base/stringprintf.h" |
+ |
+#if defined(OS_CHROMEOS) |
+static bool use_cgroups = false; |
+static bool cgroups_inited = false; |
+static const char kForegroundTasks[] = |
+ "/tmp/cgroup/cpu/chrome_renderers/foreground/tasks"; |
+static const char kBackgroundTasks[] = |
+ "/tmp/cgroup/cpu/chrome_renderers/background/tasks"; |
+static FilePath foreground_tasks; |
+static FilePath background_tasks; |
+#endif |
namespace base { |
@@ -28,6 +41,53 @@ bool Process::IsProcessBackgrounded() const { |
bool Process::SetProcessBackgrounded(bool background) { |
DCHECK(process_); |
+#if defined(OS_CHROMEOS) |
+ // Check for cgroups files. ChromeOS supports these by default. It creates |
+ // a cgroup mount in /tmp/cgroup and then configures two cpu task groups, |
+ // one contains at most a single foreground renderer and the other contains |
+ // all background renderers. This allows us to limit the impact of background |
+ // renderers on foreground ones to a greater level than simple renicing. |
+ if (!cgroups_inited) { |
+ cgroups_inited = true; |
+ foreground_tasks = FilePath(kForegroundTasks); |
+ background_tasks = FilePath(kBackgroundTasks); |
+ file_util::FileSystemType foreground_type; |
+ file_util::FileSystemType background_type; |
+ use_cgroups = |
+ file_util::GetFileSystemType(foreground_tasks, &foreground_type) && |
+ file_util::GetFileSystemType(background_tasks, &background_type) && |
+ foreground_type == file_util::FILE_SYSTEM_CGROUP && |
+ background_type == file_util::FILE_SYSTEM_CGROUP; |
+ } |
+ |
+ if (use_cgroups) { |
+ if (background) { |
+ std::string pid = StringPrintf("%d", process_); |
+ if (file_util::WriteFile(background_tasks, pid.c_str(), pid.size()) > 0) { |
+ // With cgroups there's no real notion of priority as an int, but this |
+ // will ensure we only move renderers back to the foreground group |
+ // if we've ever put them in the background one. |
+ saved_priority_ = 0; |
+ return true; |
+ } else { |
+ return false; |
+ } |
+ } else { |
+ if (saved_priority_ == kUnsetProcessPriority) { |
+ // Can't restore if we were never backgrounded. |
+ return false; |
+ } |
+ std::string pid = StringPrintf("%d", process_); |
+ if (file_util::WriteFile(foreground_tasks, pid.c_str(), pid.size()) > 0) { |
+ saved_priority_ = kUnsetProcessPriority; |
+ return true; |
+ } else { |
+ return false; |
+ } |
+ } |
+ } |
+#endif // OS_CHROMEOS |
+ |
if (background) { |
// We won't be able to raise the priority if we don't have the right rlimit. |
// The limit may be adjusted in /etc/security/limits.conf for PAM systems. |