1 #ifndef ANDROID_DVR_PERFORMANCED_PERFORMANCE_SERVICE_H_
2 #define ANDROID_DVR_PERFORMANCED_PERFORMANCE_SERVICE_H_
3 
4 #include <functional>
5 #include <string>
6 #include <unordered_map>
7 
8 #include <pdx/service.h>
9 
10 #include "cpu_set.h"
11 #include "task.h"
12 
13 namespace android {
14 namespace dvr {
15 
16 // PerformanceService manages compute partitions usings cpusets. Different
17 // cpusets are assigned specific purposes and performance characteristics;
18 // clients may request for threads to be moved into these cpusets to help
19 // achieve system performance goals.
20 class PerformanceService : public pdx::ServiceBase<PerformanceService> {
21  public:
22   pdx::Status<void> HandleMessage(pdx::Message& message) override;
23   bool IsInitialized() const override;
24 
25   std::string DumpState(size_t max_length) override;
26 
27  private:
28   friend BASE;
29 
30   PerformanceService();
31 
32   pdx::Status<void> OnSetSchedulerPolicy(pdx::Message& message, pid_t task_id,
33                                          const std::string& scheduler_class);
34 
35   pdx::Status<void> OnSetCpuPartition(pdx::Message& message, pid_t task_id,
36                                       const std::string& partition);
37   pdx::Status<void> OnSetSchedulerClass(pdx::Message& message, pid_t task_id,
38                                         const std::string& scheduler_class);
39   pdx::Status<std::string> OnGetCpuPartition(pdx::Message& message,
40                                              pid_t task_id);
41 
42   // Set which thread gets the vr:app:render policy. Only one thread at a time
43   // is allowed to have vr:app:render. If multiple threads are allowed
44   // vr:app:render, and those threads busy loop, the system can freeze. When
45   // SetVrAppRenderThread() is called, the thread which we had previously
46   // assigned vr:app:render will have its scheduling policy reset to default
47   // values.
48   void SetVrAppRenderThread(pid_t new_vr_app_render_thread);
49 
50   CpuSetManager cpuset_;
51 
52   int sched_fifo_min_priority_;
53   int sched_fifo_max_priority_;
54 
55   struct SchedulerPolicyConfig {
56     unsigned long timer_slack;
57     int scheduler_policy;
58     int priority;
59     std::function<bool(const pdx::Message& message, const Task& task)>
60         permission_check;
61     std::string cpuset;
62 
63     // Check the permisison of the given task to use this scheduler class. If a
64     // permission check function is not set then operations are only allowed on
65     // tasks in the sender's process.
IsAllowedSchedulerPolicyConfig66     bool IsAllowed(const pdx::Message& sender, const Task& task) const {
67       if (permission_check)
68         return permission_check(sender, task);
69       else if (!task || task.thread_group_id() != sender.GetProcessId())
70         return false;
71       else
72         return true;
73     }
74   };
75 
76   std::unordered_map<std::string, SchedulerPolicyConfig> scheduler_policies_;
77 
78   std::function<bool(const pdx::Message& message, const Task& task)>
79       partition_permission_check_;
80 
81   pid_t vr_app_render_thread_ = -1;
82 
83   PerformanceService(const PerformanceService&) = delete;
84   void operator=(const PerformanceService&) = delete;
85 };
86 
87 }  // namespace dvr
88 }  // namespace android
89 
90 #endif  // ANDROID_DVR_PERFORMANCED_PERFORMANCE_SERVICE_H_
91