* from android-13.0.0_r3 * Remove audio hints while at it Signed-off-by: clarencelol <clarencekuiek@icloud.com> Signed-off-by: pix106 <sbordenave@gmail.com>
135 lines
5 KiB
C++
135 lines
5 KiB
C++
/*
|
|
* 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.
|
|
*/
|
|
|
|
#define LOG_TAG "powerhal-adaptivecpu"
|
|
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
|
|
|
#include "KernelCpuFeatureReader.h"
|
|
|
|
#include <android-base/logging.h>
|
|
#include <utils/Trace.h>
|
|
|
|
#include <ostream>
|
|
|
|
namespace aidl {
|
|
namespace google {
|
|
namespace hardware {
|
|
namespace power {
|
|
namespace impl {
|
|
namespace pixel {
|
|
|
|
constexpr std::string_view kKernelFilePath("/proc/vendor_sched/acpu_stats");
|
|
constexpr size_t kReadBufferSize = sizeof(acpu_stats) * NUM_CPU_CORES;
|
|
|
|
bool KernelCpuFeatureReader::Init() {
|
|
ATRACE_CALL();
|
|
if (!OpenStatsFile(&mStatsFile)) {
|
|
return false;
|
|
}
|
|
return ReadStats(&mPreviousStats, &mPreviousReadTime);
|
|
}
|
|
|
|
bool KernelCpuFeatureReader::GetRecentCpuFeatures(
|
|
std::array<double, NUM_CPU_POLICIES> *cpuPolicyAverageFrequencyHz,
|
|
std::array<double, NUM_CPU_CORES> *cpuCoreIdleTimesPercentage) {
|
|
ATRACE_CALL();
|
|
std::array<acpu_stats, NUM_CPU_CORES> stats;
|
|
std::chrono::nanoseconds readTime;
|
|
if (!ReadStats(&stats, &readTime)) {
|
|
return false;
|
|
}
|
|
const std::chrono::nanoseconds timeDelta = readTime - mPreviousReadTime;
|
|
|
|
for (size_t i = 0; i < NUM_CPU_POLICIES; i++) {
|
|
// acpu_stats has data per-CPU, but frequency data is equivalent for all CPUs in a policy.
|
|
// So, we only read the first CPU in each policy.
|
|
const size_t statsIdx = CPU_POLICY_INDICES[i];
|
|
if (stats[statsIdx].weighted_sum_freq < mPreviousStats[statsIdx].weighted_sum_freq) {
|
|
LOG(WARNING) << "New weighted_sum_freq is less than old: new="
|
|
<< stats[statsIdx].weighted_sum_freq
|
|
<< ", old=" << mPreviousStats[statsIdx].weighted_sum_freq;
|
|
mPreviousStats[statsIdx].weighted_sum_freq = stats[statsIdx].weighted_sum_freq;
|
|
}
|
|
(*cpuPolicyAverageFrequencyHz)[i] =
|
|
static_cast<double>(stats[statsIdx].weighted_sum_freq -
|
|
mPreviousStats[statsIdx].weighted_sum_freq) /
|
|
timeDelta.count();
|
|
}
|
|
for (size_t i = 0; i < NUM_CPU_CORES; i++) {
|
|
if (stats[i].total_idle_time_ns < mPreviousStats[i].total_idle_time_ns) {
|
|
LOG(WARNING) << "New total_idle_time_ns is less than old: new="
|
|
<< stats[i].total_idle_time_ns
|
|
<< ", old=" << mPreviousStats[i].total_idle_time_ns;
|
|
mPreviousStats[i].total_idle_time_ns = stats[i].total_idle_time_ns;
|
|
}
|
|
(*cpuCoreIdleTimesPercentage)[i] =
|
|
static_cast<double>(stats[i].total_idle_time_ns -
|
|
mPreviousStats[i].total_idle_time_ns) /
|
|
timeDelta.count();
|
|
}
|
|
|
|
mPreviousStats = stats;
|
|
mPreviousReadTime = readTime;
|
|
return true;
|
|
}
|
|
|
|
bool KernelCpuFeatureReader::OpenStatsFile(std::unique_ptr<std::istream> *file) {
|
|
ATRACE_CALL();
|
|
return mFilesystem->ReadFileStream(kKernelFilePath.data(), file);
|
|
}
|
|
|
|
bool KernelCpuFeatureReader::ReadStats(std::array<acpu_stats, NUM_CPU_CORES> *stats,
|
|
std::chrono::nanoseconds *readTime) {
|
|
ATRACE_CALL();
|
|
*readTime = mTimeSource->GetKernelTime();
|
|
if (!mFilesystem->ResetFileStream(mStatsFile)) {
|
|
return false;
|
|
}
|
|
char buffer[kReadBufferSize];
|
|
{
|
|
ATRACE_NAME("read");
|
|
if (!mStatsFile->read(buffer, kReadBufferSize).good()) {
|
|
LOG(ERROR) << "Failed to read stats file";
|
|
return false;
|
|
}
|
|
}
|
|
const size_t bytesRead = mStatsFile->gcount();
|
|
if (bytesRead != kReadBufferSize) {
|
|
LOG(ERROR) << "Didn't read full data: expected=" << kReadBufferSize
|
|
<< ", actual=" << bytesRead;
|
|
return false;
|
|
}
|
|
const auto kernelStructs = reinterpret_cast<acpu_stats *>(buffer);
|
|
std::copy(kernelStructs, kernelStructs + NUM_CPU_CORES, stats->begin());
|
|
return true;
|
|
}
|
|
|
|
void KernelCpuFeatureReader::DumpToStream(std::ostream &stream) const {
|
|
ATRACE_CALL();
|
|
stream << "CPU features from acpu_stats:\n";
|
|
for (size_t i = 0; i < NUM_CPU_CORES; i++) {
|
|
stream << "- CPU " << i << ": weighted_sum_freq=" << mPreviousStats[i].weighted_sum_freq
|
|
<< ", total_idle_time_ns=" << mPreviousStats[i].total_idle_time_ns << "\n";
|
|
}
|
|
stream << "- Last read time: " << mPreviousReadTime.count() << "ns\n";
|
|
}
|
|
|
|
} // namespace pixel
|
|
} // namespace impl
|
|
} // namespace power
|
|
} // namespace hardware
|
|
} // namespace google
|
|
} // namespace aidl
|