diff options
author | Calder Kitagawa <ckitagawa@google.com> | 2018-03-15 20:35:01 +0000 |
---|---|---|
committer | Edward Lesmes <ehmaldonado@google.com> | 2021-07-23 21:54:05 +0000 |
commit | b17e610cfa3171036b3487c2261990c3f3af1c62 (patch) | |
tree | e7176cbeabe2fbf84ce5673989c86d43550514d4 /main_utils.cc | |
parent | 63974a2cc4de484d94537ef1360a801a52a7c37d (diff) | |
download | zucchini-b17e610cfa3171036b3487c2261990c3f3af1c62.tar.gz |
[Zucchini]: Add Linux RAM metrics to Zucchini
Reintroduces the PeakPageMemory (Peak Virtual Memory) and
PeakWorkingSetSize (Virtual Memory High Water Mark) metrics to Linux
builds of Zucchini. Linux is used for benchmarking of ELF and DEX
variants of Zucchini as well as general intergration and regression
testing so it is nice to have these metrics remain in the program.
The method used is based on code in base/process/internal_linux.[h|cc]
however, it avoids the overhead of having to create key value pairs
for all of the metrics so is slightly faster. Moreover, the contents
of internal_linux are intended to be private to base/process so in
order to get these metrics it is necessary to replicate part of the
code.
These were originally removed in:
https://chromium-review.googlesource.com/c/chromium/src/+/951923.
Also fixes some weirdness with "// defined(...)" comments.
Change-Id: Id69f16fa912117f3d3756b425e584c48b9f0fff2
Reviewed-on: https://chromium-review.googlesource.com/963604
Commit-Queue: Calder Kitagawa <ckitagawa@google.com>
Reviewed-by: Samuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543483}
NOKEYCHECK=True
GitOrigin-RevId: 20483a8514e95c738aae419e0fa4fe050fd65cfc
Diffstat (limited to 'main_utils.cc')
-rw-r--r-- | main_utils.cc | 92 |
1 files changed, 76 insertions, 16 deletions
diff --git a/main_utils.cc b/main_utils.cc index ee0332a..3a7055a 100644 --- a/main_utils.cc +++ b/main_utils.cc @@ -8,10 +8,17 @@ #include <memory> #include <ostream> +#include <string> #include <vector> #include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" +#include "base/process/process_handle.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" #include "base/time/time.h" #include "build/build_config.h" #include "components/zucchini/io_utils.h" @@ -64,6 +71,66 @@ constexpr Command kCommands[] = { {"crc32", "-crc32 <file>", 1, &MainCrc32}, }; +/******** GetPeakMemoryMetrics ********/ + +#if defined(OS_LINUX) +// Linux does not have an exact mapping to the values used on Windows so use a +// close approximation: +// peak_virtual_memory ~= peak_page_file_usage +// resident_set_size_hwm (high water mark) ~= peak_working_set_size +// +// On failure the input values will be set to 0. +void GetPeakMemoryMetrics(size_t* peak_virtual_memory, + size_t* resident_set_size_hwm) { + *peak_virtual_memory = 0; + *resident_set_size_hwm = 0; + auto status_path = + base::FilePath("/proc") + .Append(base::IntToString(base::GetCurrentProcessHandle())) + .Append("status"); + std::string contents_string; + base::ReadFileToString(status_path, &contents_string); + std::vector<base::StringPiece> lines = base::SplitStringPiece( + contents_string, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + + for (const auto& line : lines) { + // Tokens should generally be of the form "Metric: <val> kB" + std::vector<base::StringPiece> tokens = base::SplitStringPiece( + line, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + if (tokens.size() < 2) + continue; + + if (tokens[0] == "VmPeak:") { + if (base::StringToSizeT(tokens[1], peak_virtual_memory)) { + *peak_virtual_memory *= 1024; // in kiB + if (*resident_set_size_hwm) + return; + } + } else if (tokens[0] == "VmHWM:") { + if (base::StringToSizeT(tokens[1], resident_set_size_hwm)) { + *resident_set_size_hwm *= 1024; // in kiB + if (*peak_virtual_memory) + return; + } + } + } +} +#endif // defined(OS_LINUX) + +#if defined(OS_WIN) +// On failure the input values will be set to 0. +void GetPeakMemoryMetrics(size_t* peak_page_file_usage, + size_t* peak_working_set_size) { + *peak_page_file_usage = 0; + *peak_working_set_size = 0; + PROCESS_MEMORY_COUNTERS pmc; + if (::GetProcessMemoryInfo(::GetCurrentProcess(), &pmc, sizeof(pmc))) { + *peak_page_file_usage = pmc.PeakPagefileUsage; + *peak_working_set_size = pmc.PeakWorkingSetSize; + } +} +#endif // defined(OS_WIN) + /******** ScopedResourceUsageTracker ********/ // A class to track and log system resource usage. @@ -73,27 +140,20 @@ class ScopedResourceUsageTracker { ScopedResourceUsageTracker() { start_time_ = base::TimeTicks::Now(); -#if defined(OS_WIN) - PROCESS_MEMORY_COUNTERS pmc; - if (::GetProcessMemoryInfo(::GetCurrentProcess(), &pmc, sizeof(pmc))) { - start_peak_page_file_usage_ = pmc.PeakPagefileUsage; - start_peak_working_set_size_ = pmc.PeakWorkingSetSize; - } -#endif +#if defined(OS_LINUX) || defined(OS_WIN) + GetPeakMemoryMetrics(&start_peak_page_file_usage_, + &start_peak_working_set_size_); +#endif // defined(OS_LINUX) || defined(OS_WIN) } // Computes and prints usage. ~ScopedResourceUsageTracker() { base::TimeTicks end_time = base::TimeTicks::Now(); -#if defined(OS_WIN) +#if defined(OS_LINUX) || defined(OS_WIN) size_t cur_peak_page_file_usage = 0; size_t cur_peak_working_set_size = 0; - PROCESS_MEMORY_COUNTERS pmc; - if (::GetProcessMemoryInfo(::GetCurrentProcess(), &pmc, sizeof(pmc))) { - cur_peak_page_file_usage = pmc.PeakPagefileUsage; - cur_peak_working_set_size = pmc.PeakWorkingSetSize; - } + GetPeakMemoryMetrics(&cur_peak_page_file_usage, &cur_peak_working_set_size); LOG(INFO) << "Zucchini.PeakPagefileUsage " << cur_peak_page_file_usage / 1024 << " KiB"; @@ -106,7 +166,7 @@ class ScopedResourceUsageTracker { << (cur_peak_working_set_size - start_peak_working_set_size_) / 1024 << " KiB"; -#endif // !defined(OS_MACOSX) +#endif // defined(OS_LINUX) || defined(OS_WIN) LOG(INFO) << "Zucchini.TotalTime " << (end_time - start_time_).InSecondsF() << " s"; @@ -114,10 +174,10 @@ class ScopedResourceUsageTracker { private: base::TimeTicks start_time_; -#if defined(OS_WIN) +#if defined(OS_LINUX) || defined(OS_WIN) size_t start_peak_page_file_usage_ = 0; size_t start_peak_working_set_size_ = 0; -#endif // !defined(OS_MACOSX) +#endif // defined(OS_LINUX) || defined(OS_WIN) }; /******** Helper functions ********/ |