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