• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 namespace android {
19 namespace dvr {
20 
21 class 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.
parent()25   CpuSet* parent() const { return parent_; }
name()26   std::string name() const { return name_; }
path()27   std::string path() const { return path_; }
28 
IsRoot()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 
SetPrefixEnabled(bool enabled)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 
63 class CpuSetManager {
64  public:
CpuSetManager()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