blob: fcf280a56fe23657a51637ee1a5e037a55509a76 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#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
16namespace android {
17namespace dvr {
18
19class 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
61class 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_