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 71c929f10fb092f5771bf42d70a2512d4fdbb818..96d35a37e1f6cc1b18ea549902b6ae1e312a66aa 100644 |
| --- a/components/tracing/common/process_metrics_memory_dump_provider.cc |
| +++ b/components/tracing/common/process_metrics_memory_dump_provider.cc |
| @@ -155,6 +155,18 @@ uint32_t ReadLinuxProcSmapsFile(FILE* smaps_file, |
| } |
| return num_valid_regions; |
| } |
| + |
| +bool GetResidentSizeFromStatmFile(int fd, uint64_t* resident_pages) { |
| + lseek(fd, 0, SEEK_SET); |
| + char line[kMaxLineSize]; |
| + int res = read(fd, line, kMaxLineSize - 1); |
| + if (res <= 0) |
| + return false; |
| + line[res] = '\0'; |
| + int num_scanned = sscanf(line, "%*s %" SCNu64, resident_pages); |
| + return num_scanned == 1; |
| +} |
| + |
| #endif // defined(OS_LINUX) || defined(OS_ANDROID) |
| std::unique_ptr<base::ProcessMetrics> CreateProcessMetrics( |
| @@ -183,6 +195,9 @@ uint64_t ProcessMetricsMemoryDumpProvider::rss_bytes_for_testing = 0; |
| // static |
| FILE* ProcessMetricsMemoryDumpProvider::proc_smaps_for_testing = nullptr; |
| +// static |
| +int ProcessMetricsMemoryDumpProvider::fast_polling_statm_fd_for_testing = -1; |
| + |
| bool ProcessMetricsMemoryDumpProvider::DumpProcessMemoryMaps( |
| const base::trace_event::MemoryDumpArgs& args, |
| base::trace_event::ProcessMemoryDump* pmd) { |
| @@ -211,6 +226,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 +245,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 +256,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) |
| + fast_polling_statm_fd_ = -1; |
| +#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. |
| @@ -322,4 +344,43 @@ bool ProcessMetricsMemoryDumpProvider::DumpProcessTotals( |
| return true; |
| } |
| +void ProcessMetricsMemoryDumpProvider::PollFastMemoryTotal( |
| + uint64_t* memory_total) { |
| + *memory_total = 0; |
| +#if defined(OS_LINUX) || defined(OS_ANDROID) |
| + int statm_fd = fast_polling_statm_fd_for_testing == -1 |
| + ? fast_polling_statm_fd_ |
| + : fast_polling_statm_fd_for_testing; |
| + if (statm_fd < 0) |
| + return; |
| + |
| + uint64_t rss_pages = 0; |
| + if (!GetResidentSizeFromStatmFile(statm_fd, &rss_pages)) |
| + return; |
| + |
| + // When adding total for child processes, do not include "shared" since it |
| + // will be included in the current processes' total. |
| + *memory_total = rss_pages * base::GetPageSize(); |
|
Primiano Tucci (use gerrit)
2016/12/16 11:50:40
base::GetPageSize() is a bit silly because makes a
ssid
2016/12/16 19:48:44
Done.
|
| +#else |
| + *memory_total = process_metrics_->GetWorkingSetSize(); |
| +#endif |
| +} |
| + |
| +void ProcessMetricsMemoryDumpProvider::SetFastMemoryPollingEnabled( |
| + bool enabled) { |
| +#if defined(OS_LINUX) || defined(OS_ANDROID) |
| + if (enabled) { |
| + DCHECK(fast_polling_statm_fd_); |
|
Primiano Tucci (use gerrit)
2016/12/16 11:50:40
I think you really mean here:
DCHECK_EQ(-1, fast_p
ssid
2016/12/16 19:48:44
Yes i meant eq -1. But removed this now.
|
| + std::string name = "/proc/" + (process_ == base::kNullProcessId |
| + ? "self" |
| + : base::IntToString(process_)) + |
| + "/statm"; |
| + fast_polling_statm_fd_ = open(name.c_str(), O_RDONLY); |
|
Primiano Tucci (use gerrit)
2016/12/16 11:50:40
I'd add a DCHECK_GE(fast_polling_statm_fd_, 0);
at
ssid
2016/12/16 19:48:44
Done.
|
| + } else if (fast_polling_statm_fd_ >= 0) { |
| + close(fast_polling_statm_fd_); |
| + fast_polling_statm_fd_ = -1; |
| + } |
| +#endif |
| +} |
| + |
| } // namespace tracing |