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 |