summaryrefslogtreecommitdiff
path: root/thermal
diff options
context:
space:
mode:
authorTeYuan Wang <kamewang@google.com>2020-12-10 15:49:53 +0800
committerTeYuan Wang <kamewang@google.com>2020-12-17 13:37:02 +0000
commit8cbada8c69d30d3bad2cc09590caf8b4659a6c64 (patch)
tree9cfea3ab7ab72007560263c9f35b24a66d8776fa /thermal
parentdcee68cac1a589fc86556eec0426b3ddd2035ddd (diff)
downloadpixel-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.cpp167
-rw-r--r--thermal/utils/config_parser.cpp79
-rw-r--r--thermal/utils/config_parser.h31
-rw-r--r--thermal/utils/thermal_files.cpp1
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;
}