1 /*
2  * Copyright (C) 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 <queue>
20 #include <shared_mutex>
21 #include <string>
22 #include <unordered_map>
23 #include <unordered_set>
24 
25 #include "config_parser.h"
26 
27 namespace android {
28 namespace hardware {
29 namespace thermal {
30 namespace V2_0 {
31 namespace implementation {
32 
33 struct PowerSample {
34     uint64_t energy_counter;
35     uint64_t duration;
36 };
37 
38 struct ReleaseStatus {
39     int release_step;
40     int max_release_step;
41 };
42 
43 struct PowerStatus {
44     std::chrono::milliseconds time_remaining;
45     // A vector to record the queues of power sample history.
46     std::vector<std::queue<PowerSample>> power_history;
47     float last_updated_avg_power;
48 };
49 
50 using CdevReleaseStatus = std::unordered_map<std::string, ReleaseStatus>;
51 using PowerStatusMap = std::unordered_map<std::string, PowerStatus>;
52 
53 // A helper class for monitoring power rails.
54 class PowerFiles {
55   public:
56     PowerFiles() = default;
57     ~PowerFiles() = default;
58     // Disallow copy and assign.
59     PowerFiles(const PowerFiles &) = delete;
60     void operator=(const PowerFiles &) = delete;
61 
62     // Register a map for the throttling release decision of target power rail
63     // Return false if the power_rail is not supported.
64     bool registerPowerRailsToWatch(std::string_view sensor_name, std::string_view cdev_name,
65                                    const BindedCdevInfo &binded_cdev_info,
66                                    const CdevInfo &cdev_info, const PowerRailInfo &power_rail_info);
67 
68     // Find the energy source path, return false if no energy source found.
69     bool findEnergySourceToWatch(void);
70 
71     // Clear the data of energy_info_map_.
72     void clearEnergyInfoMap(void);
73 
74     // Update energy value to energy_info_map_, return false if the value is failed to update.
75     bool updateEnergyValues(void);
76 
77     bool getAveragePower(std::string_view power_rail, std::queue<PowerSample> *power_history,
78                          bool power_sample_update, float *avg_power);
79     bool computeAveragePower(const PowerRailInfo &power_rail_info, PowerStatus *power_status,
80                              bool power_sample_update, float *avg_power);
81 
82     // Update the throttling release status according to the average power, return true if power
83     // rail is updated.
84     bool throttlingReleaseUpdate(std::string_view sensor_name, std::string_view cdev_name,
85                                  const ThrottlingSeverity severity,
86                                  const std::chrono::milliseconds time_elapsed_ms,
87                                  const BindedCdevInfo &binded_cdev_info,
88                                  const PowerRailInfo &power_rail_info, bool power_sample_update,
89                                  bool severity_changed);
90 
91     // Get the throttling release status for the targer power rail which is binded in specific
92     // sensor.
93     int getReleaseStep(std::string_view sensor_name, std::string_view cdev_name);
94 
95     // Clear the data of throttling_release_map_.
96     void setPowerDataToDefault(std::string_view sensor_name);
97 
98     // Get throttling release status map
GetThrottlingReleaseMap()99     const std::unordered_map<std::string, CdevReleaseStatus> &GetThrottlingReleaseMap() const {
100         std::shared_lock<std::shared_mutex> _lock(throttling_release_map_mutex_);
101         return throttling_release_map_;
102     }
103 
104     // Get Power status map
GetPowerStatusMap()105     const std::unordered_map<std::string, PowerStatusMap> &GetPowerStatusMap() const {
106         std::shared_lock<std::shared_mutex> _lock(power_status_map_mutex_);
107         return power_status_map_;
108     }
109 
110   private:
111     // The map to record the energy info for each power rail.
112     std::unordered_map<std::string, PowerSample> energy_info_map_;
113     // The map to record the throttling release status for each thermal sensor.
114     std::unordered_map<std::string, CdevReleaseStatus> throttling_release_map_;
115     mutable std::shared_mutex throttling_release_map_mutex_;
116     // The map to record the power data for each thermal sensor.
117     std::unordered_map<std::string, PowerStatusMap> power_status_map_;
118     mutable std::shared_mutex power_status_map_mutex_;
119     // The set to store the energy source paths
120     std::unordered_set<std::string> energy_path_set_;
121 };
122 
123 }  // namespace implementation
124 }  // namespace V2_0
125 }  // namespace thermal
126 }  // namespace hardware
127 }  // namespace android
128