From: Tim Zimmermann Date: Mon, 29 Apr 2024 18:44:01 +0000 (+0200) Subject: aidl: thermal: Remove dependency on pixelstats HAL X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=3f030fb04fde2c8fcbf668e0e257bead36cc9816;p=GitHub%2FLineageOS%2Fandroid_hardware_samsung.git aidl: thermal: Remove dependency on pixelstats HAL Change-Id: Ic55d976ed3c8be8c6d34e1ceb2d7a6e2e3b9c49f --- diff --git a/aidl/thermal/Android.bp b/aidl/thermal/Android.bp index f398769..e615115 100644 --- a/aidl/thermal/Android.bp +++ b/aidl/thermal/Android.bp @@ -9,7 +9,6 @@ cc_binary { "utils/thermal_files.cpp", "utils/power_files.cpp", "utils/powerhal_helper.cpp", - "utils/thermal_stats_helper.cpp", "utils/thermal_watcher.cpp", ], vendor: true, @@ -27,19 +26,13 @@ cc_binary { "libutils", "libnl", "libbinder_ndk", - "android.frameworks.stats-V2-ndk", "android.hardware.power-V1-ndk", "android.hardware.thermal-V1-ndk", "pixel-power-ext-V1-ndk", - "pixelatoms-cpp", ], static_libs: [ "libpixelstats", ], - export_shared_lib_headers: [ - "android.frameworks.stats-V2-ndk", - "pixelatoms-cpp", - ], cflags: [ "-Wall", "-Werror", diff --git a/aidl/thermal/Thermal.cpp b/aidl/thermal/Thermal.cpp index 776341d..f70cedd 100644 --- a/aidl/thermal/Thermal.cpp +++ b/aidl/thermal/Thermal.cpp @@ -30,6 +30,8 @@ namespace implementation { namespace { +using std::chrono::system_clock; + ndk::ScopedAStatus initErrorStatus() { return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_STATE, "ThermalHAL not initialized properly."); @@ -522,84 +524,6 @@ void Thermal::dumpPowerRailInfo(std::ostringstream *dump_buf) { } } -void Thermal::dumpStatsRecord(std::ostringstream *dump_buf, const StatsRecord &stats_record, - std::string_view line_prefix) { - const auto now = boot_clock::now(); - *dump_buf << line_prefix << "Time Since Last Stats Report: " - << std::chrono::duration_cast( - now - stats_record.last_stats_report_time) - .count() - << " mins" << std::endl; - *dump_buf << line_prefix << "Time in State ms: ["; - for (const auto &time_in_state : stats_record.time_in_state_ms) { - *dump_buf << time_in_state.count() << " "; - } - *dump_buf << "]" << std::endl; -} - -void Thermal::dumpThermalStats(std::ostringstream *dump_buf) { - *dump_buf << "getThermalStatsInfo:" << std::endl; - *dump_buf << " Sensor Temp Stats Info:" << std::endl; - const auto &sensor_temp_stats_map_ = thermal_helper_.GetSensorTempStatsSnapshot(); - const std::string sensor_temp_stats_line_prefix(" "); - for (const auto &sensor_temp_stats_pair : sensor_temp_stats_map_) { - *dump_buf << " Sensor Name: " << sensor_temp_stats_pair.first << std::endl; - const auto &sensor_temp_stats = sensor_temp_stats_pair.second; - *dump_buf << " Max Temp: " << sensor_temp_stats.max_temp << ", TimeStamp: " - << system_clock::to_time_t(sensor_temp_stats.max_temp_timestamp) << std::endl; - *dump_buf << " Min Temp: " << sensor_temp_stats.min_temp << ", TimeStamp: " - << system_clock::to_time_t(sensor_temp_stats.min_temp_timestamp) << std::endl; - for (const auto &stats_by_threshold : sensor_temp_stats.stats_by_custom_threshold) { - *dump_buf << " Record by Threshold: ["; - for (const auto &threshold : stats_by_threshold.thresholds) { - *dump_buf << threshold << " "; - } - *dump_buf << "]" << std::endl; - if (stats_by_threshold.logging_name.has_value()) { - *dump_buf << " Logging Name: " << stats_by_threshold.logging_name.value() - << std::endl; - } - dumpStatsRecord(dump_buf, stats_by_threshold.stats_record, - sensor_temp_stats_line_prefix); - } - - if (sensor_temp_stats.stats_by_default_threshold.has_value()) { - *dump_buf << " Record by Severity:" << std::endl; - dumpStatsRecord(dump_buf, sensor_temp_stats.stats_by_default_threshold.value(), - sensor_temp_stats_line_prefix); - } - } - *dump_buf << " Sensor Cdev Request Stats Info:" << std::endl; - const auto &sensor_cdev_request_stats_map_ = - thermal_helper_.GetSensorCoolingDeviceRequestStatsSnapshot(); - const std::string sensor_cdev_request_stats_line_prefix(" "); - for (const auto &sensor_cdev_request_stats_pair : sensor_cdev_request_stats_map_) { - *dump_buf << " Sensor Name: " << sensor_cdev_request_stats_pair.first << std::endl; - for (const auto &cdev_request_stats_pair : sensor_cdev_request_stats_pair.second) { - *dump_buf << " Cooling Device Name: " << cdev_request_stats_pair.first << std::endl; - const auto &request_stats = cdev_request_stats_pair.second; - for (const auto &stats_by_threshold : request_stats.stats_by_custom_threshold) { - *dump_buf << " Record by Threshold: ["; - for (const auto &threshold : stats_by_threshold.thresholds) { - *dump_buf << threshold << " "; - } - *dump_buf << "]" << std::endl; - if (stats_by_threshold.logging_name.has_value()) { - *dump_buf << " Logging Name: " << stats_by_threshold.logging_name.value() - << std::endl; - } - dumpStatsRecord(dump_buf, stats_by_threshold.stats_record, - sensor_cdev_request_stats_line_prefix); - } - if (request_stats.stats_by_default_threshold.has_value()) { - *dump_buf << " Record by All State" << std::endl; - dumpStatsRecord(dump_buf, request_stats.stats_by_default_threshold.value(), - sensor_cdev_request_stats_line_prefix); - } - } - } -} - void Thermal::dumpThermalData(int fd) { std::ostringstream dump_buf; @@ -729,7 +653,6 @@ void Thermal::dumpThermalData(int fd) { dumpThrottlingInfo(&dump_buf); dumpThrottlingRequestStatus(&dump_buf); dumpPowerRailInfo(&dump_buf); - dumpThermalStats(&dump_buf); { dump_buf << "getAIDLPowerHalInfo:" << std::endl; dump_buf << " Exist: " << std::boolalpha << thermal_helper_.isAidlPowerHalExist() diff --git a/aidl/thermal/Thermal.h b/aidl/thermal/Thermal.h index 74449c4..5dd5648 100644 --- a/aidl/thermal/Thermal.h +++ b/aidl/thermal/Thermal.h @@ -107,9 +107,6 @@ class Thermal : public BnThermal { void dumpThrottlingInfo(std::ostringstream *dump_buf); void dumpThrottlingRequestStatus(std::ostringstream *dump_buf); void dumpPowerRailInfo(std::ostringstream *dump_buf); - void dumpStatsRecord(std::ostringstream *dump_buf, const StatsRecord &stats_record, - std::string_view line_prefix); - void dumpThermalStats(std::ostringstream *dump_buf); void dumpThermalData(int fd); }; diff --git a/aidl/thermal/thermal-helper.cpp b/aidl/thermal/thermal-helper.cpp index d7411bc..928a7a3 100644 --- a/aidl/thermal/thermal-helper.cpp +++ b/aidl/thermal/thermal-helper.cpp @@ -140,11 +140,6 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb) ret = false; } - if (!thermal_stats_helper_.initializeStats(config, sensor_info_map_, - cooling_device_info_map_)) { - LOG(FATAL) << "Failed to initialize thermal stats"; - } - for (auto const &name_status_pair : sensor_info_map_) { sensor_status_map_[name_status_pair.first] = { .severity = ThrottlingSeverity::NONE, @@ -421,7 +416,6 @@ bool ThermalHelper::readTemperature( sensor_log << sensor_log_pair.first << ":" << sensor_log_pair.second << " "; } // Update sensor temperature time in state - thermal_stats_helper_.updateSensorTempStatsBySeverity(sensor_name, out->throttlingStatus); LOG(INFO) << sensor_name.data() << ":" << out->value << " raw data: " << sensor_log.str(); } @@ -944,8 +938,6 @@ bool ThermalHelper::readThermalSensor(std::string_view sensor_name, float *temp, sensor_status.thermal_cached.temp = *temp; sensor_status.thermal_cached.timestamp = now; } - auto real_temp = (*temp) * sensor_info.multiplier; - thermal_stats_helper_.updateSensorTempStatsByThreshold(sensor_name, real_temp); return true; } @@ -1089,7 +1081,7 @@ std::chrono::milliseconds ThermalHelper::thermalWatcherCallbackFunc( thermal_throttling_.computeCoolingDevicesRequest( name_status_pair.first, sensor_info, sensor_status.severity, - &cooling_devices_to_update, &thermal_stats_helper_); + &cooling_devices_to_update); if (min_sleep_ms > sleep_ms) { min_sleep_ms = sleep_ms; } @@ -1115,11 +1107,6 @@ std::chrono::milliseconds ThermalHelper::thermalWatcherCallbackFunc( } } - int count_failed_reporting = thermal_stats_helper_.reportStats(); - if (count_failed_reporting != 0) { - LOG(ERROR) << "Failed to report " << count_failed_reporting << " thermal stats"; - } - return min_sleep_ms; } diff --git a/aidl/thermal/thermal-helper.h b/aidl/thermal/thermal-helper.h index 3b790e3..dad4fea 100644 --- a/aidl/thermal/thermal-helper.h +++ b/aidl/thermal/thermal-helper.h @@ -33,7 +33,6 @@ #include "utils/powerhal_helper.h" #include "utils/thermal_files.h" #include "utils/thermal_info.h" -#include "utils/thermal_stats_helper.h" #include "utils/thermal_throttling.h" #include "utils/thermal_watcher.h" @@ -130,16 +129,6 @@ class ThermalHelper { return power_files_.GetPowerStatusMap(); } - // Get Thermal Stats Sensor Map - const std::unordered_map GetSensorTempStatsSnapshot() { - return thermal_stats_helper_.GetSensorTempStatsSnapshot(); - } - // Get Thermal Stats Sensor, Binded Cdev State Request Map - const std::unordered_map>> - GetSensorCoolingDeviceRequestStatsSnapshot() { - return thermal_stats_helper_.GetSensorCoolingDeviceRequestStatsSnapshot(); - } - void sendPowerExtHint(const Temperature &t); bool isAidlPowerHalExist() { return power_hal_service_.isAidlPowerHalExist(); } bool isPowerHalConnected() { return power_hal_service_.isPowerHalConnected(); } @@ -184,7 +173,6 @@ class ThermalHelper { std::unordered_map> supported_powerhint_map_; PowerHalService power_hal_service_; - ThermalStatsHelper thermal_stats_helper_; mutable std::shared_mutex sensor_status_map_mutex_; std::unordered_map sensor_status_map_; }; diff --git a/aidl/thermal/utils/thermal_stats_helper.cpp b/aidl/thermal/utils/thermal_stats_helper.cpp deleted file mode 100644 index daaaf1c..0000000 --- a/aidl/thermal/utils/thermal_stats_helper.cpp +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "thermal_stats_helper.h" - -#include -#include -#include - -#include -#include -#include - -namespace aidl { -namespace android { -namespace hardware { -namespace thermal { -namespace implementation { - -constexpr std::string_view kCustomThresholdSetSuffix("-TH-"); -constexpr std::string_view kCompressedThresholdSuffix("-CMBN-TH"); - -using aidl::android::frameworks::stats::VendorAtom; -namespace PixelAtoms = ::android::hardware::google::pixel::PixelAtoms; - -namespace { -static std::shared_ptr stats_client = nullptr; -std::shared_ptr getStatsService() { - static std::once_flag statsServiceFlag; - std::call_once(statsServiceFlag, []() { - const std::string instance = std::string() + IStats::descriptor + "/default"; - bool isStatsDeclared = AServiceManager_isDeclared(instance.c_str()); - if (!isStatsDeclared) { - LOG(ERROR) << "Stats service is not registered."; - return; - } - stats_client = IStats::fromBinder( - ndk::SpAIBinder(AServiceManager_waitForService(instance.c_str()))); - }); - return stats_client; -} - -bool isRecordByDefaultThreshold(const std::variant> - &record_by_default_threshold_all_or_name_set_, - std::string_view name) { - if (std::holds_alternative(record_by_default_threshold_all_or_name_set_)) { - return std::get(record_by_default_threshold_all_or_name_set_); - } - return std::get>(record_by_default_threshold_all_or_name_set_) - .count(name.data()); -} - -template -int calculateThresholdBucket(const std::vector &thresholds, T value) { - if (thresholds.empty()) { - LOG(VERBOSE) << "No threshold present, so bucket is " << value << " as int."; - return static_cast(value); - } - auto threshold_idx = std::upper_bound(thresholds.begin(), thresholds.end(), value); - int bucket = (threshold_idx - thresholds.begin()); - LOG(VERBOSE) << "For value: " << value << " bucket is: " << bucket; - return bucket; -} - -} // namespace - -bool ThermalStatsHelper::initializeStats( - const Json::Value &config, - const std::unordered_map &sensor_info_map_, - const std::unordered_map &cooling_device_info_map_) { - StatsConfig stats_config; - if (!ParseStatsConfig(config, sensor_info_map_, cooling_device_info_map_, &stats_config)) { - LOG(ERROR) << "Failed to parse stats config"; - return false; - } - bool is_initialized_ = - initializeSensorTempStats(stats_config.sensor_stats_info, sensor_info_map_) && - initializeSensorCdevRequestStats(stats_config.cooling_device_request_info, - sensor_info_map_, cooling_device_info_map_); - if (is_initialized_) { - last_total_stats_report_time = boot_clock::now(); - LOG(INFO) << "Thermal Stats Initialized Successfully"; - } - return is_initialized_; -} - -bool ThermalStatsHelper::initializeSensorCdevRequestStats( - const StatsInfo &request_stats_info, - const std::unordered_map &sensor_info_map_, - const std::unordered_map &cooling_device_info_map_) { - std::unique_lock _lock(sensor_cdev_request_stats_map_mutex_); - for (const auto &[sensor, sensor_info] : sensor_info_map_) { - for (const auto &binded_cdev_info_pair : - sensor_info.throttling_info->binded_cdev_info_map) { - const auto &cdev = binded_cdev_info_pair.first; - const auto &max_state = - cooling_device_info_map_.at(binded_cdev_info_pair.first).max_state; - // Record by all state - if (isRecordByDefaultThreshold( - request_stats_info.record_by_default_threshold_all_or_name_set_, cdev)) { - // if the number of states is greater / equal(as state starts from 0) than - // residency_buckets in atom combine the initial states - if (max_state >= kMaxStatsResidencyCount) { - // buckets = [max_state -kMaxStatsResidencyCount + 1, ...max_state] - // idx = [1, .. max_state - (max_state - kMaxStatsResidencyCount + 1) + 1] - // idx = [1, .. kMaxStatsResidencyCount] - const auto starting_state = max_state - kMaxStatsResidencyCount + 1; - std::vector thresholds(kMaxStatsResidencyCount); - std::iota(thresholds.begin(), thresholds.end(), starting_state); - const auto logging_name = cdev + kCompressedThresholdSuffix.data(); - ThresholdList threshold_list(logging_name, thresholds); - sensor_cdev_request_stats_map_[sensor][cdev] - .stats_by_custom_threshold.emplace_back(threshold_list); - } else { - // buckets = [0, 1, 2, 3, ...max_state] - const auto default_threshold_time_in_state_size = max_state + 1; - sensor_cdev_request_stats_map_[sensor][cdev].stats_by_default_threshold = - StatsRecord(default_threshold_time_in_state_size); - } - LOG(INFO) << "Sensor Cdev user vote stats on basis of all state initialized for [" - << sensor << "-" << cdev << "]"; - } - - // Record by custom threshold - if (request_stats_info.record_by_threshold.count(cdev)) { - for (const auto &threshold_list : request_stats_info.record_by_threshold.at(cdev)) { - // check last threshold value(which is >= number of buckets as numbers in - // threshold are strictly increasing from 0) is less than max_state - if (threshold_list.thresholds.back() >= max_state) { - LOG(ERROR) << "For sensor " << sensor << " bindedCdev: " << cdev - << "Invalid bindedCdev stats threshold: " - << threshold_list.thresholds.back() << " >= " << max_state; - sensor_cdev_request_stats_map_.clear(); - return false; - } - sensor_cdev_request_stats_map_[sensor][cdev] - .stats_by_custom_threshold.emplace_back(threshold_list); - LOG(INFO) - << "Sensor Cdev user vote stats on basis of threshold initialized for [" - << sensor << "-" << cdev << "]"; - } - } - } - } - return true; -} - -bool ThermalStatsHelper::initializeSensorTempStats( - const StatsInfo &sensor_stats_info, - const std::unordered_map &sensor_info_map_) { - std::unique_lock _lock(sensor_temp_stats_map_mutex_); - const int severity_time_in_state_size = kThrottlingSeverityCount; - for (const auto &[sensor, sensor_info] : sensor_info_map_) { - // Record by severity - if (sensor_info.is_watch && - isRecordByDefaultThreshold( - sensor_stats_info.record_by_default_threshold_all_or_name_set_, sensor)) { - // number of buckets = number of severity - sensor_temp_stats_map_[sensor].stats_by_default_threshold = - StatsRecord(severity_time_in_state_size); - LOG(INFO) << "Sensor temp stats on basis of severity initialized for [" << sensor - << "]"; - } - - // Record by custom threshold - if (sensor_stats_info.record_by_threshold.count(sensor)) { - for (const auto &threshold_list : sensor_stats_info.record_by_threshold.at(sensor)) { - sensor_temp_stats_map_[sensor].stats_by_custom_threshold.emplace_back( - threshold_list); - LOG(INFO) << "Sensor temp stats on basis of threshold initialized for [" << sensor - << "]"; - } - } - } - return true; -} - -void ThermalStatsHelper::updateStatsRecord(StatsRecord *stats_record, int new_state) { - const auto now = boot_clock::now(); - const auto cur_state_duration = std::chrono::duration_cast( - now - stats_record->cur_state_start_time); - LOG(VERBOSE) << "Adding duration " << cur_state_duration.count() - << " for cur_state: " << stats_record->cur_state << " with value: " - << stats_record->time_in_state_ms[stats_record->cur_state].count(); - // Update last record end time - stats_record->time_in_state_ms[stats_record->cur_state] += cur_state_duration; - stats_record->cur_state_start_time = now; - stats_record->cur_state = new_state; -} - -void ThermalStatsHelper::updateSensorCdevRequestStats(std::string_view sensor, - std::string_view cdev, int new_value) { - std::unique_lock _lock(sensor_cdev_request_stats_map_mutex_); - if (!sensor_cdev_request_stats_map_.count(sensor.data()) || - !sensor_cdev_request_stats_map_[sensor.data()].count(cdev.data())) { - return; - } - auto &request_stats = sensor_cdev_request_stats_map_[sensor.data()][cdev.data()]; - for (auto &stats_by_threshold : request_stats.stats_by_custom_threshold) { - int value = calculateThresholdBucket(stats_by_threshold.thresholds, new_value); - if (value != stats_by_threshold.stats_record.cur_state) { - LOG(VERBOSE) << "Updating bindedCdev stats for sensor: " << sensor.data() - << " , cooling_device: " << cdev.data() << " with new value: " << value; - updateStatsRecord(&stats_by_threshold.stats_record, value); - } - } - - if (request_stats.stats_by_default_threshold.has_value()) { - auto &stats_record = request_stats.stats_by_default_threshold.value(); - if (new_value != stats_record.cur_state) { - LOG(VERBOSE) << "Updating bindedCdev stats for sensor: " << sensor.data() - << " , cooling_device: " << cdev.data() - << " with new value: " << new_value; - updateStatsRecord(&stats_record, new_value); - } - } -} - -void ThermalStatsHelper::updateSensorTempStatsByThreshold(std::string_view sensor, - float temperature) { - std::unique_lock _lock(sensor_temp_stats_map_mutex_); - if (!sensor_temp_stats_map_.count(sensor.data())) { - return; - } - auto &sensor_temp_stats = sensor_temp_stats_map_[sensor.data()]; - for (auto &stats_by_threshold : sensor_temp_stats.stats_by_custom_threshold) { - int value = calculateThresholdBucket(stats_by_threshold.thresholds, temperature); - if (value != stats_by_threshold.stats_record.cur_state) { - LOG(VERBOSE) << "Updating sensor stats for sensor: " << sensor.data() - << " with value: " << value; - updateStatsRecord(&stats_by_threshold.stats_record, value); - } - } - if (temperature > sensor_temp_stats.max_temp) { - sensor_temp_stats.max_temp = temperature; - sensor_temp_stats.max_temp_timestamp = system_clock::now(); - } - if (temperature < sensor_temp_stats.min_temp) { - sensor_temp_stats.min_temp = temperature; - sensor_temp_stats.min_temp_timestamp = system_clock::now(); - } -} - -void ThermalStatsHelper::updateSensorTempStatsBySeverity(std::string_view sensor, - const ThrottlingSeverity &severity) { - std::unique_lock _lock(sensor_temp_stats_map_mutex_); - if (sensor_temp_stats_map_.count(sensor.data()) && - sensor_temp_stats_map_[sensor.data()].stats_by_default_threshold.has_value()) { - auto &stats_record = - sensor_temp_stats_map_[sensor.data()].stats_by_default_threshold.value(); - int value = static_cast(severity); - if (value != stats_record.cur_state) { - LOG(VERBOSE) << "Updating sensor stats for sensor: " << sensor.data() - << " with value: " << value; - updateStatsRecord(&stats_record, value); - } - } -} - -int ThermalStatsHelper::reportStats() { - const auto curTime = boot_clock::now(); - const auto since_last_total_stats_update_ms = - std::chrono::duration_cast(curTime - - last_total_stats_report_time); - LOG(VERBOSE) << "Duration from last total stats update is: " - << since_last_total_stats_update_ms.count(); - if (since_last_total_stats_update_ms < kUpdateIntervalMs) { - LOG(VERBOSE) << "Time elapsed since last update less than " << kUpdateIntervalMs.count(); - return 0; - } - - const std::shared_ptr stats_client = getStatsService(); - if (!stats_client) { - LOG(ERROR) << "Unable to get AIDL Stats service"; - return -1; - } - int count_failed_reporting = - reportAllSensorTempStats(stats_client) + reportAllSensorCdevRequestStats(stats_client); - last_total_stats_report_time = curTime; - return count_failed_reporting; -} - -int ThermalStatsHelper::reportAllSensorTempStats(const std::shared_ptr &stats_client) { - int count_failed_reporting = 0; - std::unique_lock _lock(sensor_temp_stats_map_mutex_); - for (auto &[sensor, temp_stats] : sensor_temp_stats_map_) { - for (size_t threshold_set_idx = 0; - threshold_set_idx < temp_stats.stats_by_custom_threshold.size(); threshold_set_idx++) { - auto &stats_by_threshold = temp_stats.stats_by_custom_threshold[threshold_set_idx]; - std::string sensor_name = stats_by_threshold.logging_name.value_or( - sensor + kCustomThresholdSetSuffix.data() + std::to_string(threshold_set_idx)); - if (!reportSensorTempStats(stats_client, sensor_name, temp_stats, - &stats_by_threshold.stats_record)) { - count_failed_reporting++; - } - } - if (temp_stats.stats_by_default_threshold.has_value()) { - if (!reportSensorTempStats(stats_client, sensor, temp_stats, - &temp_stats.stats_by_default_threshold.value())) { - count_failed_reporting++; - } - } - } - return count_failed_reporting; -} - -bool ThermalStatsHelper::reportSensorTempStats(const std::shared_ptr &stats_client, - std::string_view sensor, - const SensorTempStats &sensor_temp_stats, - StatsRecord *stats_record) { - LOG(VERBOSE) << "Reporting sensor stats for " << sensor; - // maintain a copy in case reporting fails - StatsRecord thermal_stats_before_reporting = *stats_record; - std::vector values(2); - values[0].set(sensor); - std::vector time_in_state_ms = processStatsRecordForReporting(stats_record); - const auto since_last_update_ms = std::chrono::duration_cast( - stats_record->cur_state_start_time - stats_record->last_stats_report_time); - values[1].set(since_last_update_ms.count()); - VendorAtomValue tmp; - for (auto &time_in_state : time_in_state_ms) { - tmp.set(time_in_state); - values.push_back(tmp); - } - auto remaining_residency_buckets_count = kMaxStatsResidencyCount - time_in_state_ms.size(); - if (remaining_residency_buckets_count > 0) { - tmp.set(0); - values.insert(values.end(), remaining_residency_buckets_count, tmp); - } - tmp.set(sensor_temp_stats.max_temp); - values.push_back(tmp); - tmp.set( - system_clock::to_time_t(sensor_temp_stats.max_temp_timestamp)); - values.push_back(tmp); - tmp.set(sensor_temp_stats.min_temp); - values.push_back(tmp); - tmp.set( - system_clock::to_time_t(sensor_temp_stats.min_temp_timestamp)); - values.push_back(tmp); - - if (!reportAtom(stats_client, PixelAtoms::Atom::kVendorTempResidencyStats, std::move(values))) { - LOG(ERROR) << "Unable to report VendorTempResidencyStats to Stats service for " - "sensor: " - << sensor; - *stats_record = restoreStatsRecordOnFailure(std::move(thermal_stats_before_reporting)); - return false; - } - // Update last time of stats reporting - stats_record->last_stats_report_time = boot_clock::now(); - return true; -} - -int ThermalStatsHelper::reportAllSensorCdevRequestStats( - const std::shared_ptr &stats_client) { - int count_failed_reporting = 0; - std::unique_lock _lock(sensor_cdev_request_stats_map_mutex_); - for (auto &[sensor, cdev_request_stats_map] : sensor_cdev_request_stats_map_) { - for (auto &[cdev, request_stats] : cdev_request_stats_map) { - for (size_t threshold_set_idx = 0; - threshold_set_idx < request_stats.stats_by_custom_threshold.size(); - threshold_set_idx++) { - auto &stats_by_threshold = - request_stats.stats_by_custom_threshold[threshold_set_idx]; - std::string cdev_name = stats_by_threshold.logging_name.value_or( - cdev + kCustomThresholdSetSuffix.data() + - std::to_string(threshold_set_idx)); - if (!reportSensorCdevRequestStats(stats_client, sensor, cdev_name, - &stats_by_threshold.stats_record)) { - count_failed_reporting++; - } - } - - if (request_stats.stats_by_default_threshold.has_value()) { - if (!reportSensorCdevRequestStats( - stats_client, sensor, cdev, - &request_stats.stats_by_default_threshold.value())) { - count_failed_reporting++; - } - } - } - } - return count_failed_reporting; -} - -bool ThermalStatsHelper::reportSensorCdevRequestStats(const std::shared_ptr &stats_client, - std::string_view sensor, - std::string_view cdev, - StatsRecord *stats_record) { - LOG(VERBOSE) << "Reporting bindedCdev stats for sensor: " << sensor - << " cooling_device: " << cdev; - // maintain a copy in case reporting fails - StatsRecord thermal_stats_before_reporting = *stats_record; - std::vector values(3); - values[0].set(sensor); - values[1].set(cdev); - std::vector time_in_state_ms = processStatsRecordForReporting(stats_record); - const auto since_last_update_ms = std::chrono::duration_cast( - stats_record->cur_state_start_time - stats_record->last_stats_report_time); - values[2].set(since_last_update_ms.count()); - VendorAtomValue tmp; - for (auto &time_in_state : time_in_state_ms) { - tmp.set(time_in_state); - values.push_back(tmp); - } - - if (!reportAtom(stats_client, PixelAtoms::Atom::kVendorSensorCoolingDeviceStats, - std::move(values))) { - LOG(ERROR) << "Unable to report VendorSensorCoolingDeviceStats to Stats " - "service for sensor: " - << sensor << " cooling_device: " << cdev; - *stats_record = restoreStatsRecordOnFailure(std::move(thermal_stats_before_reporting)); - return false; - } - // Update last time of stats reporting - stats_record->last_stats_report_time = boot_clock::now(); - return true; -} - -std::vector ThermalStatsHelper::processStatsRecordForReporting(StatsRecord *stats_record) { - // update the last unclosed entry and start new record with same state - updateStatsRecord(stats_record, stats_record->cur_state); - std::vector &time_in_state_ms = stats_record->time_in_state_ms; - // convert std::chrono::milliseconds time_in_state to int64_t vector for reporting - std::vector stats_residency(time_in_state_ms.size()); - std::transform(time_in_state_ms.begin(), time_in_state_ms.end(), stats_residency.begin(), - [](std::chrono::milliseconds time_ms) { return time_ms.count(); }); - // clear previous stats - std::fill(time_in_state_ms.begin(), time_in_state_ms.end(), std::chrono::milliseconds::zero()); - return stats_residency; -} - -bool ThermalStatsHelper::reportAtom(const std::shared_ptr &stats_client, - const int32_t &atom_id, std::vector &&values) { - LOG(VERBOSE) << "Reporting thermal stats for atom_id " << atom_id; - // Send vendor atom to IStats HAL - VendorAtom event = {.reverseDomainName = "", .atomId = atom_id, .values = std::move(values)}; - const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event); - return ret.isOk(); -} - -StatsRecord ThermalStatsHelper::restoreStatsRecordOnFailure( - StatsRecord &&stats_record_before_failure) { - stats_record_before_failure.report_fail_count += 1; - // If consecutive count of failure is high, reset stat to avoid overflow - if (stats_record_before_failure.report_fail_count >= kMaxStatsReportingFailCount) { - return StatsRecord(stats_record_before_failure.time_in_state_ms.size(), - stats_record_before_failure.cur_state); - } else { - return stats_record_before_failure; - } -} - -std::unordered_map ThermalStatsHelper::GetSensorTempStatsSnapshot() { - auto sensor_temp_stats_snapshot = sensor_temp_stats_map_; - for (auto &sensor_temp_stats_pair : sensor_temp_stats_snapshot) { - for (auto &temp_stats : sensor_temp_stats_pair.second.stats_by_custom_threshold) { - // update the last unclosed entry and start new record with same state - updateStatsRecord(&temp_stats.stats_record, temp_stats.stats_record.cur_state); - } - if (sensor_temp_stats_pair.second.stats_by_default_threshold.has_value()) { - auto &stats_by_default_threshold = - sensor_temp_stats_pair.second.stats_by_default_threshold.value(); - // update the last unclosed entry and start new record with same state - updateStatsRecord(&stats_by_default_threshold, stats_by_default_threshold.cur_state); - } - } - return sensor_temp_stats_snapshot; -} - -std::unordered_map>> -ThermalStatsHelper::GetSensorCoolingDeviceRequestStatsSnapshot() { - auto sensor_cdev_request_stats_snapshot = sensor_cdev_request_stats_map_; - for (auto &sensor_cdev_request_stats_pair : sensor_cdev_request_stats_snapshot) { - for (auto &cdev_request_stats_pair : sensor_cdev_request_stats_pair.second) { - for (auto &request_stats : cdev_request_stats_pair.second.stats_by_custom_threshold) { - // update the last unclosed entry and start new record with same state - updateStatsRecord(&request_stats.stats_record, - request_stats.stats_record.cur_state); - } - if (cdev_request_stats_pair.second.stats_by_default_threshold.has_value()) { - auto &stats_by_default_threshold = - cdev_request_stats_pair.second.stats_by_default_threshold.value(); - // update the last unclosed entry and start new record with same state - updateStatsRecord(&stats_by_default_threshold, - stats_by_default_threshold.cur_state); - } - } - } - return sensor_cdev_request_stats_snapshot; -} - -} // namespace implementation -} // namespace thermal -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/aidl/thermal/utils/thermal_stats_helper.h b/aidl/thermal/utils/thermal_stats_helper.h deleted file mode 100644 index ef2f811..0000000 --- a/aidl/thermal/utils/thermal_stats_helper.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "thermal_info.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace thermal { -namespace implementation { - -using aidl::android::frameworks::stats::IStats; -using aidl::android::frameworks::stats::VendorAtomValue; -using ::android::base::boot_clock; -using std::chrono::system_clock; -using SystemTimePoint = std::chrono::time_point; - -constexpr int kMaxStatsReportingFailCount = 3; - -struct StatsRecord { - int cur_state; /* temperature / cdev state at current time */ - boot_clock::time_point cur_state_start_time; - boot_clock::time_point last_stats_report_time = boot_clock::time_point::min(); - std::vector time_in_state_ms; /* stats array */ - int report_fail_count = 0; /* Number of times failed to report stats */ - explicit StatsRecord(const size_t &time_in_state_size, int state = 0) - : cur_state(state), - cur_state_start_time(boot_clock::now()), - last_stats_report_time(boot_clock::now()), - report_fail_count(0) { - time_in_state_ms = std::vector( - time_in_state_size, std::chrono::milliseconds::zero()); - } - StatsRecord() = default; - StatsRecord(const StatsRecord &) = default; - StatsRecord &operator=(const StatsRecord &) = default; - StatsRecord(StatsRecord &&) = default; - StatsRecord &operator=(StatsRecord &&) = default; - ~StatsRecord() = default; -}; - -template -struct StatsByThreshold { - std::vector thresholds; - std::optional logging_name; - StatsRecord stats_record; - explicit StatsByThreshold(ThresholdList threshold_list) - : thresholds(threshold_list.thresholds), logging_name(threshold_list.logging_name) { - // number of states = number of thresholds + 1 - // e.g. threshold: [30, 50, 60] - // buckets: [MIN - 30, 30 - 50, 50-60, 60-MAX] - int time_in_state_size = threshold_list.thresholds.size() + 1; - stats_record = StatsRecord(time_in_state_size); - } - StatsByThreshold() = default; - StatsByThreshold(const StatsByThreshold &) = default; - StatsByThreshold &operator=(const StatsByThreshold &) = default; - StatsByThreshold(StatsByThreshold &&) = default; - StatsByThreshold &operator=(StatsByThreshold &&) = default; - ~StatsByThreshold() = default; -}; - -template -struct ThermalStats { - std::vector> stats_by_custom_threshold; - std::optional stats_by_default_threshold; -}; - -struct SensorTempStats : ThermalStats { - float max_temp = std::numeric_limits::min(); - SystemTimePoint max_temp_timestamp = SystemTimePoint::min(); - float min_temp = std::numeric_limits::max(); - SystemTimePoint min_temp_timestamp = SystemTimePoint::min(); -}; - -class ThermalStatsHelper { - public: - ThermalStatsHelper() = default; - ~ThermalStatsHelper() = default; - // Disallow copy and assign - ThermalStatsHelper(const ThermalStatsHelper &) = delete; - void operator=(const ThermalStatsHelper &) = delete; - - bool initializeStats(const Json::Value &config, - const std::unordered_map &sensor_info_map_, - const std::unordered_map &cooling_device_info_map_); - void updateSensorCdevRequestStats(std::string_view trigger_sensor, std::string_view cdev, - int new_state); - void updateSensorTempStatsBySeverity(std::string_view sensor, - const ThrottlingSeverity &severity); - void updateSensorTempStatsByThreshold(std::string_view sensor, float temperature); - /* - * Function to report all the stats by calling all specific stats reporting function. - * Returns: - * 0, if time_elapsed < kUpdateIntervalMs or if no failure in reporting - * -1, if failed to get AIDL stats services - * >0, count represents the number of stats failed to report. - */ - int reportStats(); - // Get a snapshot of Thermal Stats Sensor Map till that point in time - std::unordered_map GetSensorTempStatsSnapshot(); - // Get a snapshot of Thermal Stats Sensor Map till that point in time - std::unordered_map>> - GetSensorCoolingDeviceRequestStatsSnapshot(); - - private: - static constexpr std::chrono::milliseconds kUpdateIntervalMs = - std::chrono::duration_cast(24h); - boot_clock::time_point last_total_stats_report_time = boot_clock::time_point::min(); - - mutable std::shared_mutex sensor_temp_stats_map_mutex_; - // Temperature stats for each sensor being watched - std::unordered_map sensor_temp_stats_map_; - mutable std::shared_mutex sensor_cdev_request_stats_map_mutex_; - // userVote request stat for the sensor to the corresponding cdev (sensor -> cdev -> - // StatsRecord) - std::unordered_map>> - sensor_cdev_request_stats_map_; - - bool initializeSensorTempStats( - const StatsInfo &sensor_stats_info, - const std::unordered_map &sensor_info_map_); - bool initializeSensorCdevRequestStats( - const StatsInfo &request_stats_info, - const std::unordered_map &sensor_info_map_, - const std::unordered_map &cooling_device_info_map_); - void updateStatsRecord(StatsRecord *stats_record, int new_state); - int reportAllSensorTempStats(const std::shared_ptr &stats_client); - bool reportSensorTempStats(const std::shared_ptr &stats_client, std::string_view sensor, - const SensorTempStats &sensor_temp_stats, StatsRecord *stats_record); - int reportAllSensorCdevRequestStats(const std::shared_ptr &stats_client); - bool reportSensorCdevRequestStats(const std::shared_ptr &stats_client, - std::string_view sensor, std::string_view cdev, - StatsRecord *stats_record); - bool reportAtom(const std::shared_ptr &stats_client, const int32_t &atom_id, - std::vector &&values); - std::vector processStatsRecordForReporting(StatsRecord *stats_record); - StatsRecord restoreStatsRecordOnFailure(StatsRecord &&stats_record_before_failure); -}; - -} // namespace implementation -} // namespace thermal -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/aidl/thermal/utils/thermal_throttling.cpp b/aidl/thermal/utils/thermal_throttling.cpp index 8aac95d..d90ed9b 100644 --- a/aidl/thermal/utils/thermal_throttling.cpp +++ b/aidl/thermal/utils/thermal_throttling.cpp @@ -658,8 +658,7 @@ void ThermalThrottling::thermalThrottlingUpdate( void ThermalThrottling::computeCoolingDevicesRequest( std::string_view sensor_name, const SensorInfo &sensor_info, - const ThrottlingSeverity curr_severity, std::vector *cooling_devices_to_update, - ThermalStatsHelper *thermal_stats_helper) { + const ThrottlingSeverity curr_severity, std::vector *cooling_devices_to_update) { int release_step = 0; std::unique_lock _lock(thermal_throttling_status_map_mutex_); @@ -726,9 +725,6 @@ void ThermalThrottling::computeCoolingDevicesRequest( cooling_devices_to_update->emplace_back(cdev_name); } cdev_request_pair.second = request_state; - // Update sensor cdev request time in state - thermal_stats_helper->updateSensorCdevRequestStats(sensor_name, cdev_name, - cdev_request_pair.second); } } } diff --git a/aidl/thermal/utils/thermal_throttling.h b/aidl/thermal/utils/thermal_throttling.h index e83ee06..01e9e60 100644 --- a/aidl/thermal/utils/thermal_throttling.h +++ b/aidl/thermal/utils/thermal_throttling.h @@ -27,7 +27,6 @@ #include "power_files.h" #include "thermal_info.h" -#include "thermal_stats_helper.h" namespace aidl { namespace android { @@ -86,8 +85,7 @@ class ThermalThrottling { // Compute the throttling target from all the sensors' request void computeCoolingDevicesRequest(std::string_view sensor_name, const SensorInfo &sensor_info, const ThrottlingSeverity curr_severity, - std::vector *cooling_devices_to_update, - ThermalStatsHelper *thermal_stats_helper); + std::vector *cooling_devices_to_update); // Get the aggregated (from all sensor) max request for a cooling device bool getCdevMaxRequest(std::string_view cdev_name, int *max_state);