1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "cpu_set.h" 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 34fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <log/log.h> 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <algorithm> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <iomanip> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <iostream> 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sstream> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <string> 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <android-base/file.h> 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "directory_reader.h" 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "stdio_filebuf.h" 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "task.h" 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "unique_file.h" 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace { 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconstexpr int kDirectoryFlags = O_RDONLY | O_DIRECTORY | O_CLOEXEC; 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconstexpr pid_t kKernelThreadDaemonPid = 2; 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr { 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool CpuSet::prefix_enabled_ = false; 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid CpuSetManager::Load(const std::string& cpuset_root) { 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!root_set_) 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko root_set_ = Create(cpuset_root); 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::unique_ptr<CpuSet> CpuSetManager::Create(const std::string& path) { 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko base::unique_fd root_cpuset_fd(open(path.c_str(), kDirectoryFlags)); 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (root_cpuset_fd.get() < 0) { 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("CpuSet::Create: Failed to open \"%s\": %s", path.c_str(), 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return nullptr; 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Create(std::move(root_cpuset_fd), "/", nullptr); 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::unique_ptr<CpuSet> CpuSetManager::Create(base::unique_fd base_fd, 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::string& name, 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko CpuSet* parent) { 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DirectoryReader directory(base::unique_fd(dup(base_fd))); 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!directory) { 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("CpuSet::Create: Failed to opendir %s cpuset: %s", name.c_str(), 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(directory.GetError())); 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return nullptr; 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::unique_ptr<CpuSet> group( 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko new CpuSet(parent, name, base::unique_fd(dup(base_fd)))); 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko path_map_.insert(std::make_pair(group->path(), group.get())); 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (dirent* entry = directory.Next()) { 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (entry->d_type == DT_DIR) { 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string directory_name(entry->d_name); 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (directory_name == "." || directory_name == "..") 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko continue; 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko base::unique_fd entry_fd( 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko openat(base_fd.get(), directory_name.c_str(), kDirectoryFlags)); 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (entry_fd.get() >= 0) { 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto child = 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Create(std::move(entry_fd), directory_name.c_str(), group.get()); 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (child) 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko group->AddChild(std::move(child)); 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return nullptr; 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("CpuSet::Create: Failed to openat \"%s\": %s", entry->d_name, 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return nullptr; 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return group; 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoCpuSet* CpuSetManager::Lookup(const std::string& path) { 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto search = path_map_.find(path); 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (search != path_map_.end()) 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return search->second; 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return nullptr; 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::vector<CpuSet*> CpuSetManager::GetCpuSets() { 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<CpuSet*> sets(path_map_.size()); 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (const auto& pair : path_map_) { 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sets.push_back(pair.second); 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return sets; 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::string CpuSetManager::DumpState() const { 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t max_path = 0; 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<CpuSet*> sets; 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (const auto& pair : path_map_) { 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko max_path = std::max(max_path, pair.second->path().length()); 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sets.push_back(pair.second); 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::sort(sets.begin(), sets.end(), [](const CpuSet* a, const CpuSet* b) { 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return a->path() < b->path(); 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko }); 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::ostringstream stream; 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::left; 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::setw(max_path) << "Path"; 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << " "; 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::setw(6) << "CPUs"; 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << " "; 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::setw(6) << "Tasks"; 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::endl; 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::string(max_path, '_'); 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << " "; 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::string(6, '_'); 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << " "; 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::string(6, '_'); 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::endl; 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (const auto set : sets) { 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::left; 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::setw(max_path) << set->path(); 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << " "; 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::right; 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::setw(6) << set->GetCpuList(); 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << " "; 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::setw(6) << set->GetTasks().size(); 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << std::endl; 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return stream.str(); 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid CpuSetManager::MoveUnboundTasks(const std::string& target_set) { 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto root = Lookup("/"); 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!root) { 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("CpuSetManager::MoveUnboundTasks: Failed to find root cpuset!"); 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto target = Lookup(target_set); 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!target) { 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "CpuSetManager::MoveUnboundTasks: Failed to find target cpuset \"%s\"!", 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko target_set.c_str()); 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto cpu_list = root->GetCpuList(); 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (auto task_id : root->GetTasks()) { 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Task task(task_id); 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Move only unbound kernel threads to the target cpuset. 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (task.cpus_allowed_list() == cpu_list && 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko task.parent_process_id() == kKernelThreadDaemonPid) { 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGD_IF(TRACE, 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "CpuSetManager::MoveUnboundTasks: Moving task_id=%d name=%s to " 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "target_set=%s tgid=%d ppid=%d.", 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko task_id, task.name().c_str(), target_set.c_str(), 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko task.thread_group_id(), task.parent_process_id()); 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int ret = target->AttachTask(task_id); 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGW_IF(ret < 0 && ret != -EINVAL, 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "CpuSetManager::MoveUnboundTasks: Failed to attach task_id=%d " 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "to cpuset=%s: %s", 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko task_id, target_set.c_str(), strerror(-ret)); 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGD_IF(TRACE, 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "CpuSet::MoveUnboundTasks: Skipping task_id=%d name=%s cpus=%s.", 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko task_id, task.name().c_str(), task.cpus_allowed_list().c_str()); 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoCpuSet::CpuSet(CpuSet* parent, const std::string& name, 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko base::unique_fd&& cpuset_fd) 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : parent_(parent), name_(name), cpuset_fd_(std::move(cpuset_fd)) { 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (parent_ == nullptr) 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko path_ = name_; 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else if (parent_->IsRoot()) 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko path_ = parent_->name() + name_; 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko path_ = parent_->path() + "/" + name_; 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGI("CpuSet::CpuSet: path=%s", path().c_str()); 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobase::unique_fd CpuSet::OpenPropertyFile(const std::string& name) const { 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return OpenFile(prefix_enabled_ ? "cpuset." + name : name); 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoUniqueFile CpuSet::OpenPropertyFilePointer(const std::string& name) const { 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return OpenFilePointer(prefix_enabled_ ? "cpuset." + name : name); 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobase::unique_fd CpuSet::OpenFile(const std::string& name, int flags) const { 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::string relative_path = "./" + name; 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return base::unique_fd( 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko openat(cpuset_fd_.get(), relative_path.c_str(), flags)); 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoUniqueFile CpuSet::OpenFilePointer(const std::string& name, int flags) const { 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::string relative_path = "./" + name; 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko base::unique_fd fd(openat(cpuset_fd_.get(), relative_path.c_str(), flags)); 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (fd.get() < 0) { 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("CpuSet::OpenPropertyFilePointer: Failed to open %s/%s: %s", 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko path_.c_str(), name.c_str(), strerror(errno)); 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return nullptr; 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko UniqueFile fp(fdopen(fd.release(), "r")); 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!fp) 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("CpuSet::OpenPropertyFilePointer: Failed to fdopen %s/%s: %s", 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko path_.c_str(), name.c_str(), strerror(errno)); 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return fp; 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint CpuSet::AttachTask(pid_t task_id) const { 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto file = OpenFile("tasks", O_RDWR); 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (file.get() >= 0) { 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::ostringstream stream; 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stream << task_id; 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string value = stream.str(); 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const bool ret = base::WriteStringToFd(value, file.get()); 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return !ret ? -errno : 0; 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("CpuSet::AttachTask: Failed to open %s/tasks: %s", path_.c_str(), 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -errno; 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::vector<pid_t> CpuSet::GetTasks() const { 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<pid_t> tasks; 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (auto file = OpenFilePointer("tasks")) { 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stdio_filebuf<char> filebuf(file.get()); 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::istream file_stream(&filebuf); 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (std::string line; std::getline(file_stream, line);) { 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pid_t task_id = std::strtol(line.c_str(), nullptr, 10); 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko tasks.push_back(task_id); 262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return tasks; 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::string CpuSet::GetCpuList() const { 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (auto file = OpenPropertyFilePointer("cpus")) { 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko stdio_filebuf<char> filebuf(file.get()); 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::istream file_stream(&filebuf); 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string line; 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (std::getline(file_stream, line)) 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return line; 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("CpuSet::GetCpuList: Failed to read cpu list!!!"); 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ""; 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid CpuSet::AddChild(std::unique_ptr<CpuSet> child) { 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko children_.push_back(std::move(child)); 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 288