#ifndef ANDROID_DVR_PERFORMANCED_CPU_SET_H_ #define ANDROID_DVR_PERFORMANCED_CPU_SET_H_ #include <fcntl.h> #include <memory> #include <mutex> #include <string> #include <unordered_map> #include <vector> #include <android-base/unique_fd.h> #include "unique_file.h" namespace android { namespace dvr { class CpuSet { public: // Returns the parent group for this group, if any. This pointer is owned by // the group hierarchy and is only valid as long as the hierarchy is valid. CpuSet* parent() const { return parent_; } std::string name() const { return name_; } std::string path() const { return path_; } bool IsRoot() const { return parent_ == nullptr; } std::string GetCpuList() const; int AttachTask(pid_t task_id) const; std::vector<pid_t> GetTasks() const; private: friend class CpuSetManager; CpuSet(CpuSet* parent, const std::string& name, base::unique_fd&& cpuset_fd); void AddChild(std::unique_ptr<CpuSet> child); base::unique_fd OpenPropertyFile(const std::string& name) const; UniqueFile OpenPropertyFilePointer(const std::string& name) const; base::unique_fd OpenFile(const std::string& name, int flags = O_RDONLY) const; UniqueFile OpenFilePointer(const std::string& name, int flags = O_RDONLY) const; CpuSet* parent_; std::string name_; std::string path_; base::unique_fd cpuset_fd_; std::vector<std::unique_ptr<CpuSet>> children_; static void SetPrefixEnabled(bool enabled) { prefix_enabled_ = enabled; } static bool prefix_enabled_; CpuSet(const CpuSet&) = delete; void operator=(const CpuSet&) = delete; }; class CpuSetManager { public: CpuSetManager() {} // Creats a CpuSet hierarchy by walking the directory tree starting at // |cpuset_root|. This argument must be the path to the root cpuset for the // system, which is usually /dev/cpuset. void Load(const std::string& cpuset_root); // Lookup and return a CpuSet from a cpuset path. Ownership of the pointer // DOES NOT pass to the caller; the pointer remains valid as long as the // CpuSet hierarchy is valid. CpuSet* Lookup(const std::string& path); // Returns a vector of all the cpusets found at initializaiton. Ownership of // the pointers to CpuSets DOES NOT pass to the caller; the pointers remain // valid as long as the CpuSet hierarchy is valid. std::vector<CpuSet*> GetCpuSets(); // Moves all unbound tasks from the root set into the target set. This is used // to shield the system from interference from unbound kernel threads. void MoveUnboundTasks(const std::string& target_set); std::string DumpState() const; operator bool() const { return root_set_ != nullptr; } private: // Creates a CpuSet from a path to a cpuset cgroup directory. Recursively // creates child groups for each directory found under |path|. std::unique_ptr<CpuSet> Create(const std::string& path); std::unique_ptr<CpuSet> Create(base::unique_fd base_fd, const std::string& name, CpuSet* parent); std::unique_ptr<CpuSet> root_set_; std::unordered_map<std::string, CpuSet*> path_map_; CpuSetManager(const CpuSetManager&) = delete; void operator=(const CpuSetManager&) = delete; }; } // namespace dvr } // namespace android #endif // ANDROID_DVR_PERFORMANCED_CPU_SET_H_