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