OLD | NEW |
---|---|
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 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 "base/process_util.h" | 5 #include "base/process_util.h" |
6 | 6 |
7 #include <ctype.h> | 7 #include <ctype.h> |
8 #include <dirent.h> | 8 #include <dirent.h> |
9 #include <fcntl.h> | 9 #include <fcntl.h> |
10 #include <sys/types.h> | 10 #include <sys/types.h> |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
319 return num_pages * getpagesize(); | 319 return num_pages * getpagesize(); |
320 } | 320 } |
321 return 0; | 321 return 0; |
322 } | 322 } |
323 | 323 |
324 size_t ProcessMetrics::GetPrivateBytes() const { | 324 size_t ProcessMetrics::GetPrivateBytes() const { |
325 // http://crbug.com/16251 | 325 // http://crbug.com/16251 |
326 return 0; | 326 return 0; |
327 } | 327 } |
328 | 328 |
329 void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const { | |
330 FilePath stat_file = | |
331 FilePath("/proc").Append(IntToString(process_)).Append("maps"); | |
Joel Stanley (old)
2009/08/03 16:02:37
The other functions that scrape /proc/<pid> use sm
| |
332 std::string maps; | |
333 size_t file_mapped_size = 0; | |
334 size_t anon_size = 0; | |
335 size_t private_size = 0; | |
Evan Martin
2009/08/03 05:16:11
you can declare these variables closer to where th
| |
336 if (!file_util::ReadFileToString(stat_file, &maps)) | |
Evan Martin
2009/08/03 05:16:11
should this error case fill in |usage| since the c
| |
337 return; | |
338 | |
339 std::vector<std::string> map_lines; | |
340 SplitString(maps, '\n', &map_lines); | |
341 for (std::vector<std::string>::iterator iter = map_lines.begin(); | |
342 iter != map_lines.end(); ++iter) { | |
343 if (*iter == "") { | |
344 continue; | |
345 } | |
346 | |
347 std::vector<std::string> fields; | |
348 SplitString(*iter, ' ', &fields); | |
349 if (fields.size() < 5) { | |
350 LOG(ERROR) << "Badly formatted /proc/*/maps line: " << *iter; | |
351 continue; | |
352 } | |
353 | |
354 // First fields is memory range, which gives us size. Formatted as: | |
355 // XXXXXXXX-XXXXXXXX | |
356 unsigned int sep_pos = fields[0].find('-'); | |
Evan Martin
2009/08/03 05:16:11
string::size_type here, i guess
| |
357 if (sep_pos == std::string::npos) { | |
358 LOG(ERROR) << "Badly formatted address range: " << fields[0]; | |
359 continue; | |
360 } | |
361 int address_begin = HexStringToInt(fields[0].substr(0, sep_pos)); | |
362 int address_end = HexStringToInt(fields[0].substr(sep_pos + 1)); | |
363 if (address_end < address_begin) | |
364 continue; | |
365 size_t size = address_end - address_begin; | |
366 | |
367 // Second field is permissions formatted as: | |
368 // [r-][w-][x-][ps] | |
Evan Martin
2009/08/03 05:16:11
I think you have regex syntax here, right? might
| |
369 // Where: | |
370 // r = read | |
371 // w = write | |
372 // x = execute | |
373 // p = private | |
374 // s = shared | |
375 if (fields[1][3] == 'p') | |
376 private_size += size; | |
377 | |
378 // Fifth field is inode. If non-zero, this memory region is mapped by a | |
379 // file. | |
380 int inode = 0; | |
381 StringToInt(fields[4], &inode); | |
382 if (inode) { | |
383 file_mapped_size += size; | |
384 } else { | |
385 anon_size += size; | |
386 } | |
387 } | |
388 | |
389 usage->priv = private_size / 1024; | |
390 usage->image = file_mapped_size / 1024; | |
391 usage->mapped = anon_size / 1024; | |
392 } | |
393 | |
329 // Private and Shared working set sizes are obtained from /proc/<pid>/smaps, | 394 // Private and Shared working set sizes are obtained from /proc/<pid>/smaps, |
330 // as in http://www.pixelbeat.org/scripts/ps_mem.py | 395 // as in http://www.pixelbeat.org/scripts/ps_mem.py |
331 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { | 396 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { |
332 FilePath stat_file = | 397 FilePath stat_file = |
333 FilePath("/proc").Append(IntToString(process_)).Append("smaps"); | 398 FilePath("/proc").Append(IntToString(process_)).Append("smaps"); |
334 std::string smaps; | 399 std::string smaps; |
335 int shared_kb = 0; | 400 int shared_kb = 0; |
336 int private_kb = 0; | 401 int private_kb = 0; |
337 int pss_kb = 0; | 402 int pss_kb = 0; |
338 bool have_pss = false; | 403 bool have_pss = false; |
(...skipping 21 matching lines...) Expand all Loading... | |
360 private_kb += StringToInt(tokenizer.token()); | 425 private_kb += StringToInt(tokenizer.token()); |
361 } else if (StartsWithASCII(last_key_name, "Pss", 1)) { | 426 } else if (StartsWithASCII(last_key_name, "Pss", 1)) { |
362 have_pss = true; | 427 have_pss = true; |
363 pss_kb += StringToInt(tokenizer.token()) + kPssAdjust; | 428 pss_kb += StringToInt(tokenizer.token()) + kPssAdjust; |
364 } | 429 } |
365 state = KEY_NAME; | 430 state = KEY_NAME; |
366 break; | 431 break; |
367 } | 432 } |
368 } | 433 } |
369 ws_usage->priv = private_kb; | 434 ws_usage->priv = private_kb; |
370 // Sharable is not calculated, as it does not provide interesting data. | |
371 ws_usage->shareable = 0; | |
372 if (have_pss) { | 435 if (have_pss) { |
373 ws_usage->shared = pss_kb - private_kb; | 436 ws_usage->shared = pss_kb - private_kb; |
374 } else { | 437 } else { |
375 ws_usage->shared = shared_kb; | 438 ws_usage->shared = shared_kb; |
376 } | 439 } |
440 // Shared pages are sharable, so even if this isn't that useful, fill it in | |
441 // with the most sensible value since the about:memory handler page needs it. | |
442 ws_usage->shareable = ws_usage->shared; | |
Joel Stanley (old)
2009/08/03 16:02:37
from chrome/browser/resources/about_memory.html, w
| |
377 return true; | 443 return true; |
378 } | 444 } |
379 | 445 |
380 // To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING | 446 // To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING |
381 // in your kernel configuration. | 447 // in your kernel configuration. |
382 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { | 448 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { |
383 std::string proc_io_contents; | 449 std::string proc_io_contents; |
384 FilePath io_file("/proc"); | 450 FilePath io_file("/proc"); |
385 io_file = io_file.Append(IntToString(process_)); | 451 io_file = io_file.Append(IntToString(process_)); |
386 io_file = io_file.Append("io"); | 452 io_file = io_file.Append("io"); |
(...skipping 24 matching lines...) Expand all Loading... | |
411 (*io_counters).WriteTransferCount = StringToInt64(tokenizer.token()); | 477 (*io_counters).WriteTransferCount = StringToInt64(tokenizer.token()); |
412 } | 478 } |
413 state = KEY_NAME; | 479 state = KEY_NAME; |
414 break; | 480 break; |
415 } | 481 } |
416 } | 482 } |
417 return true; | 483 return true; |
418 } | 484 } |
419 | 485 |
420 } // namespace base | 486 } // namespace base |
OLD | NEW |