diff options
author | TeYuan Wang <kamewang@google.com> | 2020-12-10 15:49:53 +0800 |
---|---|---|
committer | TeYuan Wang <kamewang@google.com> | 2020-12-17 13:37:02 +0000 |
commit | 8cbada8c69d30d3bad2cc09590caf8b4659a6c64 (patch) | |
tree | 9cfea3ab7ab72007560263c9f35b24a66d8776fa /thermal | |
parent | dcee68cac1a589fc86556eec0426b3ddd2035ddd (diff) | |
download | pixel-8cbada8c69d30d3bad2cc09590caf8b4659a6c64.tar.gz |
thermal: refactor virtual sensor mechanism
Bug: 174863519
Test: slider: virtual sensor can trigger notifythrottling cb
redfin: notifythrottling cb works normally
Change-Id: Ia8855976a959b81256aff2d827bbd893e10fb5b8
Diffstat (limited to 'thermal')
-rw-r--r-- | thermal/thermal-helper.cpp | 167 | ||||
-rw-r--r-- | thermal/utils/config_parser.cpp | 79 | ||||
-rw-r--r-- | thermal/utils/config_parser.h | 31 | ||||
-rw-r--r-- | thermal/utils/thermal_files.cpp | 1 |
4 files changed, 148 insertions, 130 deletions
diff --git a/thermal/thermal-helper.cpp b/thermal/thermal-helper.cpp index 133afc6e..24b44e40 100644 --- a/thermal/thermal-helper.cpp +++ b/thermal/thermal-helper.cpp @@ -300,6 +300,17 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb) .hard_limit_request_map[limit_info_pair.first] = 0; cdev_status_map_[limit_info_pair.first][name_status_pair.first] = 0; } + + if (name_status_pair.second.virtual_sensor_info != nullptr) { + if (sensor_info_map_.count( + name_status_pair.second.virtual_sensor_info->trigger_sensor)) { + sensor_info_map_[name_status_pair.second.virtual_sensor_info->trigger_sensor] + .is_monitor = true; + } else { + LOG(FATAL) << "Could not find trigger sensor " + << name_status_pair.second.virtual_sensor_info->trigger_sensor; + } + } } auto tz_map = parseThermalPathMap(kSensorPrefix.data()); @@ -637,26 +648,22 @@ std::pair<ThrottlingSeverity, ThrottlingSeverity> ThermalHelper::getSeverityFrom bool ThermalHelper::initializeSensorMap(const std::map<std::string, std::string> &path_map) { for (const auto &sensor_info_pair : sensor_info_map_) { std::string_view sensor_name = sensor_info_pair.first; - if (sensor_info_pair.second.is_virtual_sensor) { - sensor_name = sensor_info_pair.second.trigger_sensor; + if (sensor_info_pair.second.virtual_sensor_info != nullptr) { + continue; } if (!path_map.count(sensor_name.data())) { LOG(ERROR) << "Could not find " << sensor_name << " in sysfs"; - continue; + return false; } std::string path = android::base::StringPrintf( "%s/%s", path_map.at(sensor_name.data()).c_str(), kSensorTempSuffix.data()); - if (sensor_info_pair.second.is_virtual_sensor) { - sensor_name = sensor_info_pair.first; - } + if (!thermal_sensors_.addThermalFile(sensor_name, path)) { LOG(ERROR) << "Could not add " << sensor_name << "to sensors map"; + return false; } } - if (sensor_info_map_.size() == thermal_sensors_.getNumThermalFiles()) { - return true; - } - return false; + return true; } bool ThermalHelper::initializeCoolingDevices(const std::map<std::string, std::string> &path_map) { @@ -689,7 +696,7 @@ void ThermalHelper::setMinTimeout(SensorInfo *sensor_info) { void ThermalHelper::initializeTrip(const std::map<std::string, std::string> &path_map, std::set<std::string> *monitored_sensors) { for (auto &sensor_info : sensor_info_map_) { - if (!sensor_info.second.is_monitor || sensor_info.second.is_virtual_sensor) { + if (!sensor_info.second.is_monitor || (sensor_info.second.virtual_sensor_info != nullptr)) { continue; } @@ -781,7 +788,8 @@ bool ThermalHelper::fillCurrentTemperatures(bool filterType, TemperatureType_2_0 if (filterType && name_info_pair.second.type != type) { continue; } - if (readTemperature(name_info_pair.first, &temp)) { + if (readTemperature(name_info_pair.first, &temp, nullptr, + name_info_pair.second.virtual_sensor_info != nullptr)) { ret.emplace_back(std::move(temp)); } else { LOG(ERROR) << __func__ @@ -845,60 +853,57 @@ bool ThermalHelper::fillCpuUsages(hidl_vec<CpuUsage> *cpu_usages) const { } bool ThermalHelper::checkVirtualSensor(std::string_view sensor_name, std::string *temp) const { - double mTemp = 0; - for (const auto &sensor_info_pair : sensor_info_map_) { - int idx = 0; - if (sensor_info_pair.first != sensor_name.data()) { - continue; - } - for (int i = 0; i < static_cast<int>(kCombinationCount); i++) { - if (sensor_info_pair.second.linked_sensors[i].compare("NAN") == 0) { - continue; - } - if (sensor_info_pair.second.linked_sensors[i].size() <= 0) { - continue; - } - std::string data; - idx += 1; - if (!thermal_sensors_.readThermalFile(sensor_info_pair.second.linked_sensors[i], - &data)) { - continue; - } - data = ::android::base::Trim(data); - float sensor_reading = std::stof(data); - if (std::isnan(sensor_info_pair.second.coefficients[i])) { + float temp_val = 0.0; + + const auto &sensor_info = sensor_info_map_.at(sensor_name.data()); + for (size_t i = 0; i < sensor_info.virtual_sensor_info->linked_sensors.size(); i++) { + std::string data; + const auto &linked_sensor_info = + sensor_info_map_.at(sensor_info.virtual_sensor_info->linked_sensors[i].data()); + if (linked_sensor_info.virtual_sensor_info == nullptr) { + if (!thermal_sensors_.readThermalFile( + sensor_info.virtual_sensor_info->linked_sensors[i], &data)) { continue; } - float coefficient = sensor_info_pair.second.coefficients[i]; - switch (sensor_info_pair.second.formula) { - case FormulaOption::COUNT_THRESHOLD: - if ((coefficient < 0 && sensor_reading < -coefficient) || - (coefficient >= 0 && sensor_reading >= coefficient)) - mTemp += 1; - break; - case FormulaOption::WEIGHTED_AVG: - mTemp += sensor_reading * coefficient; - break; - case FormulaOption::MAXIMUM: - if (i == 0) - mTemp = std::numeric_limits<float>::lowest(); - if (sensor_reading * coefficient > mTemp) - mTemp = sensor_reading * coefficient; - break; - case FormulaOption::MINIMUM: - if (i == 0) - mTemp = std::numeric_limits<float>::max(); - if (sensor_reading * coefficient < mTemp) - mTemp = sensor_reading * coefficient; - break; - default: - break; - } + } else if (!checkVirtualSensor(sensor_info.virtual_sensor_info->linked_sensors[i], &data)) { + return false; + } + + LOG(VERBOSE) << sensor_name.data() << "'s linked sensor " + << sensor_info.virtual_sensor_info->linked_sensors[i] << ": temp = " << data; + data = ::android::base::Trim(data); + float sensor_reading = std::stof(data); + if (std::isnan(sensor_info.virtual_sensor_info->coefficients[i])) { + return false; + } + float coefficient = sensor_info.virtual_sensor_info->coefficients[i]; + switch (sensor_info.virtual_sensor_info->formula) { + case FormulaOption::COUNT_THRESHOLD: + if ((coefficient < 0 && sensor_reading < -coefficient) || + (coefficient >= 0 && sensor_reading >= coefficient)) + temp_val += 1; + break; + case FormulaOption::WEIGHTED_AVG: + temp_val += sensor_reading * coefficient; + break; + case FormulaOption::MAXIMUM: + if (i == 0) + temp_val = std::numeric_limits<float>::lowest(); + if (sensor_reading * coefficient > temp_val) + temp_val = sensor_reading * coefficient; + break; + case FormulaOption::MINIMUM: + if (i == 0) + temp_val = std::numeric_limits<float>::max(); + if (sensor_reading * coefficient < temp_val) + temp_val = sensor_reading * coefficient; + break; + default: + break; } - *temp = std::to_string(mTemp); - return true; } - return false; + *temp = std::to_string(temp_val); + return true; } // This is called in the different thread context and will update sensor_status @@ -911,9 +916,9 @@ std::chrono::milliseconds ThermalHelper::thermalWatcherCallbackFunc( auto min_sleep_ms = std::chrono::milliseconds(std::numeric_limits<int>::max()); for (auto &name_status_pair : sensor_status_map_) { + bool force_update = false; Temperature_2_0 temp; TemperatureThreshold threshold; - bool is_virtual_sensor = false; SensorStatus &sensor_status = name_status_pair.second; const SensorInfo &sensor_info = sensor_info_map_.at(name_status_pair.first); @@ -922,26 +927,33 @@ std::chrono::milliseconds ThermalHelper::thermalWatcherCallbackFunc( continue; } - is_virtual_sensor = sensor_info.is_virtual_sensor; - - std::string uevent_sensor_name = name_status_pair.first; - if (is_virtual_sensor) { - const SensorInfo &sensor_info = sensor_info_map_.at(name_status_pair.first); - uevent_sensor_name = sensor_info.trigger_sensor; - } - // Check if the sensor need to be updated auto time_elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>( now - sensor_status.last_update_time); auto sleep_ms = (sensor_status.severity != ThrottlingSeverity::NONE) ? sensor_info.passive_delay : sensor_info.polling_delay; + + if (time_elapsed_ms > sleep_ms) { + force_update = true; + } else if (uevent_sensors.size() && + uevent_sensors.find((sensor_info.virtual_sensor_info != nullptr) + ? sensor_info.virtual_sensor_info->trigger_sensor + : name_status_pair.first) != uevent_sensors.end()) { + force_update = true; + } else if (sensor_info.virtual_sensor_info != nullptr) { + const auto trigger_sensor_status = + sensor_status_map_.at(sensor_info.virtual_sensor_info->trigger_sensor); + if (trigger_sensor_status.severity != ThrottlingSeverity::NONE) { + force_update = true; + } + } + LOG(VERBOSE) << "sensor " << name_status_pair.first << ": time_elpased=" << time_elapsed_ms.count() - << ", sleep_ms=" << sleep_ms.count(); - if ((time_elapsed_ms < sleep_ms) && - (!uevent_sensors.size() || - uevent_sensors.find(uevent_sensor_name) == uevent_sensors.end())) { + << ", sleep_ms=" << sleep_ms.count() << ", force_update = " << force_update; + + if (!force_update) { auto timeout_remaining = sleep_ms - time_elapsed_ms; if (min_sleep_ms > timeout_remaining) { min_sleep_ms = timeout_remaining; @@ -952,7 +964,8 @@ std::chrono::milliseconds ThermalHelper::thermalWatcherCallbackFunc( } std::pair<ThrottlingSeverity, ThrottlingSeverity> throtting_status; - if (!readTemperature(name_status_pair.first, &temp, &throtting_status, is_virtual_sensor)) { + if (!readTemperature(name_status_pair.first, &temp, &throtting_status, + (sensor_info.virtual_sensor_info != nullptr))) { LOG(ERROR) << __func__ << ": error reading temperature for sensor: " << name_status_pair.first; continue; @@ -983,6 +996,8 @@ std::chrono::milliseconds ThermalHelper::thermalWatcherCallbackFunc( if (sensor_status.severity != ThrottlingSeverity::NONE) { LOG(INFO) << temp.name << ": " << temp.value << " degC"; + } else { + LOG(VERBOSE) << temp.name << ": " << temp.value << " degC"; } // Start PID computation diff --git a/thermal/utils/config_parser.cpp b/thermal/utils/config_parser.cpp index 87b4c7da..d97513c8 100644 --- a/thermal/utils/config_parser.cpp +++ b/thermal/utils/config_parser.cpp @@ -203,12 +203,10 @@ std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path) hot_hysteresis.fill(0.0); std::array<float, kThrottlingSeverityCount> cold_hysteresis; cold_hysteresis.fill(0.0); - std::array<std::string, kCombinationCount> linked_sensors; - linked_sensors.fill("NAN"); - std::array<float, kCombinationCount> coefficients; - coefficients.fill(0.0); - + std::vector<std::string> linked_sensors; + std::vector<float> coefficients; std::string trigger_sensor; + FormulaOption formula = FormulaOption::COUNT_THRESHOLD; bool is_virtual_sensor = false; if (sensors[i]["VirtualSensor"].empty() || !sensors[i]["VirtualSensor"].isBool()) { @@ -303,46 +301,49 @@ std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path) if (is_virtual_sensor) { values = sensors[i]["Combination"]; - if (values.size() > kCombinationCount) { - LOG(ERROR) << "Invalid " - << "Sensor[" << name << "]'s Combination count" << values.size(); + if (values.size()) { + linked_sensors.reserve(values.size()); + for (Json::Value::ArrayIndex j = 0; j < values.size(); ++j) { + linked_sensors.emplace_back(values[j].asString()); + LOG(INFO) << "Sensor[" << name << "]'s combination[" << j + << "]: " << linked_sensors[j]; + } + } else { sensors_parsed.clear(); return sensors_parsed; - } else { - for (Json::Value::ArrayIndex j = 0; j < kCombinationCount; ++j) { - if (values[j].isString()) { - if (values[j].asString().compare("NAN") != 0) { - linked_sensors[j] = values[j].asString(); - } - } - } } + values = sensors[i]["Coefficient"]; - if (values.size() > kCombinationCount) { - LOG(ERROR) << "Invalid " - << "Sensor[" << name << "]'s Combination count" << values.size(); + if (values.size()) { + coefficients.reserve(values.size()); + for (Json::Value::ArrayIndex j = 0; j < values.size(); ++j) { + coefficients.emplace_back(getFloatFromValue(values[j])); + LOG(INFO) << "Sensor[" << name << "]'s coefficient[" << j + << "]: " << coefficients[j]; + } + } else { sensors_parsed.clear(); return sensors_parsed; - } else { - for (Json::Value::ArrayIndex j = 0; j < kCombinationCount; ++j) { - if (values[j].isString()) { - if (values[j].asString().compare("NAN") != 0) { - coefficients[j] = std::stof(values[j].asString()); - } - } else { - coefficients[j] = values[j].asFloat(); - } - } } + + if (linked_sensors.size() != coefficients.size()) { + sensors_parsed.clear(); + return sensors_parsed; + } + trigger_sensor = sensors[i]["TriggerSensor"].asString(); - if (sensors[i]["Formula"].asString().compare("COUNT_THRESHOLD") == 0) + if (sensors[i]["Formula"].asString().compare("COUNT_THRESHOLD") == 0) { formula = FormulaOption::COUNT_THRESHOLD; - else if (sensors[i]["Formula"].asString().compare("WEIGHTED_AVG") == 0) + } else if (sensors[i]["Formula"].asString().compare("WEIGHTED_AVG") == 0) { formula = FormulaOption::WEIGHTED_AVG; - else if (sensors[i]["Formula"].asString().compare("MAXIMUM") == 0) + } else if (sensors[i]["Formula"].asString().compare("MAXIMUM") == 0) { formula = FormulaOption::MAXIMUM; - else + } else if (sensors[i]["Formula"].asString().compare("MINIMUM") == 0) { formula = FormulaOption::MINIMUM; + } else { + sensors_parsed.clear(); + return sensors_parsed; + } } float vr_threshold = NAN; @@ -510,6 +511,12 @@ std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path) } } + std::unique_ptr<VirtualSensorInfo> virtual_sensor_info; + if (is_virtual_sensor) { + virtual_sensor_info.reset( + new VirtualSensorInfo{linked_sensors, coefficients, trigger_sensor, formula}); + } + std::unique_ptr<ThrottlingInfo> throttling_info(new ThrottlingInfo{ k_po, k_pu, k_i, k_d, i_max, max_alloc_power, min_alloc_power, s_power, i_cutoff, throttle_type, cdev_request, cdev_weight, limit_info}); @@ -524,14 +531,10 @@ std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path) .multiplier = multiplier, .polling_delay = polling_delay, .passive_delay = passive_delay, - .linked_sensors = linked_sensors, - .coefficients = coefficients, - .trigger_sensor = trigger_sensor, - .formula = formula, - .is_virtual_sensor = is_virtual_sensor, .send_cb = send_cb, .send_powerhint = send_powerhint, .is_monitor = is_monitor, + .virtual_sensor_info = std::move(virtual_sensor_info), .throttling_info = std::move(throttling_info), }; diff --git a/thermal/utils/config_parser.h b/thermal/utils/config_parser.h index 51224828..3b099761 100644 --- a/thermal/utils/config_parser.h +++ b/thermal/utils/config_parser.h @@ -28,13 +28,6 @@ namespace thermal { namespace V2_0 { namespace implementation { -enum FormulaOption : uint32_t { - COUNT_THRESHOLD = 0, - WEIGHTED_AVG, - MAXIMUM, - MINIMUM, -}; - using ::android::hardware::hidl_enum_range; using CoolingType_2_0 = ::android::hardware::thermal::V2_0::CoolingType; using TemperatureType_2_0 = ::android::hardware::thermal::V2_0::TemperatureType; @@ -42,12 +35,23 @@ using ::android::hardware::thermal::V2_0::ThrottlingSeverity; constexpr size_t kThrottlingSeverityCount = std::distance( hidl_enum_range<ThrottlingSeverity>().begin(), hidl_enum_range<ThrottlingSeverity>().end()); using ThrottlingArray = std::array<float, static_cast<size_t>(kThrottlingSeverityCount)>; -constexpr size_t kCombinationCount = 10; -using LinkedSensorArray = std::array<std::string, static_cast<size_t>(kCombinationCount)>; -using CoefficientArray = std::array<float, static_cast<size_t>(kCombinationCount)>; constexpr std::chrono::milliseconds kMinPollIntervalMs = std::chrono::milliseconds(2000); constexpr std::chrono::milliseconds kUeventPollTimeoutMs = std::chrono::milliseconds(300000); +enum FormulaOption : uint32_t { + COUNT_THRESHOLD = 0, + WEIGHTED_AVG, + MAXIMUM, + MINIMUM, +}; + +struct VirtualSensorInfo { + std::vector<std::string> linked_sensors; + std::vector<float> coefficients; + std::string trigger_sensor; + FormulaOption formula; +}; + enum ThrottleType : uint32_t { PID = 0, // Enabled PID power allocator LIMIT, // Enable hard limit throttling @@ -82,15 +86,10 @@ struct SensorInfo { float multiplier; std::chrono::milliseconds polling_delay; std::chrono::milliseconds passive_delay; - - LinkedSensorArray linked_sensors; - CoefficientArray coefficients; - std::string trigger_sensor; - FormulaOption formula; - bool is_virtual_sensor; bool send_cb; bool send_powerhint; bool is_monitor; + std::unique_ptr<VirtualSensorInfo> virtual_sensor_info; std::unique_ptr<ThrottlingInfo> throttling_info; }; diff --git a/thermal/utils/thermal_files.cpp b/thermal/utils/thermal_files.cpp index 45e3c4ff..6f56af98 100644 --- a/thermal/utils/thermal_files.cpp +++ b/thermal/utils/thermal_files.cpp @@ -45,6 +45,7 @@ bool ThermalFiles::readThermalFile(std::string_view thermal_name, std::string *d std::string file_path = getThermalFilePath(std::string_view(thermal_name)); *data = ""; if (file_path.empty()) { + PLOG(WARNING) << "Failed to find " << thermal_name << "'s path"; return false; } |