Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(230)

Side by Side Diff: components/tracing/common/process_metrics_memory_dump_provider.cc

Issue 2568313004: [memory-infra] Implement PollFastMemoryTotal in ProcessMetricsMemoryDumpProvider. (Closed)
Patch Set: Remove memset. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/tracing/common/process_metrics_memory_dump_provider.h" 5 #include "components/tracing/common/process_metrics_memory_dump_provider.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <map> 10 #include <map>
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 if (should_add_current_region) { 148 if (should_add_current_region) {
149 pmm->AddVMRegion(region); 149 pmm->AddVMRegion(region);
150 ++num_valid_regions; 150 ++num_valid_regions;
151 should_add_current_region = false; 151 should_add_current_region = false;
152 } 152 }
153 } 153 }
154 } 154 }
155 } 155 }
156 return num_valid_regions; 156 return num_valid_regions;
157 } 157 }
158
159 int OpenStatmFile(base::ProcessId process) {
Primiano Tucci (use gerrit) 2016/12/15 15:00:02 Since you kept the full SetFastPollingEnabled(bool
ssid 2016/12/16 03:16:41 Done.
160 std::string name =
161 "/proc/" +
162 (process == base::kNullProcessId ? "self" : base::IntToString(process)) +
163 "/statm";
164 return open(name.c_str(), O_RDONLY);
165 }
166
167 bool GetResidentSizesFromStatmFile(int fd,
168 uint64_t* resident_bytes,
169 uint64_t* shared_bytes) {
170 lseek(fd, 0, SEEK_SET);
171 char line[kMaxLineSize];
172 int res = read(fd, line, kMaxLineSize);
Primiano Tucci (use gerrit) 2016/12/15 15:00:02 if you do this, then here you have to pass kMaxLin
ssid 2016/12/16 03:16:41 Done.
173 if (res <= 0)
174 return false;
175 line[res] = '\0';
176 int num_scanned =
177 sscanf(line, "%*s %" SCNu64 " %" SCNu64, resident_bytes, shared_bytes);
178 return num_scanned == 2;
179 }
180
158 #endif // defined(OS_LINUX) || defined(OS_ANDROID) 181 #endif // defined(OS_LINUX) || defined(OS_ANDROID)
159 182
160 std::unique_ptr<base::ProcessMetrics> CreateProcessMetrics( 183 std::unique_ptr<base::ProcessMetrics> CreateProcessMetrics(
161 base::ProcessId process) { 184 base::ProcessId process) {
162 if (process == base::kNullProcessId) 185 if (process == base::kNullProcessId)
163 return base::ProcessMetrics::CreateCurrentProcessMetrics(); 186 return base::ProcessMetrics::CreateCurrentProcessMetrics();
164 #if defined(OS_LINUX) || defined(OS_ANDROID) 187 #if defined(OS_LINUX) || defined(OS_ANDROID)
165 // Just pass ProcessId instead of handle since they are the same in linux and 188 // Just pass ProcessId instead of handle since they are the same in linux and
166 // android. 189 // android.
167 return base::ProcessMetrics::CreateProcessMetrics(process); 190 return base::ProcessMetrics::CreateProcessMetrics(process);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 } 227 }
205 #endif // defined(OS_LINUX) || defined(OS_ANDROID) 228 #endif // defined(OS_LINUX) || defined(OS_ANDROID)
206 229
207 // static 230 // static
208 void ProcessMetricsMemoryDumpProvider::RegisterForProcess( 231 void ProcessMetricsMemoryDumpProvider::RegisterForProcess(
209 base::ProcessId process) { 232 base::ProcessId process) {
210 std::unique_ptr<ProcessMetricsMemoryDumpProvider> metrics_provider( 233 std::unique_ptr<ProcessMetricsMemoryDumpProvider> metrics_provider(
211 new ProcessMetricsMemoryDumpProvider(process)); 234 new ProcessMetricsMemoryDumpProvider(process));
212 base::trace_event::MemoryDumpProvider::Options options; 235 base::trace_event::MemoryDumpProvider::Options options;
213 options.target_pid = process; 236 options.target_pid = process;
237 options.is_fast_polling_supported = true;
214 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( 238 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
215 metrics_provider.get(), "ProcessMemoryMetrics", nullptr, options); 239 metrics_provider.get(), "ProcessMemoryMetrics", nullptr, options);
216 bool did_insert = 240 bool did_insert =
217 g_dump_providers_map.Get() 241 g_dump_providers_map.Get()
218 .insert(std::make_pair(process, std::move(metrics_provider))) 242 .insert(std::make_pair(process, std::move(metrics_provider)))
219 .second; 243 .second;
220 if (!did_insert) { 244 if (!did_insert) {
221 DLOG(ERROR) << "ProcessMetricsMemoryDumpProvider already registered for " 245 DLOG(ERROR) << "ProcessMetricsMemoryDumpProvider already registered for "
222 << (process == base::kNullProcessId 246 << (process == base::kNullProcessId
223 ? "current process" 247 ? "current process"
224 : "process id " + base::IntToString(process)); 248 : "process id " + base::IntToString(process));
225 } 249 }
226 } 250 }
227 251
228 // static 252 // static
229 void ProcessMetricsMemoryDumpProvider::UnregisterForProcess( 253 void ProcessMetricsMemoryDumpProvider::UnregisterForProcess(
230 base::ProcessId process) { 254 base::ProcessId process) {
231 auto iter = g_dump_providers_map.Get().find(process); 255 auto iter = g_dump_providers_map.Get().find(process);
232 if (iter == g_dump_providers_map.Get().end()) { 256 if (iter == g_dump_providers_map.Get().end())
233 return; 257 return;
234 }
235 base::trace_event::MemoryDumpManager::GetInstance() 258 base::trace_event::MemoryDumpManager::GetInstance()
236 ->UnregisterAndDeleteDumpProviderSoon(std::move(iter->second)); 259 ->UnregisterAndDeleteDumpProviderSoon(std::move(iter->second));
237 g_dump_providers_map.Get().erase(iter); 260 g_dump_providers_map.Get().erase(iter);
238 } 261 }
239 262
240 ProcessMetricsMemoryDumpProvider::ProcessMetricsMemoryDumpProvider( 263 ProcessMetricsMemoryDumpProvider::ProcessMetricsMemoryDumpProvider(
241 base::ProcessId process) 264 base::ProcessId process)
242 : process_(process), 265 : process_(process),
243 process_metrics_(CreateProcessMetrics(process)), 266 process_metrics_(CreateProcessMetrics(process)),
244 is_rss_peak_resettable_(true) {} 267 is_rss_peak_resettable_(true) {
268 #if defined(OS_LINUX) || defined(OS_ANDROID)
269 fast_polling_statm_fd_ = -1;
270 #endif
271 }
245 272
246 ProcessMetricsMemoryDumpProvider::~ProcessMetricsMemoryDumpProvider() {} 273 ProcessMetricsMemoryDumpProvider::~ProcessMetricsMemoryDumpProvider() {
274 // Clear files in case polling was not disabled yet.
275 SetFastMemoryPollingEnabled(false);
276 }
247 277
248 // Called at trace dump point time. Creates a snapshot of the memory maps for 278 // Called at trace dump point time. Creates a snapshot of the memory maps for
249 // the current process. 279 // the current process.
250 bool ProcessMetricsMemoryDumpProvider::OnMemoryDump( 280 bool ProcessMetricsMemoryDumpProvider::OnMemoryDump(
251 const base::trace_event::MemoryDumpArgs& args, 281 const base::trace_event::MemoryDumpArgs& args,
252 base::trace_event::ProcessMemoryDump* pmd) { 282 base::trace_event::ProcessMemoryDump* pmd) {
253 bool res = DumpProcessTotals(args, pmd); 283 bool res = DumpProcessTotals(args, pmd);
254 284
255 #if defined(OS_LINUX) || defined(OS_ANDROID) 285 #if defined(OS_LINUX) || defined(OS_ANDROID)
256 if (args.level_of_detail == 286 if (args.level_of_detail ==
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 #endif // !defined(OS_IOS) 332 #endif // !defined(OS_IOS)
303 333
304 pmd->process_totals()->set_resident_set_bytes(rss_bytes); 334 pmd->process_totals()->set_resident_set_bytes(rss_bytes);
305 pmd->set_has_process_totals(); 335 pmd->set_has_process_totals();
306 pmd->process_totals()->set_peak_resident_set_bytes(peak_rss_bytes); 336 pmd->process_totals()->set_peak_resident_set_bytes(peak_rss_bytes);
307 337
308 // Returns true even if other metrics failed, since rss is reported. 338 // Returns true even if other metrics failed, since rss is reported.
309 return true; 339 return true;
310 } 340 }
311 341
342 void ProcessMetricsMemoryDumpProvider::PollFastMemoryTotal(
343 uint64_t* memory_total) {
344 *memory_total = 0;
345 #if defined(OS_LINUX) || defined(OS_ANDROID)
346 if (fast_polling_statm_fd_ == -1)
347 fast_polling_statm_fd_ = OpenStatmFile(process_);
348 if (fast_polling_statm_fd_ < 0)
349 return;
350
351 uint64_t rss = 0, shared = 0;
352 if (!GetResidentSizesFromStatmFile(fast_polling_statm_fd_, &rss, &shared))
353 return;
354
355 // When adding total for child processes, do not include "shared" since it
356 // will be included in the current processes' total.
357 *memory_total = (process_ == base::kNullProcessId ? rss : rss - shared) *
358 base::GetPageSize();
359 #else
360 *memory_total = process_metrics_->GetWorkingSetSize();
361 #endif
362 }
363
364 void ProcessMetricsMemoryDumpProvider::SetFastMemoryPollingEnabled(
365 bool enabled) {
366 #if defined(OS_LINUX) || defined(OS_ANDROID)
367 if (!enabled && fast_polling_statm_fd_ >= 0) {
368 close(fast_polling_statm_fd_);
369 fast_polling_statm_fd_ = -1;
370 }
371 #endif
372 }
373
312 } // namespace tracing 374 } // namespace tracing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698