• 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 <aidl/android/hardware/power/BnPowerHintSession.h>
20 #include <aidl/android/hardware/power/WorkDuration.h>
21 #include <utils/Looper.h>
22 #include <utils/Thread.h>
23 
24 #include <mutex>
25 #include <unordered_map>
26 
27 #include "adaptivecpu/AdaptiveCpu.h"
28 
29 namespace aidl {
30 namespace google {
31 namespace hardware {
32 namespace power {
33 namespace impl {
34 namespace pixel {
35 
36 using aidl::android::hardware::power::BnPowerHintSession;
37 using aidl::android::hardware::power::WorkDuration;
38 using ::android::Message;
39 using ::android::MessageHandler;
40 using ::android::sp;
41 using std::chrono::milliseconds;
42 using std::chrono::nanoseconds;
43 using std::chrono::steady_clock;
44 using std::chrono::time_point;
45 
46 struct AppHintDesc {
AppHintDescAppHintDesc47     AppHintDesc(int32_t tgid, int32_t uid, std::vector<int> threadIds)
48         : tgid(tgid),
49           uid(uid),
50           threadIds(std::move(threadIds)),
51           duration(0LL),
52           current_min(0),
53           is_active(true),
54           update_count(0),
55           integral_error(0),
56           previous_error(0) {}
57     std::string toString() const;
58     const int32_t tgid;
59     const int32_t uid;
60     const std::vector<int> threadIds;
61     nanoseconds duration;
62     int current_min;
63     // status
64     std::atomic<bool> is_active;
65     // pid
66     uint64_t update_count;
67     int64_t integral_error;
68     int64_t previous_error;
69 };
70 
71 class PowerHintSession : public BnPowerHintSession {
72   public:
73     explicit PowerHintSession(std::shared_ptr<AdaptiveCpu> adaptiveCpu, int32_t tgid, int32_t uid,
74                               const std::vector<int32_t> &threadIds, int64_t durationNanos);
75     ~PowerHintSession();
76     ndk::ScopedAStatus close() override;
77     ndk::ScopedAStatus pause() override;
78     ndk::ScopedAStatus resume() override;
79     ndk::ScopedAStatus updateTargetWorkDuration(int64_t targetDurationNanos) override;
80     ndk::ScopedAStatus reportActualWorkDuration(
81             const std::vector<WorkDuration> &actualDurations) override;
82     bool isActive();
83     bool isTimeout();
84     void wakeup();
85     void setStale();
86     // Is this hint session for a user application
87     bool isAppSession();
88     const std::vector<int> &getTidList() const;
89     int getUclampMin();
90     void dumpToStream(std::ostream &stream);
91 
92     void updateWorkPeriod(const std::vector<WorkDuration> &actualDurations);
93     time_point<steady_clock> getEarlyBoostTime();
94     time_point<steady_clock> getStaleTime();
95 
96   private:
97     class StaleTimerHandler : public MessageHandler {
98       public:
StaleTimerHandler(PowerHintSession * session)99         StaleTimerHandler(PowerHintSession *session)
100             : mSession(session), mIsMonitoring(false), mIsSessionDead(false) {}
101         void updateTimer();
102         void updateTimer(time_point<steady_clock> staleTime);
103         void handleMessage(const Message &message) override;
104         void setSessionDead();
105 
106       private:
107         PowerHintSession *mSession;
108         std::mutex mClosedLock;
109         std::mutex mMessageLock;
110         std::atomic<time_point<steady_clock>> mStaleTime;
111         std::atomic<bool> mIsMonitoring;
112         bool mIsSessionDead;
113     };
114 
115     class EarlyBoostHandler : public MessageHandler {
116       public:
EarlyBoostHandler(PowerHintSession * session)117         EarlyBoostHandler(PowerHintSession *session)
118             : mSession(session), mIsMonitoring(false), mIsSessionDead(false) {}
119         void updateTimer(time_point<steady_clock> boostTime);
120         void handleMessage(const Message &message) override;
121         void setSessionDead();
122 
123       private:
124         PowerHintSession *mSession;
125         std::mutex mBoostLock;
126         std::mutex mMessageLock;
127         std::atomic<time_point<steady_clock>> mBoostTime;
128         std::atomic<bool> mIsMonitoring;
129         bool mIsSessionDead;
130     };
131 
132   private:
133     void updateUniveralBoostMode();
134     int setSessionUclampMin(int32_t min);
135     void tryToSendPowerHint(std::string hint);
136     std::string getIdString() const;
137     const std::shared_ptr<AdaptiveCpu> mAdaptiveCpu;
138     AppHintDesc *mDescriptor = nullptr;
139     sp<StaleTimerHandler> mStaleTimerHandler;
140     sp<EarlyBoostHandler> mEarlyBoostHandler;
141     std::atomic<time_point<steady_clock>> mLastUpdatedTime;
142     sp<MessageHandler> mPowerManagerHandler;
143     std::mutex mSessionLock;
144     std::atomic<bool> mSessionClosed = false;
145     // These 3 variables are for earlyboost work period estimation.
146     int64_t mLastStartedTimeNs;
147     int64_t mLastDurationNs;
148     int64_t mWorkPeriodNs;
149 
150     // To cache the status of whether ADPF hints are supported.
151     std::unordered_map<std::string, std::optional<bool>> mSupportedHints;
152 };
153 
154 }  // namespace pixel
155 }  // namespace impl
156 }  // namespace power
157 }  // namespace hardware
158 }  // namespace google
159 }  // namespace aidl
160