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)91 HintManager(sp<NodeLooperThread> nm, const std::unordered_map<std::string, Hint> &actions, 92 const std::vector<std::shared_ptr<AdpfConfig>> &adpfs) 93 : nm_(std::move(nm)), actions_(actions), adpfs_(adpfs), adpf_index_(0) {} ~HintManager()94 ~HintManager() { 95 if (nm_.get() != nullptr) nm_->Stop(); 96 } 97 98 // Return true if the sysfs manager thread is running. 99 bool IsRunning() const; 100 101 // Do hint based on hint_type which defined as PowerHint in the actions 102 // section of the JSON config. Return true with valid hint_type and also 103 // NodeLooperThread::Request succeeds; otherwise return false. 104 bool DoHint(const std::string& hint_type); 105 106 // Do hint with the override time for all actions defined for the given 107 // hint_type. Return true with valid hint_type and also 108 // NodeLooperThread::Request succeeds; otherwise return false. 109 bool DoHint(const std::string& hint_type, 110 std::chrono::milliseconds timeout_ms_override); 111 112 // End hint early. Return true with valid hint_type and also 113 // NodeLooperThread::Cancel succeeds; otherwise return false. 114 bool EndHint(const std::string& hint_type); 115 116 // Query if given hint supported. 117 bool IsHintSupported(const std::string& hint_type) const; 118 119 // Query if given hint enabled. 120 bool IsHintEnabled(const std::string &hint_type) const; 121 122 // set ADPF config by profile name. 123 bool SetAdpfProfile(const std::string &profile_name); 124 125 // get current ADPF. 126 std::shared_ptr<AdpfConfig> GetAdpfProfile() const; 127 128 // Static method to construct HintManager from the JSON config file. 129 static std::unique_ptr<HintManager> GetFromJSON( 130 const std::string& config_path, bool start = true); 131 132 // Return available hints managed by HintManager 133 std::vector<std::string> GetHints() const; 134 135 // Return stats of hints managed by HintManager 136 HintStats GetHintStats(const std::string &hint_type) const; 137 138 // Dump internal status to fd 139 void DumpToFd(int fd); 140 141 // Start thread loop 142 bool Start(); 143 144 // Singleton 145 static std::shared_ptr<HintManager> GetInstance(); 146 static std::shared_ptr<HintManager> Reload(bool start); 147 148 protected: 149 static std::vector<std::unique_ptr<Node>> ParseNodes( 150 const std::string& json_doc); 151 static std::unordered_map<std::string, Hint> ParseActions( 152 const std::string &json_doc, const std::vector<std::unique_ptr<Node>> &nodes); 153 static std::vector<std::shared_ptr<AdpfConfig>> ParseAdpfConfigs(const std::string &json_doc); 154 static bool InitHintStatus(const std::unique_ptr<HintManager> &hm); 155 156 private: 157 HintManager(HintManager const&) = delete; 158 void operator=(HintManager const&) = delete; 159 static std::shared_ptr<HintManager> mInstance; 160 161 bool ValidateHint(const std::string& hint_type) const; 162 // Helper function to update the HintStatus when DoHint 163 void DoHintStatus(const std::string &hint_type, std::chrono::milliseconds timeout_ms); 164 // Helper function to update the HintStatus when EndHint 165 void EndHintStatus(const std::string &hint_type); 166 // Helper function to take hint actions when DoHint 167 void DoHintAction(const std::string &hint_type); 168 // Helper function to take hint actions when EndHint 169 void EndHintAction(const std::string &hint_type); 170 sp<NodeLooperThread> nm_; 171 std::unordered_map<std::string, Hint> actions_; 172 std::vector<std::shared_ptr<AdpfConfig>> adpfs_; 173 uint32_t adpf_index_; 174 }; 175 176 } // namespace perfmgr 177 } // namespace android 178 179 #endif // ANDROID_LIBPERFMGR_HINTMANAGER_H_ 180