From f12919935099acefa0b3e34e2ee36db85e2165b0 Mon Sep 17 00:00:00 2001 From: Sandeep Patil Date: Mon, 19 Nov 2018 15:25:18 -0800 Subject: [PATCH] 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 --- libmeminfo/include/meminfo/procmeminfo.h | 4 ++- libmeminfo/libmeminfo_test.cpp | 2 +- libmeminfo/procmeminfo.cpp | 32 +++++++++++------------- libmeminfo/tools/procmem.cpp | 18 ++++++------- 4 files changed, 26 insertions(+), 30 deletions(-) diff --git a/libmeminfo/include/meminfo/procmeminfo.h b/libmeminfo/include/meminfo/procmeminfo.h index 3b620a00b..0d6f652ab 100644 --- a/libmeminfo/include/meminfo/procmeminfo.h +++ b/libmeminfo/include/meminfo/procmeminfo.h @@ -29,6 +29,9 @@ namespace meminfo { class ProcMemInfo final { // Per-process memory accounting public: + // Reset the working set accounting of the process via /proc//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& Maps(); @@ -36,7 +39,6 @@ class ProcMemInfo final { const MemUsage& Wss(); const std::vector& SwapOffsets() const; - bool WssReset(); ~ProcMemInfo() = default; private: diff --git a/libmeminfo/libmeminfo_test.cpp b/libmeminfo/libmeminfo_test.cpp index 6d731737b..e28c35249 100644 --- a/libmeminfo/libmeminfo_test.cpp +++ b/libmeminfo/libmeminfo_test.cpp @@ -142,7 +142,7 @@ class ValidateProcMemInfoWss : public ::testing::Test { 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 56b62e826..378f923b3 100644 --- a/libmeminfo/procmeminfo.cpp +++ b/libmeminfo/procmeminfo.cpp @@ -53,6 +53,16 @@ static void add_mem_usage(MemUsage* to, const MemUsage& from) { 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 std::vector& ProcMemInfo::Maps() { 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 @@ const std::vector& ProcMemInfo::SwapOffsets() const { 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//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 3571e4173..d30c2f2ba 100644 --- a/libmeminfo/tools/procmem.cpp +++ b/libmeminfo/tools/procmem.cpp @@ -66,14 +66,12 @@ static void scan_usage(std::stringstream& ss, const MemUsage& usage, const std:: // clear string stream first. ss.str(""); // TODO: use ::android::base::StringPrintf instead of 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 @@ int main(int argc, char* argv[]) { } 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); }