diff --git a/powerstats/AdaptiveDvfsStateResidencyDataProvider.cpp b/powerstats/AdaptiveDvfsStateResidencyDataProvider.cpp index 28b076c..6e377aa 100644 --- a/powerstats/AdaptiveDvfsStateResidencyDataProvider.cpp +++ b/powerstats/AdaptiveDvfsStateResidencyDataProvider.cpp @@ -25,6 +25,9 @@ using android::base::Split; using android::base::Trim; +static const std::string pathSuffix = "/time_in_state"; +static const std::string stateSuffix = "MHz"; + namespace aidl { namespace android { namespace hardware { @@ -34,33 +37,35 @@ namespace stats { AdaptiveDvfsStateResidencyDataProvider::AdaptiveDvfsStateResidencyDataProvider( std::string path, uint64_t clockRate, - std::string powerEntityName, - std::string freqPath) + std::vector> powerEntities) : DvfsStateResidencyDataProvider(path, clockRate, {}) { - std::unique_ptr fp(fopen(freqPath.c_str(), "r"), fclose); - if (!fp) { - PLOG(ERROR) << __func__ << ":Failed to open file " << freqPath; - return; - } - size_t len = 0; char *line = nullptr; - std::string suffix = "MHz"; std::vector> states = {}; std::vector parts; - std::string freqStr; - while (getline(&line, &len, fp.get()) != -1) { - parts = Split(line, " "); - if (parts.size() > 0) { - freqStr = Trim(parts[0]); - states.push_back(std::make_pair( - freqStr.substr(0, freqStr.length() - 3) + suffix, - freqStr)); + for (int32_t i = 0; i < powerEntities.size(); i++) { + std::string freqPath = powerEntities[i].second + pathSuffix; + std::unique_ptr fp(fopen(freqPath.c_str(), "r"), fclose); + if (!fp) { + PLOG(ERROR) << __func__ << ":Failed to open file " << freqPath; + continue; } + + while (getline(&line, &len, fp.get()) != -1) { + parts = Split(Trim(std::string(line)), " "); + if (parts.size() > 0) { + std::string freqStr = Trim(parts[0]); + states.push_back(std::make_pair( + freqStr.substr(0, freqStr.length() - 3) + stateSuffix, + freqStr)); + } + } + + mPowerEntities.push_back({powerEntities[i].first, std::move(states)}); } - mPowerEntities.push_back({powerEntityName, std::move(states)}); + free(line); } bool AdaptiveDvfsStateResidencyDataProvider::getStateResidencies( diff --git a/powerstats/DvfsStateResidencyDataProvider.cpp b/powerstats/DvfsStateResidencyDataProvider.cpp index c7561d6..ba8bd5e 100644 --- a/powerstats/DvfsStateResidencyDataProvider.cpp +++ b/powerstats/DvfsStateResidencyDataProvider.cpp @@ -103,6 +103,10 @@ bool DvfsStateResidencyDataProvider::getStateResidencies( it = residencies->find(mPowerEntities[powerEntityIndex].powerEntityName + nameSuffix); } + // The given string is last state for each entity. + if (StartsWith(Trim(std::string(line)), "last_freq_change_time_ns:")) + it = residencies->end(); + if (it != residencies->end()) { stateId = matchState(line, mPowerEntities[powerEntityIndex]); diff --git a/powerstats/include/AdaptiveDvfsStateResidencyDataProvider.h b/powerstats/include/AdaptiveDvfsStateResidencyDataProvider.h index 661b940..5983f0b 100644 --- a/powerstats/include/AdaptiveDvfsStateResidencyDataProvider.h +++ b/powerstats/include/AdaptiveDvfsStateResidencyDataProvider.h @@ -28,14 +28,12 @@ class AdaptiveDvfsStateResidencyDataProvider : public DvfsStateResidencyDataProv /* * path - path to dvfs sysfs node. * clockRate - clock rate in KHz. - * powerEntityName - power entity name to parse. - * freqPath - path to frequency table. + * powerEntities - list of power entity pairs (name to power entity, path to frequency table) */ AdaptiveDvfsStateResidencyDataProvider( std::string path, uint64_t clockRate, - std::string powerEntityName, - std::string freqPath); + std::vector> powerEntities); ~AdaptiveDvfsStateResidencyDataProvider() = default; /*