libmeminfo: Add support to reset workingset without procmeminfo objects

Bug: 114325007
Bug: 111694435
Test: libmeminfo_test 1

Change-Id: I816809cda13983e47294a956347a27085397cbcf
Signed-off-by: Sandeep Patil <sspatil@google.com>
diff --git a/libmeminfo/include/meminfo/procmeminfo.h b/libmeminfo/include/meminfo/procmeminfo.h
index 3b620a0..0d6f652 100644
--- a/libmeminfo/include/meminfo/procmeminfo.h
+++ b/libmeminfo/include/meminfo/procmeminfo.h
@@ -29,6 +29,9 @@
 class ProcMemInfo final {
     // Per-process memory accounting
   public:
+    // Reset the working set accounting of the process via /proc/<pid>/clear_refs
+    static bool ResetWorkingSet(pid_t pid);
+
     ProcMemInfo(pid_t pid, bool get_wss = false, uint64_t pgflags = 0, uint64_t pgflags_mask = 0);
 
     const std::vector<Vma>& Maps();
@@ -36,7 +39,6 @@
     const MemUsage& Wss();
     const std::vector<uint16_t>& SwapOffsets() const;
 
-    bool WssReset();
     ~ProcMemInfo() = default;
 
   private:
diff --git a/libmeminfo/libmeminfo_test.cpp b/libmeminfo/libmeminfo_test.cpp
index 6d73173..e28c352 100644
--- a/libmeminfo/libmeminfo_test.cpp
+++ b/libmeminfo/libmeminfo_test.cpp
@@ -142,7 +142,7 @@
 
 TEST_F(ValidateProcMemInfoWss, TestWorkingTestReset) {
     // Expect reset to succeed
-    EXPECT_TRUE(proc_mem->WssReset());
+    EXPECT_TRUE(ProcMemInfo::ResetWorkingSet(pid));
 }
 
 TEST_F(ValidateProcMemInfoWss, TestWssEquality) {
diff --git a/libmeminfo/procmeminfo.cpp b/libmeminfo/procmeminfo.cpp
index 56b62e8..378f923 100644
--- a/libmeminfo/procmeminfo.cpp
+++ b/libmeminfo/procmeminfo.cpp
@@ -53,6 +53,16 @@
     to->shared_dirty += from.shared_dirty;
 }
 
+bool ProcMemInfo::ResetWorkingSet(pid_t pid) {
+    std::string clear_refs_path = ::android::base::StringPrintf("/proc/%d/clear_refs", pid);
+    if (!::android::base::WriteStringToFile("1\n", clear_refs_path)) {
+        PLOG(ERROR) << "Failed to write to " << clear_refs_path;
+        return false;
+    }
+
+    return true;
+}
+
 ProcMemInfo::ProcMemInfo(pid_t pid, bool get_wss, uint64_t pgflags, uint64_t pgflags_mask)
     : pid_(pid), get_wss_(get_wss), pgflags_(pgflags), pgflags_mask_(pgflags_mask) {
     if (!ReadMaps(get_wss_)) {
@@ -66,14 +76,16 @@
 
 const MemUsage& ProcMemInfo::Usage() {
     if (get_wss_) {
-        LOG(WARNING) << "Trying to read memory usage from working set object";
+        LOG(WARNING) << "Trying to read process memory usage for " << pid_
+                     << " using invalid object";
     }
     return usage_;
 }
 
 const MemUsage& ProcMemInfo::Wss() {
     if (!get_wss_) {
-        LOG(WARNING) << "Trying to read working set when there is none";
+        LOG(WARNING) << "Trying to read process working set for " << pid_
+                     << " using invalid object";
     }
 
     return wss_;
@@ -83,22 +95,6 @@
     return swap_offsets_;
 }
 
-bool ProcMemInfo::WssReset() {
-    if (!get_wss_) {
-        LOG(ERROR) << "Trying to reset working set from a memory usage counting object";
-        return false;
-    }
-
-    std::string clear_refs_path = ::android::base::StringPrintf("/proc/%d/clear_refs", pid_);
-    if (!::android::base::WriteStringToFile("1\n", clear_refs_path)) {
-        PLOG(ERROR) << "Failed to write to " << clear_refs_path;
-        return false;
-    }
-
-    wss_.clear();
-    return true;
-}
-
 bool ProcMemInfo::ReadMaps(bool get_wss) {
     // parse and read /proc/<pid>/maps
     std::string maps_file = ::android::base::StringPrintf("/proc/%d/maps", pid_);
diff --git a/libmeminfo/tools/procmem.cpp b/libmeminfo/tools/procmem.cpp
index 3571e41..d30c2f2 100644
--- a/libmeminfo/tools/procmem.cpp
+++ b/libmeminfo/tools/procmem.cpp
@@ -66,14 +66,12 @@
     // clear string stream first.
     ss.str("");
     // TODO: use ::android::base::StringPrintf instead of <iomanip> here.
-    if (!show_wss)
-        ss << std::setw(6) << usage.vss/1024 << padding;
-    ss << std::setw(6) << usage.rss/1024 << padding << std::setw(6)
-       << usage.pss/1024 << padding << std::setw(6) << usage.uss/1024 << padding
-       << std::setw(6) << usage.shared_clean/1024 << padding << std::setw(6)
-       << usage.shared_dirty/1024 << padding << std::setw(6)
-       << usage.private_clean/1024 << padding << std::setw(6)
-       << usage.private_dirty/1024 << padding;
+    if (!show_wss) ss << std::setw(6) << usage.vss / 1024 << padding;
+    ss << std::setw(6) << usage.rss / 1024 << padding << std::setw(6) << usage.pss / 1024 << padding
+       << std::setw(6) << usage.uss / 1024 << padding << std::setw(6) << usage.shared_clean / 1024
+       << padding << std::setw(6) << usage.shared_dirty / 1024 << padding << std::setw(6)
+       << usage.private_clean / 1024 << padding << std::setw(6) << usage.private_dirty / 1024
+       << padding;
 }
 
 static int show(ProcMemInfo& proc, bool hide_zeroes, bool show_wss) {
@@ -158,14 +156,14 @@
     }
 
     bool need_wss = wss_reset || show_wss;
-    ProcMemInfo proc(pid, need_wss);
     if (wss_reset) {
-        if (!proc.WssReset()) {
+        if (!ProcMemInfo::ResetWorkingSet(pid)) {
             std::cerr << "Failed to reset working set of pid : " << pid << std::endl;
             exit(EXIT_FAILURE);
         }
         return 0;
     }
 
+    ProcMemInfo proc(pid, need_wss);
     return show(proc, hide_zeroes, show_wss);
 }