1 #ifndef ANDROID_DVR_PERFORMANCED_CPU_SET_H_ 2 #define ANDROID_DVR_PERFORMANCED_CPU_SET_H_ 3 4 #include <fcntl.h> 5 6 #include <memory> 7 #include <mutex> 8 #include <sstream> 9 #include <string> 10 #include <unordered_map> 11 #include <vector> 12 13 #include <android-base/unique_fd.h> 14 15 #include <pdx/status.h> 16 17 #include "unique_file.h" 18 19 namespace android { 20 namespace dvr { 21 22 class CpuSet { 23 public: 24 // Returns the parent group for this group, if any. This pointer is owned by 25 // the group hierarchy and is only valid as long as the hierarchy is valid. parent()26 CpuSet* parent() const { return parent_; } name()27 std::string name() const { return name_; } path()28 std::string path() const { return path_; } 29 IsRoot()30 bool IsRoot() const { return parent_ == nullptr; } 31 32 std::string GetCpuList() const; 33 34 pdx::Status<void> AttachTask(pid_t task_id) const; 35 std::vector<pid_t> GetTasks() const; 36 37 private: 38 friend class CpuSetManager; 39 40 CpuSet(CpuSet* parent, const std::string& name, base::unique_fd&& cpuset_fd); 41 42 void AddChild(std::unique_ptr<CpuSet> child); 43 44 base::unique_fd OpenPropertyFile(const std::string& name) const; 45 UniqueFile OpenPropertyFilePointer(const std::string& name) const; 46 47 base::unique_fd OpenFile(const std::string& name, int flags = O_RDONLY) const; 48 UniqueFile OpenFilePointer(const std::string& name, 49 int flags = O_RDONLY) const; 50 51 CpuSet* parent_; 52 std::string name_; 53 std::string path_; 54 base::unique_fd cpuset_fd_; 55 std::vector<std::unique_ptr<CpuSet>> children_; 56 SetPrefixEnabled(bool enabled)57 static void SetPrefixEnabled(bool enabled) { prefix_enabled_ = enabled; } 58 static bool prefix_enabled_; 59 60 CpuSet(const CpuSet&) = delete; 61 void operator=(const CpuSet&) = delete; 62 }; 63 64 class CpuSetManager { 65 public: CpuSetManager()66 CpuSetManager() {} 67 68 // Creats a CpuSet hierarchy by walking the directory tree starting at 69 // |cpuset_root|. This argument must be the path to the root cpuset for the 70 // system, which is usually /dev/cpuset. 71 void Load(const std::string& cpuset_root); 72 73 // Lookup and return a CpuSet from a cpuset path. Ownership of the pointer 74 // DOES NOT pass to the caller; the pointer remains valid as long as the 75 // CpuSet hierarchy is valid. 76 CpuSet* Lookup(const std::string& path); 77 78 // Returns a vector of all the cpusets found at initializaiton. Ownership of 79 // the pointers to CpuSets DOES NOT pass to the caller; the pointers remain 80 // valid as long as the CpuSet hierarchy is valid. 81 std::vector<CpuSet*> GetCpuSets(); 82 83 // Moves all unbound tasks from the root set into the target set. This is used 84 // to shield the system from interference from unbound kernel threads. 85 void MoveUnboundTasks(const std::string& target_set); 86 87 void DumpState(std::ostringstream& stream) const; 88 89 operator bool() const { return root_set_ != nullptr; } 90 91 private: 92 // Creates a CpuSet from a path to a cpuset cgroup directory. Recursively 93 // creates child groups for each directory found under |path|. 94 std::unique_ptr<CpuSet> Create(const std::string& path); 95 std::unique_ptr<CpuSet> Create(base::unique_fd base_fd, 96 const std::string& name, CpuSet* parent); 97 98 std::unique_ptr<CpuSet> root_set_; 99 std::unordered_map<std::string, CpuSet*> path_map_; 100 101 CpuSetManager(const CpuSetManager&) = delete; 102 void operator=(const CpuSetManager&) = delete; 103 }; 104 105 } // namespace dvr 106 } // namespace android 107 108 #endif // ANDROID_DVR_PERFORMANCED_CPU_SET_H_ 109