1 /* 2 * Copyright (C) 2017 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 specic language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_LIBPERFMGR_HINTMANAGER_H_ 18 #define ANDROID_LIBPERFMGR_HINTMANAGER_H_ 19 20 #include <android-base/thread_annotations.h> 21 22 #include <atomic> 23 #include <cstddef> 24 #include <cstdint> 25 #include <memory> 26 #include <mutex> 27 #include <set> 28 #include <string> 29 #include <unordered_map> 30 #include <utility> 31 #include <vector> 32 33 #include "perfmgr/AdpfConfig.h" 34 #include "perfmgr/NodeLooperThread.h" 35 36 namespace android { 37 namespace perfmgr { 38 39 struct HintStats { HintStatsHintStats40 HintStats() : count(0), duration_ms(0) {} 41 uint32_t count; 42 uint64_t duration_ms; 43 }; 44 45 struct HintStatus { 46 const std::chrono::milliseconds max_timeout; HintStatusHintStatus47 HintStatus() : max_timeout(std::chrono::milliseconds(0)) {} HintStatusHintStatus48 explicit HintStatus(std::chrono::milliseconds max_timeout) 49 : max_timeout(max_timeout), 50 start_time(std::chrono::steady_clock::time_point::min()), 51 end_time(std::chrono::steady_clock::time_point::min()) {} 52 std::chrono::steady_clock::time_point start_time; 53 std::chrono::steady_clock::time_point end_time; 54 struct HintStatsInternal { HintStatsInternalHintStatus::HintStatsInternal55 HintStatsInternal() : count(0), duration_ms(0) {} 56 std::atomic<uint32_t> count; 57 std::atomic<uint64_t> duration_ms; 58 } stats; 59 }; 60 61 enum class HintActionType { Node, DoHint, EndHint, MaskHint }; 62 63 struct HintAction { HintActionHintAction64 HintAction(HintActionType t, const std::string &v, const std::string &p) 65 : type(t), value(v), enable_property(p) {} 66 HintActionType type; 67 std::string value; 68 std::string enable_property; 69 }; 70 71 struct Hint { HintHint72 Hint() {} HintHint73 Hint(const Hint &obj) 74 : node_actions(obj.node_actions), 75 hint_actions(obj.hint_actions), 76 mask_requesters(obj.mask_requesters), 77 status(obj.status) {} 78 std::vector<NodeAction> node_actions; 79 std::vector<HintAction> hint_actions; 80 mutable std::mutex hint_lock; 81 std::set<std::string> mask_requesters GUARDED_BY(hint_lock); 82 std::shared_ptr<HintStatus> status GUARDED_BY(hint_lock); 83 }; 84 85 // HintManager is the external interface of the library to be used by PowerHAL 86 // to do power hints with sysfs nodes. HintManager maintains a representation of 87 // the actions that are parsed from the configuration file as a mapping from a 88 // PowerHint to the set of actions that are performed for that PowerHint. 89 class HintManager { 90 public: HintManager(sp<NodeLooperThread> nm,const std::unordered_map<std::string,Hint> & actions,const std::vector<std::shared_ptr<AdpfConfig>> & adpfs,std::optional<std::string> gpu_sysfs_config_path)91 HintManager(sp<NodeLooperThread> nm, const std::unordered_map<std::string, Hint> &actions, 92 const std::vector<std::shared_ptr<AdpfConfig>> &adpfs, 93 std::optional<std::string> gpu_sysfs_config_path) 94 : nm_(std::move(nm)), 95 actions_(actions), 96 adpfs_(adpfs), 97 adpf_index_(0), 98 gpu_sysfs_config_path_(gpu_sysfs_config_path) {} ~HintManager()99 ~HintManager() { 100 if (nm_.get() != nullptr) nm_->Stop(); 101 } 102 103 // Return true if the sysfs manager thread is running. 104 bool IsRunning() const; 105 106 // Do hint based on hint_type which defined as PowerHint in the actions 107 // section of the JSON config. Return true with valid hint_type and also 108 // NodeLooperThread::Request succeeds; otherwise return false. 109 bool DoHint(const std::string &hint_type); 110 111 // Do hint with the override time for all actions defined for the given 112 // hint_type. Return true with valid hint_type and also 113 // NodeLooperThread::Request succeeds; otherwise return false. 114 bool DoHint(const std::string &hint_type, std::chrono::milliseconds timeout_ms_override); 115 116 // End hint early. Return true with valid hint_type and also 117 // NodeLooperThread::Cancel succeeds; otherwise return false. 118 bool EndHint(const std::string &hint_type); 119 120 // Query if given hint supported. 121 bool IsHintSupported(const std::string &hint_type) const; 122 123 // Query if given hint enabled. 124 bool IsHintEnabled(const std::string &hint_type) const; 125 126 // set ADPF config by profile name. 127 bool SetAdpfProfile(const std::string &profile_name); 128 129 std::optional<std::string> gpu_sysfs_config_path() const; 130 131 // get current ADPF. 132 std::shared_ptr<AdpfConfig> GetAdpfProfile() const; 133 134 // Query if given AdpfProfile supported. 135 bool IsAdpfProfileSupported(const std::string &name) const; 136 137 // Static method to construct the global HintManager from the JSON config file. 138 static HintManager *GetFromJSON(const std::string &config_path, bool start = true); 139 140 // Return available hints managed by HintManager 141 std::vector<std::string> GetHints() const; 142 143 // Return stats of hints managed by HintManager 144 HintStats GetHintStats(const std::string &hint_type) const; 145 146 // Dump internal status to fd 147 void DumpToFd(int fd); 148 149 // Start thread loop 150 bool Start(); 151 152 // Singleton 153 static HintManager *GetInstance(); 154 155 protected: 156 static std::vector<std::unique_ptr<Node>> ParseNodes( 157 const std::string& json_doc); 158 static std::unordered_map<std::string, Hint> ParseActions( 159 const std::string &json_doc, const std::vector<std::unique_ptr<Node>> &nodes); 160 static std::vector<std::shared_ptr<AdpfConfig>> ParseAdpfConfigs(const std::string &json_doc); 161 static bool InitHintStatus(const std::unique_ptr<HintManager> &hm); 162 163 static void Reload(bool start); 164 HintManager(HintManager const&) = delete; 165 HintManager &operator=(HintManager const &) = delete; 166 167 bool ValidateHint(const std::string& hint_type) const; 168 // Helper function to update the HintStatus when DoHint 169 void DoHintStatus(const std::string &hint_type, std::chrono::milliseconds timeout_ms); 170 // Helper function to update the HintStatus when EndHint 171 void EndHintStatus(const std::string &hint_type); 172 // Helper function to take hint actions when DoHint 173 void DoHintAction(const std::string &hint_type); 174 // Helper function to take hint actions when EndHint 175 void EndHintAction(const std::string &hint_type); 176 sp<NodeLooperThread> nm_; 177 std::unordered_map<std::string, Hint> actions_; 178 std::vector<std::shared_ptr<AdpfConfig>> adpfs_; 179 uint32_t adpf_index_; 180 std::optional<std::string> gpu_sysfs_config_path_; 181 182 static std::unique_ptr<HintManager> sInstance; 183 }; 184 185 } // namespace perfmgr 186 } // namespace android 187 188 #endif // ANDROID_LIBPERFMGR_HINTMANAGER_H_ 189