libmeminfo: Add SmapsRollup
This adds the tests and SmapsRollup() parsing function in
ProcMemInfo. Adds tests to check the return value as well as
the correctness.
Bug: 111694435
Test: libmeminfo_test 1 --gtest_filter=TestProcMemInfo.*
Test: libmeminfo_benchmark --benchmark_filter=BM_SmapsRollup_
Result:
----------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------
BM_SmapsRollup_old 4751 ns 4730 ns 149458
BM_SmapsRollup_new 4858 ns 4837 ns 144636
----------------------------------------------------------
Change-Id: Ia051fe53a7622e3091502ff7166efafae35e7935
Signed-off-by: Sandeep Patil <sspatil@google.com>
diff --git a/libmeminfo/procmeminfo.cpp b/libmeminfo/procmeminfo.cpp
index 8867e14..1daff1e 100644
--- a/libmeminfo/procmeminfo.cpp
+++ b/libmeminfo/procmeminfo.cpp
@@ -30,6 +30,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <procinfo/process_map.h>
@@ -102,6 +103,12 @@
return wss_;
}
+bool ProcMemInfo::SmapsOrRollup(bool use_rollup, MemUsage* stats) const {
+ std::string path = ::android::base::StringPrintf("/proc/%d/%s", pid_,
+ use_rollup ? "smaps_rollup" : "smaps");
+ return SmapsOrRollupFromFile(path, stats);
+};
+
const std::vector<uint16_t>& ProcMemInfo::SwapOffsets() {
if (get_wss_) {
LOG(WARNING) << "Trying to read process swap offsets for " << pid_
@@ -252,5 +259,50 @@
return true;
}
+// Public APIs
+bool SmapsOrRollupFromFile(const std::string& path, MemUsage* stats) {
+ auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
+ if (fp == nullptr) {
+ return false;
+ }
+
+ char line[1024];
+ stats->clear();
+ while (fgets(line, sizeof(line), fp.get()) != nullptr) {
+ switch (line[0]) {
+ case 'P':
+ if (strncmp(line, "Pss:", 4) == 0) {
+ char* c = line + 4;
+ stats->pss += strtoull(c, nullptr, 10);
+ } else if (strncmp(line, "Private_Clean:", 14) == 0) {
+ char* c = line + 14;
+ uint64_t prcl = strtoull(c, nullptr, 10);
+ stats->private_clean += prcl;
+ stats->uss += prcl;
+ } else if (strncmp(line, "Private_Dirty:", 14) == 0) {
+ char* c = line + 14;
+ uint64_t prdi = strtoull(c, nullptr, 10);
+ stats->private_dirty += prdi;
+ stats->uss += prdi;
+ }
+ break;
+ case 'R':
+ if (strncmp(line, "Rss:", 4) == 0) {
+ char* c = line + 4;
+ stats->rss += strtoull(c, nullptr, 10);
+ }
+ break;
+ case 'S':
+ if (strncmp(line, "SwapPss:", 8) == 0) {
+ char* c = line + 8;
+ stats->swap_pss += strtoull(c, nullptr, 10);
+ }
+ break;
+ }
+ }
+
+ return true;
+}
+
} // namespace meminfo
} // namespace android