summaryrefslogtreecommitdiff
path: root/pwrstats_util
diff options
context:
space:
mode:
authorBenjamin Schwartz <bsschwar@google.com>2019-07-26 09:47:57 -0700
committerBenjamin Schwartz <bsschwar@google.com>2019-07-30 14:12:06 -0700
commitd14a96e65cc9e72fb40d7982d9d142d2328530a6 (patch)
treed6dd81ca4441afd404918db313966daedf548dab /pwrstats_util
parentca7da7ba52a35d57603dff299df37800d312c423 (diff)
pwrstats_util: refactor
In order to be able to add new tool options and stats that get collected, pwrstats_util needs to be refactored. Refactoring will attempt to do the following: 1. Most code is common across devices. 2. Adding new types of stats that get collected is as simple as possible without losing valuable flexibility. Bug: 138136821 Test: adb shell pwrstats_util Test: adb shell pwrstats_util -d /data/local/tmp/tempfile.txt Change-Id: Ieeb9338caddd954a96052fca893348784fef27f3
Diffstat (limited to 'pwrstats_util')
-rw-r--r--pwrstats_util/Android.bp29
-rw-r--r--pwrstats_util/PowerStatsAggregator.cpp41
-rw-r--r--pwrstats_util/PowerStatsAggregator.h (renamed from pwrstats_util/PowerStatsUtil.h)24
-rw-r--r--pwrstats_util/PowerStatsUtil.cpp155
-rw-r--r--pwrstats_util/dataproviders/PowerEntityResidencyDataProvider.cpp82
-rw-r--r--pwrstats_util/dataproviders/PowerEntityResidencyDataProvider.h28
-rw-r--r--pwrstats_util/pwrstats_util.cpp (renamed from pwrstats_util/main.cpp)24
7 files changed, 197 insertions, 186 deletions
diff --git a/pwrstats_util/Android.bp b/pwrstats_util/Android.bp
index e32624d..647c4d4 100644
--- a/pwrstats_util/Android.bp
+++ b/pwrstats_util/Android.bp
@@ -12,14 +12,32 @@
// 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.
-cc_binary {
- name: "pwrstats_util",
+cc_library_static {
+ name: "libpowerstatsutil",
+ defaults: ["pwrstatsutil_defaults"],
+ export_include_dirs: ["."],
srcs: [
- "main.cpp",
- "PowerStatsUtil.cpp",
+ "pwrstats_util.cpp",
+ "PowerStatsAggregator.cpp",
+ "dataproviders/PowerEntityResidencyDataProvider.cpp",
],
+ shared_libs: [
+ "libhidlbase",
+ "android.hardware.power.stats@1.0",
+ ],
+}
+
+// Useful defaults for pwrstats_util
+cc_defaults {
+ name: "pwrstatsutil_defaults",
+ vendor: true,
cflags: [
"-Wall",
+
+ // Try to catch typical 32-bit assumptions that break with 64-bit pointers.
+ "-Werror=pointer-to-int-cast",
+ "-Werror=int-to-pointer-cast",
+ "-Werror=type-limits",
"-Werror",
],
tidy: true,
@@ -44,8 +62,5 @@ cc_binary {
"libbase",
"libutils",
"liblog",
- "libhidlbase",
- "android.hardware.power.stats@1.0",
],
- vendor: true,
}
diff --git a/pwrstats_util/PowerStatsAggregator.cpp b/pwrstats_util/PowerStatsAggregator.cpp
new file mode 100644
index 0000000..c320505
--- /dev/null
+++ b/pwrstats_util/PowerStatsAggregator.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 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 "pwrstats_util"
+
+#include "PowerStatsAggregator.h"
+
+#include <android-base/logging.h>
+#include <android-base/parsedouble.h>
+
+#include <iostream>
+#include <memory>
+#include <unordered_map>
+
+void PowerStatsAggregator::addDataProvider(std::unique_ptr<IPowerStatsDataProvider> p) {
+ mDataProviders.emplace_back(std::move(p));
+}
+
+int PowerStatsAggregator::getData(std::unordered_map<std::string, uint64_t>* data) const {
+ data->clear();
+ for (auto&& provider : mDataProviders) {
+ int ret = provider->get(data);
+ if (ret != 0) {
+ data->clear();
+ return ret;
+ }
+ }
+ return 0;
+}
diff --git a/pwrstats_util/PowerStatsUtil.h b/pwrstats_util/PowerStatsAggregator.h
index 3e685e5..70ff70f 100644
--- a/pwrstats_util/PowerStatsUtil.h
+++ b/pwrstats_util/PowerStatsAggregator.h
@@ -13,11 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#ifndef POWERSTATSUTIL_H
-#define POWERSTATSUTIL_H
+#ifndef POWERSTATSAGGREGATOR_H
+#define POWERSTATSAGGREGATOR_H
#include <memory>
-#include <string>
#include <unordered_map>
#include <vector>
@@ -25,23 +24,26 @@
* Classes that implement this interface can be used to provide stats in the form of key/value
* pairs to PwrStatsUtil.
**/
-class IPwrStatsUtilDataProvider {
+class IPowerStatsDataProvider {
public:
- virtual ~IPwrStatsUtilDataProvider() = default;
- virtual int get(std::unordered_map<std::string, uint64_t>& data) = 0;
+ virtual ~IPowerStatsDataProvider() = default;
+ virtual int get(std::unordered_map<std::string, uint64_t>* data) = 0;
};
/**
* This class is used to return stats in the form of key/value pairs for all registered classes
* that implement IPwrStatsUtilDataProvider.
**/
-class PowerStatsUtil {
+class PowerStatsAggregator {
public:
- PowerStatsUtil();
- int getData(std::unordered_map<std::string, uint64_t>& data);
+ PowerStatsAggregator() = default;
+ int getData(std::unordered_map<std::string, uint64_t>* data) const;
+ void addDataProvider(std::unique_ptr<IPowerStatsDataProvider> dataProvider);
private:
- std::vector<std::unique_ptr<IPwrStatsUtilDataProvider>> mDataProviders;
+ std::vector<std::unique_ptr<IPowerStatsDataProvider>> mDataProviders;
};
-#endif // POWERSTATSUTIL_H
+int run(int argc, char** argv, const PowerStatsAggregator& agg);
+
+#endif // POWERSTATSAGGREGATOR_H
diff --git a/pwrstats_util/PowerStatsUtil.cpp b/pwrstats_util/PowerStatsUtil.cpp
deleted file mode 100644
index ffd4d30..0000000
--- a/pwrstats_util/PowerStatsUtil.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2019 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 "pwrstats_util"
-
-#include "PowerStatsUtil.h"
-
-#include <android-base/logging.h>
-#include <android-base/parsedouble.h>
-#include <android/hardware/power/stats/1.0/IPowerStats.h>
-
-#include <fstream>
-#include <iostream>
-#include <memory>
-#include <regex>
-#include <string>
-#include <unordered_map>
-
-using android::sp;
-using android::hardware::Return;
-
-/**
- * C-state residency data provider:
- * Provides C-state residency information for each of the CPUs and L3 cache.
- **/
-class CstateDataProvider : public IPwrStatsUtilDataProvider {
- public:
- CstateDataProvider() = default;
-
- int get(std::unordered_map<std::string, uint64_t>& data) override {
- // example accessing a sysfs node
- std::ifstream file("/sys/kernel/debug/lpm_stats/stats");
-
- std::smatch matches;
- const std::regex searchExpr("\\[(.*?)\\] (.*?):");
- std::string line;
- const std::string searchStr = "total success time:";
-
- while (std::getline(file, line)) {
- if (std::regex_search(line, matches, searchExpr)) {
- std::ostringstream key;
- key << matches[1] << "__" << matches[2];
-
- while (std::getline(file, line)) {
- size_t pos = line.find(searchStr);
- if (pos != std::string::npos) {
- float val;
- if (android::base::ParseFloat(line.substr(pos + searchStr.size()), &val)) {
- data.emplace(key.str(), static_cast<uint64_t>(val * 1000));
- } else {
- LOG(ERROR) << __func__ << ": failed to parse c-state data";
- }
- break;
- }
- }
- }
- }
-
- return 0;
- }
-};
-
-/**
- * Power Stats HAL data provider:
- * Provides data monitored by Power Stats HAL 1.0
- **/
-class PwrStatsHalDataProvider : public IPwrStatsUtilDataProvider {
- public:
- PwrStatsHalDataProvider() = default;
-
- int get(std::unordered_map<std::string, uint64_t>& data) override {
- // example using the power stats HAL
- sp<android::hardware::power::stats::V1_0::IPowerStats> powerStatsService =
- android::hardware::power::stats::V1_0::IPowerStats::getService();
- if (powerStatsService == nullptr) {
- LOG(ERROR) << "Unable to get power.stats HAL service.";
- return 1;
- }
-
- std::unordered_map<uint32_t, std::string> entityNames;
- std::unordered_map<uint32_t, std::unordered_map<uint32_t, std::string>> stateNames;
-
- Return<void> ret;
- ret = powerStatsService->getPowerEntityInfo([&entityNames](auto infos, auto /* status */) {
- for (auto const& info : infos) {
- entityNames.emplace(info.powerEntityId, info.powerEntityName);
- }
- });
- if (!ret.isOk()) {
- return 1;
- }
-
- ret = powerStatsService->getPowerEntityStateInfo({}, [&stateNames](auto stateSpaces,
- auto /* status */) {
- for (auto const& stateSpace : stateSpaces) {
- stateNames.emplace(stateSpace.powerEntityId,
- std::unordered_map<uint32_t, std::string>());
- auto& entityStateNames = stateNames.at(stateSpace.powerEntityId);
- for (auto const& state : stateSpace.states) {
- entityStateNames.emplace(state.powerEntityStateId, state.powerEntityStateName);
- }
- }
- });
- if (!ret.isOk()) {
- return 1;
- }
-
- ret = powerStatsService->getPowerEntityStateResidencyData(
- {}, [&entityNames, &stateNames, &data](auto results, auto /* status */) {
- for (auto const& result : results) {
- for (auto stateResidency : result.stateResidencyData) {
- std::ostringstream key;
- key << entityNames.at(result.powerEntityId) << "__"
- << stateNames.at(result.powerEntityId)
- .at(stateResidency.powerEntityStateId);
- data.emplace(key.str(),
- static_cast<uint64_t>(stateResidency.totalTimeInStateMs));
- }
- }
- });
- if (!ret.isOk()) {
- return 1;
- }
-
- return 0;
- }
-};
-
-PowerStatsUtil::PowerStatsUtil() {
- mDataProviders.emplace_back(std::make_unique<CstateDataProvider>());
- mDataProviders.emplace_back(std::make_unique<PwrStatsHalDataProvider>());
-}
-
-int PowerStatsUtil::getData(std::unordered_map<std::string, uint64_t>& data) {
- data.clear();
- for (auto&& provider : mDataProviders) {
- int ret = provider->get(data);
- if (ret != 0) {
- return ret;
- }
- }
- return 0;
-}
diff --git a/pwrstats_util/dataproviders/PowerEntityResidencyDataProvider.cpp b/pwrstats_util/dataproviders/PowerEntityResidencyDataProvider.cpp
new file mode 100644
index 0000000..ae5eff4
--- /dev/null
+++ b/pwrstats_util/dataproviders/PowerEntityResidencyDataProvider.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2019 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 "pwrstats_util"
+
+#include "PowerEntityResidencyDataProvider.h"
+#include <android-base/logging.h>
+#include <android/hardware/power/stats/1.0/IPowerStats.h>
+using android::sp;
+using android::hardware::Return;
+
+/**
+ * Power Entity State Residency data provider:
+ * Provides data monitored by Power Stats HAL 1.0
+ **/
+
+int PowerEntityResidencyDataProvider::get(std::unordered_map<std::string, uint64_t>* data) {
+ sp<android::hardware::power::stats::V1_0::IPowerStats> powerStatsService =
+ android::hardware::power::stats::V1_0::IPowerStats::getService();
+ if (powerStatsService == nullptr) {
+ LOG(ERROR) << "Unable to get power.stats HAL service.";
+ return 1;
+ }
+
+ std::unordered_map<uint32_t, std::string> entityNames;
+ std::unordered_map<uint32_t, std::unordered_map<uint32_t, std::string>> stateNames;
+
+ Return<void> ret;
+ ret = powerStatsService->getPowerEntityInfo([&entityNames](auto infos, auto /* status */) {
+ for (auto const& info : infos) {
+ entityNames.emplace(info.powerEntityId, info.powerEntityName);
+ }
+ });
+ if (!ret.isOk()) {
+ return 1;
+ }
+
+ ret = powerStatsService->getPowerEntityStateInfo({}, [&stateNames](auto stateSpaces,
+ auto /* status */) {
+ for (auto const& stateSpace : stateSpaces) {
+ stateNames.emplace(stateSpace.powerEntityId,
+ std::unordered_map<uint32_t, std::string>());
+ auto& entityStateNames = stateNames.at(stateSpace.powerEntityId);
+ for (auto const& state : stateSpace.states) {
+ entityStateNames.emplace(state.powerEntityStateId, state.powerEntityStateName);
+ }
+ }
+ });
+ if (!ret.isOk()) {
+ return 1;
+ }
+
+ ret = powerStatsService->getPowerEntityStateResidencyData({}, [&entityNames, &stateNames,
+ &data](auto results,
+ auto /* status */) {
+ for (auto const& result : results) {
+ for (auto stateResidency : result.stateResidencyData) {
+ std::ostringstream key;
+ key << entityNames.at(result.powerEntityId) << "__"
+ << stateNames.at(result.powerEntityId).at(stateResidency.powerEntityStateId);
+ data->emplace(key.str(), static_cast<uint64_t>(stateResidency.totalTimeInStateMs));
+ }
+ }
+ });
+ if (!ret.isOk()) {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/pwrstats_util/dataproviders/PowerEntityResidencyDataProvider.h b/pwrstats_util/dataproviders/PowerEntityResidencyDataProvider.h
new file mode 100644
index 0000000..73bb453
--- /dev/null
+++ b/pwrstats_util/dataproviders/PowerEntityResidencyDataProvider.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+#ifndef POWERENTITYRESIDENCYDATAPROVIDER_H
+#define POWERENTITYRESIDENCYDATAPROVIDER_H
+
+#include "PowerStatsAggregator.h"
+
+class PowerEntityResidencyDataProvider : public IPowerStatsDataProvider {
+ public:
+ PowerEntityResidencyDataProvider() = default;
+
+ int get(std::unordered_map<std::string, uint64_t>* data) override;
+};
+
+#endif // POWERENTITYRESIDENCYDATAPROVIDER_H
diff --git a/pwrstats_util/main.cpp b/pwrstats_util/pwrstats_util.cpp
index 8f82d6f..b28b4b0 100644
--- a/pwrstats_util/main.cpp
+++ b/pwrstats_util/pwrstats_util.cpp
@@ -27,7 +27,7 @@
#include <iostream>
#include <unordered_map>
-#include "PowerStatsUtil.h"
+#include "PowerStatsAggregator.h"
namespace {
volatile std::sig_atomic_t gSignalStatus;
@@ -72,10 +72,9 @@ static Options parseArgs(int argc, char** argv) {
return opt;
}
-static void snapshot(void) {
+static void snapshot(const PowerStatsAggregator& agg) {
std::unordered_map<std::string, uint64_t> data;
- PowerStatsUtil util;
- int ret = util.getData(data);
+ int ret = agg.getData(&data);
if (ret) {
exit(EXIT_FAILURE);
}
@@ -87,7 +86,7 @@ static void snapshot(void) {
exit(EXIT_SUCCESS);
}
-static void daemon(const std::string& filePath) {
+static void daemon(const std::string& filePath, const PowerStatsAggregator& agg) {
// Following a subset of steps outlined in http://man7.org/linux/man-pages/man7/daemon.7.html
// Call fork to create child process
@@ -145,9 +144,8 @@ static void daemon(const std::string& filePath) {
// get the start_data
auto start_time = std::chrono::system_clock::now();
- PowerStatsUtil util;
std::unordered_map<std::string, uint64_t> start_data;
- int ret = util.getData(start_data);
+ int ret = agg.getData(&start_data);
if (ret) {
LOG(ERROR) << "failed to get start data";
exit(EXIT_FAILURE);
@@ -160,7 +158,7 @@ static void daemon(const std::string& filePath) {
// get the end data
std::unordered_map<std::string, uint64_t> end_data;
- ret = util.getData(end_data);
+ ret = agg.getData(&end_data);
if (ret) {
LOG(ERROR) << "failed to get end data";
exit(EXIT_FAILURE);
@@ -185,18 +183,18 @@ static void daemon(const std::string& filePath) {
exit(EXIT_SUCCESS);
}
-void run(const Options& opt) {
+static void runWithOptions(const Options& opt, const PowerStatsAggregator& agg) {
if (opt.daemonMode) {
- daemon(opt.filePath);
+ daemon(opt.filePath, agg);
} else {
- snapshot();
+ snapshot(agg);
}
}
-int main(int argc, char** argv) {
+int run(int argc, char** argv, const PowerStatsAggregator& agg) {
Options opt = parseArgs(argc, argv);
- run(opt);
+ runWithOptions(opt, agg);
return 0;
}