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