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>
This commit is contained in:
parent
549feab631
commit
f129199350
|
@ -29,6 +29,9 @@ namespace meminfo {
|
|||
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 @@ class ProcMemInfo final {
|
|||
const MemUsage& Wss();
|
||||
const std::vector<uint16_t>& SwapOffsets() const;
|
||||
|
||||
bool WssReset();
|
||||
~ProcMemInfo() = default;
|
||||
|
||||
private:
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<Vma>& 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<uint16_t>& 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/<pid>/maps
|
||||
std::string maps_file = ::android::base::StringPrintf("/proc/%d/maps", pid_);
|
||||
|
|
|
@ -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 <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 @@ 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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue