Merge "Add 'ro.cpuset.default' system property for default cpusets."
diff --git a/init/README.md b/init/README.md
index d3dd73a..99522b9 100644
--- a/init/README.md
+++ b/init/README.md
@@ -203,7 +203,9 @@
`writepid <file...>`
> Write the child's pid to the given files when it forks. Meant for
- cgroup/cpuset usage.
+ cgroup/cpuset usage. If no files under /dev/cpuset/ are specified, but the
+ system property 'ro.cpuset.default' is set to a non-empty cpuset name (e.g.
+ '/foreground'), then the pid is written to file /dev/cpuset/_cpuset\_name_/tasks.
`priority <priority>`
> Scheduling priority of the service process. This value has to be in range
diff --git a/init/service.cpp b/init/service.cpp
index ba901fd..35aaa56 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -630,6 +630,28 @@
std::for_each(descriptors_.begin(), descriptors_.end(),
std::bind(&DescriptorInfo::CreateAndPublish, std::placeholders::_1, scon));
+ // See if there were "writepid" instructions to write to files under /dev/cpuset/.
+ auto cpuset_predicate = [](const std::string& path) {
+ return android::base::StartsWith(path, "/dev/cpuset/");
+ };
+ auto iter = std::find_if(writepid_files_.begin(), writepid_files_.end(), cpuset_predicate);
+ if (iter == writepid_files_.end()) {
+ // There were no "writepid" instructions for cpusets, check if the system default
+ // cpuset is specified to be used for the process.
+ std::string default_cpuset = property_get("ro.cpuset.default");
+ if (!default_cpuset.empty()) {
+ // Make sure the cpuset name starts and ends with '/'.
+ // A single '/' means the 'root' cpuset.
+ if (default_cpuset.front() != '/') {
+ default_cpuset.insert(0, 1, '/');
+ }
+ if (default_cpuset.back() != '/') {
+ default_cpuset.push_back('/');
+ }
+ writepid_files_.push_back(
+ StringPrintf("/dev/cpuset%stasks", default_cpuset.c_str()));
+ }
+ }
std::string pid_str = StringPrintf("%d", getpid());
for (const auto& file : writepid_files_) {
if (!WriteStringToFile(pid_str, file)) {