Chromium Code Reviews| Index: components/tracing/common/process_metrics_memory_dump_provider.cc |
| diff --git a/components/tracing/common/process_metrics_memory_dump_provider.cc b/components/tracing/common/process_metrics_memory_dump_provider.cc |
| index d2c00c347f0db3f7f9b13286e2af3edc4ac089b3..d06919aeb38cb920024be0478c01961ed375dae3 100644 |
| --- a/components/tracing/common/process_metrics_memory_dump_provider.cc |
| +++ b/components/tracing/common/process_metrics_memory_dump_provider.cc |
| @@ -17,23 +17,22 @@ |
| #include "base/memory/ptr_util.h" |
| #include "base/process/process_metrics.h" |
| #include "base/strings/string_number_conversions.h" |
| +#include "base/strings/string_tokenizer.h" |
| #include "base/strings/string_util.h" |
| +#include "base/synchronization/lock.h" |
| #include "base/trace_event/memory_dump_manager.h" |
| #include "base/trace_event/process_memory_dump.h" |
| #include "base/trace_event/process_memory_maps.h" |
| #include "base/trace_event/process_memory_totals.h" |
| +#include "base/trace_event/trace_log.h" |
| #include "build/build_config.h" |
| namespace tracing { |
| namespace { |
| -base::LazyInstance< |
| - std::map<base::ProcessId, |
| - std::unique_ptr<ProcessMetricsMemoryDumpProvider>>>::Leaky |
| - g_dump_providers_map = LAZY_INSTANCE_INITIALIZER; |
| - |
| #if defined(OS_LINUX) || defined(OS_ANDROID) |
| +const int kInvalidFD = -1; |
|
Primiano Tucci (use gerrit)
2016/12/13 20:02:39
honestly I think that directly using -1 makes the
ssid
2016/12/14 02:59:32
Done.
|
| const char kClearPeakRssCommand[] = "5"; |
| const uint32_t kMaxLineSize = 4096; |
| @@ -155,6 +154,34 @@ uint32_t ReadLinuxProcSmapsFile(FILE* smaps_file, |
| } |
| return num_valid_regions; |
| } |
| + |
| +int OpenStatmFile(base::ProcessId process) { |
| + std::string name = |
| + "/proc/" + |
| + (process == base::kNullProcessId ? "self" : base::IntToString(process)) + |
| + "/statm"; |
| + return open(name.c_str(), O_RDONLY); |
| +} |
| + |
| +bool GetResidentSizesFromStatmFile(int file_des, |
|
Primiano Tucci (use gerrit)
2016/12/13 20:02:39
s/file_des/fd/
ssid
2016/12/14 02:59:32
Done.
|
| + size_t* resident_bytes, |
| + size_t* shared_bytes) { |
| + lseek(file_des, 0, SEEK_SET); |
| + char line[kMaxLineSize]; |
| + int res = read(file_des, line, kMaxLineSize); |
| + if (res <= 0) |
| + return false; |
| + line[res] = '\0'; |
| + base::CStringTokenizer t(line, line + strlen(line), " "); |
|
Primiano Tucci (use gerrit)
2016/12/13 20:02:39
hmm CStringTokenizer will implicitly convert line
ssid
2016/12/14 02:59:32
Makes sense. fixed.
|
| + t.GetNext(); |
| + // Ignore the first first number. |
| + t.GetNext(); |
| + base::StringToSizeT(t.token().c_str(), resident_bytes); |
| + t.GetNext(); |
| + base::StringToSizeT(t.token().c_str(), shared_bytes); |
| + return true; |
| +} |
| + |
| #endif // defined(OS_LINUX) || defined(OS_ANDROID) |
| std::unique_ptr<base::ProcessMetrics> CreateProcessMetrics( |
| @@ -173,6 +200,11 @@ std::unique_ptr<base::ProcessMetrics> CreateProcessMetrics( |
| #endif // defined(OS_LINUX) || defined(OS_ANDROID) |
| } |
| +base::LazyInstance< |
|
Primiano Tucci (use gerrit)
2016/12/13 20:02:39
is there a functional reason why you moved this? I
ssid
2016/12/14 02:59:32
Sorry this was a mistake.
|
| + std::map<base::ProcessId, |
| + std::unique_ptr<ProcessMetricsMemoryDumpProvider>>>::Leaky |
| + g_dump_providers_map = LAZY_INSTANCE_INITIALIZER; |
| + |
| } // namespace |
| // static |
| @@ -211,6 +243,7 @@ void ProcessMetricsMemoryDumpProvider::RegisterForProcess( |
| new ProcessMetricsMemoryDumpProvider(process)); |
| base::trace_event::MemoryDumpProvider::Options options; |
| options.target_pid = process; |
| + options.is_fast_polling_supported = true; |
| base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| metrics_provider.get(), "ProcessMemoryMetrics", nullptr, options); |
| bool did_insert = |
| @@ -229,9 +262,8 @@ void ProcessMetricsMemoryDumpProvider::RegisterForProcess( |
| void ProcessMetricsMemoryDumpProvider::UnregisterForProcess( |
| base::ProcessId process) { |
| auto iter = g_dump_providers_map.Get().find(process); |
| - if (iter == g_dump_providers_map.Get().end()) { |
| + if (iter == g_dump_providers_map.Get().end()) |
| return; |
| - } |
| base::trace_event::MemoryDumpManager::GetInstance() |
| ->UnregisterAndDeleteDumpProviderSoon(std::move(iter->second)); |
| g_dump_providers_map.Get().erase(iter); |
| @@ -241,9 +273,16 @@ ProcessMetricsMemoryDumpProvider::ProcessMetricsMemoryDumpProvider( |
| base::ProcessId process) |
| : process_(process), |
| process_metrics_(CreateProcessMetrics(process)), |
| - is_rss_peak_resettable_(true) {} |
| + is_rss_peak_resettable_(true) { |
| +#if defined(OS_LINUX) || defined(OS_ANDROID) |
| + proc_statm_file_ = kInvalidFD; |
| +#endif |
| +} |
| -ProcessMetricsMemoryDumpProvider::~ProcessMetricsMemoryDumpProvider() {} |
| +ProcessMetricsMemoryDumpProvider::~ProcessMetricsMemoryDumpProvider() { |
| + // Clear files in case polling was not disabled yet. |
| + SetFastMemoryPollingEnabled(false); |
| +} |
| // Called at trace dump point time. Creates a snapshot of the memory maps for |
| // the current process. |
| @@ -309,4 +348,35 @@ bool ProcessMetricsMemoryDumpProvider::DumpProcessTotals( |
| return true; |
| } |
| +void ProcessMetricsMemoryDumpProvider::PollFastMemoryTotal( |
| + uint64_t* memory_total) { |
| + *memory_total = 0; |
| +#if defined(OS_LINUX) || defined(OS_ANDROID) |
| + if (proc_statm_file_ == kInvalidFD) |
| + proc_statm_file_ = OpenStatmFile(process_); |
| + if (proc_statm_file_ < 0) |
| + return; |
| + |
| + size_t rss = 0, shared = 0; |
| + if (!GetResidentSizesFromStatmFile(proc_statm_file_, &rss, &shared)) |
| + return; |
| + |
| + // When adding total for child processes, do not include "shared" since it |
| + // will be included in the current processes' total. |
| + *memory_total = (process_ == base::kNullProcessId ? rss : rss - shared) * |
|
Primiano Tucci (use gerrit)
2016/12/13 20:02:39
hmm not sure I am convinced here.
The math should
ssid
2016/12/14 02:59:32
Hm but we will miss the shared memory increases if
Primiano Tucci (use gerrit)
2016/12/15 15:00:02
I was suggesting the other way round, *always*coun
ssid
2016/12/16 03:16:41
makes sense. Changed to just resident size.
|
| + base::GetPageSize(); |
| +#else |
| + *memory_total = process_metrics_->GetWorkingSetSize(); |
| +#endif |
| +} |
| + |
| +void ProcessMetricsMemoryDumpProvider::SetFastMemoryPollingEnabled( |
| + bool enabled) { |
| +#if defined(OS_LINUX) || defined(OS_ANDROID) |
| + if (proc_statm_file_ >= 0) |
|
Primiano Tucci (use gerrit)
2016/12/13 20:02:39
Ok I see how doing the auto-opening makes things e
ssid
2016/12/14 02:59:32
It is weird to have SetFastMemoryPollingDisabled m
|
| + close(proc_statm_file_); |
| + proc_statm_file_ = kInvalidFD; |
| +#endif |
| +} |
| + |
| } // namespace tracing |