meminfo: Add SmapsOrRollupPss

Adds SmapsOrRollup parsing methods to only read Pss of the
process fomr /proc/<pid>/{smaps, smaps_rollup}.

Bug: 111694435
Test: libmeminfo_test 1 --gtest_filter=TestProcMemInfo.*

Change-Id: I31b982ae5ff2bb5b165ea33f6c57755ee34cbbc7
Merged-In: I31b982ae5ff2bb5b165ea33f6c57755ee34cbbc7
Signed-off-by: Sandeep Patil <sspatil@google.com>
diff --git a/libmeminfo/procmeminfo.cpp b/libmeminfo/procmeminfo.cpp
index 9345bda..f72d469 100644
--- a/libmeminfo/procmeminfo.cpp
+++ b/libmeminfo/procmeminfo.cpp
@@ -178,6 +178,12 @@
     return SmapsOrRollupFromFile(path, stats);
 };
 
+bool ProcMemInfo::SmapsOrRollupPss(bool use_rollup, uint64_t* pss) const {
+    std::string path = ::android::base::StringPrintf("/proc/%d/%s", pid_,
+                                                     use_rollup ? "smaps_rollup" : "smaps");
+    return SmapsOrRollupPssFromFile(path, pss);
+}
+
 const std::vector<uint16_t>& ProcMemInfo::SwapOffsets() {
     if (get_wss_) {
         LOG(WARNING) << "Trying to read process swap offsets for " << pid_
@@ -412,5 +418,22 @@
     return true;
 }
 
+bool SmapsOrRollupPssFromFile(const std::string& path, uint64_t* pss) {
+    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
+    if (fp == nullptr) {
+        return false;
+    }
+    *pss = 0;
+    char line[1024];
+    while (fgets(line, sizeof(line), fp.get()) != nullptr) {
+        uint64_t v;
+        if (sscanf(line, "Pss: %" SCNu64 " kB", &v) == 1) {
+            *pss += v;
+        }
+    }
+
+    return true;
+}
+
 }  // namespace meminfo
 }  // namespace android