• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <android-base/properties.h>
20 #include <perfmgr/HintManager.h>
21 #include <utils/Mutex.h>
22 
23 #include <mutex>
24 #include <optional>
25 
26 #include "AppHintDesc.h"
27 #include "BackgroundWorker.h"
28 #include "GpuCapacityNode.h"
29 #include "SessionTaskMap.h"
30 #include "TaskRampupMultNode.h"
31 
32 namespace aidl {
33 namespace google {
34 namespace hardware {
35 namespace power {
36 namespace impl {
37 namespace pixel {
38 
39 using ::android::Thread;
40 
41 template <class HintManagerT = ::android::perfmgr::HintManager>
42 class PowerSessionManager : public Immobile {
43   public:
44     ~PowerSessionManager() = default;
45 
46     // Update the current hint info
47     void updateHintMode(const std::string &mode, bool enabled);
48     // Add and remove power hint session
49     void addPowerSession(const std::string &idString,
50                          const std::shared_ptr<AppHintDesc> &sessionDescriptor,
51                          const std::shared_ptr<AppDescriptorTrace> &sessionTrace,
52                          const std::vector<int32_t> &threadIds);
53     void removePowerSession(int64_t sessionId);
54     // Replace current threads in session with threadIds
55     void setThreadsFromPowerSession(int64_t sessionId, const std::vector<int32_t> &threadIds);
56     // Pause and resume power hint session
57     void pause(int64_t sessionId);
58     void resume(int64_t sessionId);
59 
60     void dumpToFd(int fd);
61 
62     void updateTargetWorkDuration(int64_t sessionId, AdpfVoteType voteId,
63                                   std::chrono::nanoseconds durationNs);
64 
65     // Set vote for power hint session
66     void voteSet(int64_t sessionId, AdpfVoteType voteId, int uclampMin, int uclampMax,
67                  std::chrono::steady_clock::time_point startTime,
68                  std::chrono::nanoseconds durationNs);
69     void voteSet(int64_t sessionId, AdpfVoteType voteId, Cycles capacity,
70                  std::chrono::steady_clock::time_point startTime,
71                  std::chrono::nanoseconds durationNs);
72 
73     void disableBoosts(int64_t sessionId);
74 
75     void setPreferPowerEfficiency(int64_t sessionId, bool enabled);
76 
77     void updateHboostStatistics(int64_t sessionId, SessionJankyLevel jankyLevel,
78                                 int32_t numOfFrames);
79     void updateFrameBuckets(int64_t sessionId, const FrameBuckets &lastReportedFrames);
80     bool hasValidTaskRampupMultNode();
81     void updateRampupBoostMode(int64_t sessionId, SessionJankyLevel jankyLevel,
82                                int32_t defaultRampupVal, int32_t highRampupVal);
83 
84     // Singleton
getInstance()85     static PowerSessionManager *getInstance() {
86         static PowerSessionManager instance{};
87         return &instance;
88     }
89 
90     std::optional<Frequency> gpuFrequency() const;
91 
92     void registerSession(std::shared_ptr<void> session, int64_t sessionId);
93     void unregisterSession(int64_t sessionId);
94     // Only for testing
95     void clear();
96     std::shared_ptr<void> getSession(int64_t sessionId);
97     bool getGameModeEnableState();
98 
99   private:
100     std::optional<bool> isAnyAppSessionActive();
101     const std::string kDisableBoostHintName;
102 
103     // Rewrite specific
104     mutable std::mutex mSessionTaskMapMutex;
105     SessionTaskMap mSessionTaskMap;
106     std::shared_ptr<PriorityQueueWorkerPool> mPriorityQueueWorkerPool;
107 
108     // Session timeout
109     struct EventSessionTimeout {
110         std::chrono::steady_clock::time_point timeStamp;
111         int64_t sessionId{0};
112         int voteId{0};
113     };
114     void handleEvent(const EventSessionTimeout &e);
115     TemplatePriorityQueueWorker<EventSessionTimeout> mEventSessionTimeoutWorker;
116 
117     // Calculate uclamp range
118     void applyUclampLocked(int64_t sessionId, std::chrono::steady_clock::time_point timePoint)
119             REQUIRES(mSessionTaskMapMutex);
120 
121     void applyGpuVotesLocked(int64_t sessionId, std::chrono::steady_clock::time_point timePoint)
122             REQUIRES(mSessionTaskMapMutex);
123 
124     void applyCpuAndGpuVotes(int64_t sessionId, std::chrono::steady_clock::time_point timePoint);
125     // Force a session active or in-active, helper for other methods
126     void forceSessionActive(int64_t sessionId, bool isActive);
127     std::string getSessionTaskProfile(int64_t sessionId, bool isSetProfile) const;
128     void voteRampupBoostLocked(int64_t sessionId, bool rampupBoostVote, int32_t defaultRampupVal,
129                                int32_t highRampupVal);
130 
131     // Singleton
PowerSessionManager()132     PowerSessionManager()
133         : mPriorityQueueWorkerPool(new PriorityQueueWorkerPool(1, "adpf_handler")),
134           mEventSessionTimeoutWorker([&](auto e) { handleEvent(e); }, mPriorityQueueWorkerPool),
135           mGpuCapacityNode(createGpuCapacityNode()),
136           mTaskRampupMultNode(TaskRampupMultNode::getInstance()) {}
137     PowerSessionManager(PowerSessionManager const &) = delete;
138     PowerSessionManager &operator=(PowerSessionManager const &) = delete;
139 
140     std::optional<std::unique_ptr<GpuCapacityNode>> const mGpuCapacityNode;
141 
142     std::mutex mSessionMapMutex;
143     std::unordered_map<int, std::weak_ptr<void>> mSessionMap GUARDED_BY(mSessionMapMutex);
144 
145     std::atomic<bool> mGameModeEnabled{false};
146     std::shared_ptr<TaskRampupMultNode> mTaskRampupMultNode;
147 };
148 
149 }  // namespace pixel
150 }  // namespace impl
151 }  // namespace power
152 }  // namespace hardware
153 }  // namespace google
154 }  // namespace aidl
155