summaryrefslogtreecommitdiff
path: root/pixelstats/MmMetricsReporter.cpp
diff options
context:
space:
mode:
authorRobin Hsu <robinhsu@google.com>2022-07-06 14:22:59 +0800
committerRobin Hsu <robinhsu@google.com>2022-08-26 02:59:09 +0000
commit36df9efa5c29ed920ae242dc165d5c4ac050a88b (patch)
treee7e778d17b809155c93645533991134e5cb9b7b8 /pixelstats/MmMetricsReporter.cpp
parent715bbce7e00a5557a8ec014e04766890a4c7d4ee (diff)
pixelstat: MM metrics: add generic reader
Add shared functions for reading direct reclaim and compaction duration information. The format is a number of integers. e.g. /sys/kernel/pixel_stat/mm/vmscan/direct_reclaim/visible/latency_stat: 0 0 0 0 0 0 Test: local test Bug: 234564667 Signed-off-by: Robin Hsu <robinhsu@google.com> Change-Id: If09cf4b6538be0bcbb99a9e90a81784a9c406bc9
Diffstat (limited to 'pixelstats/MmMetricsReporter.cpp')
-rw-r--r--pixelstats/MmMetricsReporter.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/pixelstats/MmMetricsReporter.cpp b/pixelstats/MmMetricsReporter.cpp
index b7dd5d9..b6498bf 100644
--- a/pixelstats/MmMetricsReporter.cpp
+++ b/pixelstats/MmMetricsReporter.cpp
@@ -183,6 +183,90 @@ bool MmMetricsReporter::ReadFileToUint(const char *const path, uint64_t *val) {
return true;
}
+/*
+ * This function reads whole file and parses tokens separated by <delim> into
+ * long integers. Useful for direct reclaim & compaction duration sysfs nodes.
+ * Data write is using all or none policy: It will not write partial data unless
+ * all data values are good.
+ *
+ * path: file to open/read
+ * data: where to store the results
+ * start_idx: index into data[] where to start saving the results
+ * delim: delimiters separating different longs
+ * skip: how many resulting longs to skip before saving
+ * nonnegtive: set to true to validate positive numbers
+ *
+ * Return value: number of longs actually stored on success. negative
+ * error codes on errors.
+ */
+static int ReadFileToLongs(const std::string &path, std::vector<long> *data, int start_idx,
+ const char *delim, int skip, bool nonnegative = false) {
+ std::vector<long> out;
+ enum { err_read_file = -1, err_parse = -2 };
+ std::string file_contents;
+
+ if (!ReadFileToString(path, &file_contents)) {
+ // Don't print this log if the file doesn't exist, since logs will be printed repeatedly.
+ if (errno != ENOENT) {
+ ALOGI("Unable to read %s - %s", path.c_str(), strerror(errno));
+ }
+ return err_read_file;
+ }
+
+ file_contents = android::base::Trim(file_contents);
+ std::vector<std::string> words = android::base::Tokenize(file_contents, delim);
+ if (words.size() == 0)
+ return 0;
+
+ for (auto &w : words) {
+ if (skip) {
+ skip--;
+ continue;
+ }
+ long tmp;
+ if (!android::base::ParseInt(w, &tmp) || (nonnegative && tmp < 0))
+ return err_parse;
+ out.push_back(tmp);
+ }
+
+ int min_size = std::max(static_cast<int>(out.size()) + start_idx, 0);
+ if (min_size > data->size())
+ data->resize(min_size);
+ std::copy(out.begin(), out.end(), data->begin() + start_idx);
+
+ return out.size();
+}
+
+/*
+ * This function calls ReadFileToLongs, and checks the expected number
+ * of long integers read. Useful for direct reclaim & compaction duration
+ * sysfs nodes.
+ *
+ * path: file to open/read
+ * data: where to store the results
+ * start_idx: index into data[] where to start saving the results
+ * delim: delimiters separating different longs
+ * skip: how many resulting longs to skip before saving
+ * expected_num: number of expected longs to be read.
+ * nonnegtive: set to true to validate positive numbers
+ *
+ * Return value: true if successfully get expected number of long values.
+ * otherwise false.
+ */
+static inline bool ReadFileToLongsCheck(const std::string &path, std::vector<long> *store,
+ int start_idx, const char *delim, int skip,
+ int expected_num, bool nonnegative = false) {
+ int num = ReadFileToLongs(path, store, start_idx, delim, skip, nonnegative);
+
+ if (num == expected_num)
+ return true;
+
+ int last_idx = std::min(start_idx + expected_num, static_cast<int>(store->size()));
+ std::fill(store->begin() + start_idx, store->begin() + last_idx, -1);
+
+ return false;
+}
+
bool MmMetricsReporter::reportVendorAtom(const std::shared_ptr<IStats> &stats_client, int atom_id,
const std::vector<VendorAtomValue> &values,
const std::string &atom_name) {