OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/process_metrics.h" | 5 #include "base/process/process_metrics.h" |
6 | 6 |
7 #include <dirent.h> | 7 #include <dirent.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 #include <sys/time.h> | 10 #include <sys/time.h> |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 // ... | 414 // ... |
415 const size_t kMemTotalIndex = 1; | 415 const size_t kMemTotalIndex = 1; |
416 const size_t kMemFreeIndex = 4; | 416 const size_t kMemFreeIndex = 4; |
417 const size_t kMemBuffersIndex = 7; | 417 const size_t kMemBuffersIndex = 7; |
418 const size_t kMemCachedIndex = 10; | 418 const size_t kMemCachedIndex = 10; |
419 const size_t kMemActiveAnonIndex = 22; | 419 const size_t kMemActiveAnonIndex = 22; |
420 const size_t kMemInactiveAnonIndex = 25; | 420 const size_t kMemInactiveAnonIndex = 25; |
421 const size_t kMemActiveFileIndex = 28; | 421 const size_t kMemActiveFileIndex = 28; |
422 const size_t kMemInactiveFileIndex = 31; | 422 const size_t kMemInactiveFileIndex = 31; |
423 | 423 |
| 424 // The format of /proc/diskstats is: |
| 425 // Device major number |
| 426 // Device minor number |
| 427 // Device name |
| 428 // Field 1 -- # of reads completed |
| 429 // This is the total number of reads completed successfully. |
| 430 // Field 2 -- # of reads merged, field 6 -- # of writes merged |
| 431 // Reads and writes which are adjacent to each other may be merged for |
| 432 // efficiency. Thus two 4K reads may become one 8K read before it is |
| 433 // ultimately handed to the disk, and so it will be counted (and queued) |
| 434 // as only one I/O. This field lets you know how often this was done. |
| 435 // Field 3 -- # of sectors read |
| 436 // This is the total number of sectors read successfully. |
| 437 // Field 4 -- # of milliseconds spent reading |
| 438 // This is the total number of milliseconds spent by all reads (as |
| 439 // measured from __make_request() to end_that_request_last()). |
| 440 // Field 5 -- # of writes completed |
| 441 // This is the total number of writes completed successfully. |
| 442 // Field 6 -- # of writes merged |
| 443 // See the description of field 2. |
| 444 // Field 7 -- # of sectors written |
| 445 // This is the total number of sectors written successfully. |
| 446 // Field 8 -- # of milliseconds spent writing |
| 447 // This is the total number of milliseconds spent by all writes (as |
| 448 // measured from __make_request() to end_that_request_last()). |
| 449 // Field 9 -- # of I/Os currently in progress |
| 450 // The only field that should go to zero. Incremented as requests are |
| 451 // given to appropriate struct request_queue and decremented as they |
| 452 // finish. |
| 453 // Field 10 -- # of milliseconds spent doing I/Os |
| 454 // This field increases so long as field 9 is nonzero. |
| 455 // Field 11 -- weighted # of milliseconds spent doing I/Os |
| 456 // This field is incremented at each I/O start, I/O completion, I/O |
| 457 // merge, or read of these stats by the number of I/Os in progress |
| 458 // (field 9) times the number of milliseconds spent doing I/O since the |
| 459 // last update of this field. This can provide an easy measure of both |
| 460 // I/O completion time and the backlog that may be accumulating. |
| 461 |
| 462 const size_t kDiskDriveName = 2; |
| 463 const size_t kDiskReads = 3; |
| 464 const size_t kDiskReadsMerged = 4; |
| 465 const size_t kDiskSectorsRead = 5; |
| 466 const size_t kDiskReadTime = 6; |
| 467 const size_t kDiskWrites = 7; |
| 468 const size_t kDiskWritesMerged = 8; |
| 469 const size_t kDiskSectorsWritten = 9; |
| 470 const size_t kDiskWriteTime = 10; |
| 471 const size_t kDiskIO = 11; |
| 472 const size_t kDiskIOTime = 12; |
| 473 const size_t kDiskWeightedIOTime = 13; |
| 474 |
424 } // namespace | 475 } // namespace |
425 | 476 |
426 SystemMemoryInfoKB::SystemMemoryInfoKB() | 477 SystemMemoryInfoKB::SystemMemoryInfoKB() |
427 : total(0), | 478 : total(0), |
428 free(0), | 479 free(0), |
429 buffers(0), | 480 buffers(0), |
430 cached(0), | 481 cached(0), |
431 active_anon(0), | 482 active_anon(0), |
432 inactive_anon(0), | 483 inactive_anon(0), |
433 active_file(0), | 484 active_file(0), |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 int num_res = sscanf(mali_memory_data.c_str(), "%lld bytes", &mali_size); | 571 int num_res = sscanf(mali_memory_data.c_str(), "%lld bytes", &mali_size); |
521 if (num_res == 1) | 572 if (num_res == 1) |
522 meminfo->gem_size += mali_size; | 573 meminfo->gem_size += mali_size; |
523 } | 574 } |
524 #endif // defined(ARCH_CPU_ARM_FAMILY) | 575 #endif // defined(ARCH_CPU_ARM_FAMILY) |
525 #endif // defined(OS_CHROMEOS) | 576 #endif // defined(OS_CHROMEOS) |
526 | 577 |
527 return true; | 578 return true; |
528 } | 579 } |
529 | 580 |
| 581 SystemDiskInfo::SystemDiskInfo() { |
| 582 reads = 0; |
| 583 reads_merged = 0; |
| 584 sectors_read = 0; |
| 585 read_time = 0; |
| 586 writes = 0; |
| 587 writes_merged = 0; |
| 588 sectors_written = 0; |
| 589 write_time = 0; |
| 590 io = 0; |
| 591 io_time = 0; |
| 592 weighted_io_time = 0; |
| 593 } |
| 594 |
| 595 bool IsValidDiskName(const std::string& candidate) { |
| 596 if (candidate.length() < 3) |
| 597 return false; |
| 598 if (candidate.substr(0,2) == "sd" || candidate.substr(0,2) == "hd") { |
| 599 // [sh]d[a-z]+ case |
| 600 for (size_t i = 2; i < candidate.length(); i++) { |
| 601 if (!islower(candidate[i])) |
| 602 return false; |
| 603 } |
| 604 } else { |
| 605 if (candidate.length() < 7) { |
| 606 return false; |
| 607 } |
| 608 if (candidate.substr(0,6) == "mmcblk") { |
| 609 // mmcblk[0-9]+ case |
| 610 for (size_t i = 6; i < candidate.length(); i++) { |
| 611 if (!isdigit(candidate[i])) |
| 612 return false; |
| 613 } |
| 614 } else { |
| 615 return false; |
| 616 } |
| 617 } |
| 618 |
| 619 return true; |
| 620 } |
| 621 |
| 622 bool GetSystemDiskInfo(SystemDiskInfo* diskinfo) { |
| 623 // Synchronously reading files in /proc is safe. |
| 624 ThreadRestrictions::ScopedAllowIO allow_io; |
| 625 |
| 626 FilePath diskinfo_file("/proc/diskstats"); |
| 627 std::string diskinfo_data; |
| 628 if (!ReadFileToString(diskinfo_file, &diskinfo_data)) { |
| 629 DLOG(WARNING) << "Failed to open " << diskinfo_file.value(); |
| 630 return false; |
| 631 } |
| 632 |
| 633 std::vector<std::string> diskinfo_lines; |
| 634 size_t line_count = Tokenize(diskinfo_data, "\n", &diskinfo_lines); |
| 635 if (line_count == 0) { |
| 636 DLOG(WARNING) << "No lines found"; |
| 637 return false; |
| 638 } |
| 639 |
| 640 diskinfo->reads = 0; |
| 641 diskinfo->reads_merged = 0; |
| 642 diskinfo->sectors_read = 0; |
| 643 diskinfo->read_time = 0; |
| 644 diskinfo->writes = 0; |
| 645 diskinfo->writes_merged = 0; |
| 646 diskinfo->sectors_written = 0; |
| 647 diskinfo->write_time = 0; |
| 648 diskinfo->io = 0; |
| 649 diskinfo->io_time = 0; |
| 650 diskinfo->weighted_io_time = 0; |
| 651 |
| 652 uint64 reads = 0; |
| 653 uint64 reads_merged = 0; |
| 654 uint64 sectors_read = 0; |
| 655 uint64 read_time = 0; |
| 656 uint64 writes = 0; |
| 657 uint64 writes_merged = 0; |
| 658 uint64 sectors_written = 0; |
| 659 uint64 write_time = 0; |
| 660 uint64 io = 0; |
| 661 uint64 io_time = 0; |
| 662 uint64 weighted_io_time = 0; |
| 663 |
| 664 for (size_t i = 0; i < line_count; i++) { |
| 665 std::vector<std::string> disk_fields; |
| 666 SplitStringAlongWhitespace(diskinfo_lines[i], &disk_fields); |
| 667 |
| 668 // Fields may have overflowed and reset to zero. |
| 669 if (IsValidDiskName(disk_fields[kDiskDriveName])) { |
| 670 StringToUint64(disk_fields[kDiskReads], &reads); |
| 671 StringToUint64(disk_fields[kDiskReadsMerged], &reads_merged); |
| 672 StringToUint64(disk_fields[kDiskSectorsRead], §ors_read); |
| 673 StringToUint64(disk_fields[kDiskReadTime], &read_time); |
| 674 StringToUint64(disk_fields[kDiskWrites], &writes); |
| 675 StringToUint64(disk_fields[kDiskWritesMerged], &writes_merged); |
| 676 StringToUint64(disk_fields[kDiskSectorsWritten], §ors_written); |
| 677 StringToUint64(disk_fields[kDiskWriteTime], &write_time); |
| 678 StringToUint64(disk_fields[kDiskIO], &io); |
| 679 StringToUint64(disk_fields[kDiskIOTime], &io_time); |
| 680 StringToUint64(disk_fields[kDiskWeightedIOTime], &weighted_io_time); |
| 681 |
| 682 diskinfo->reads += reads; |
| 683 diskinfo->reads_merged += reads_merged; |
| 684 diskinfo->sectors_read += sectors_read; |
| 685 diskinfo->read_time += read_time; |
| 686 diskinfo->writes += writes; |
| 687 diskinfo->writes_merged += writes_merged; |
| 688 diskinfo->sectors_written += sectors_written; |
| 689 diskinfo->write_time += write_time; |
| 690 diskinfo->io += io; |
| 691 diskinfo->io_time += io_time; |
| 692 diskinfo->weighted_io_time += weighted_io_time; |
| 693 } |
| 694 } |
| 695 |
| 696 return true; |
| 697 } |
| 698 |
530 #if defined(OS_CHROMEOS) | 699 #if defined(OS_CHROMEOS) |
531 void GetSwapInfo(SwapInfo* swap_info) { | 700 void GetSwapInfo(SwapInfo* swap_info) { |
532 // Synchronously reading files in /sys/block/zram0 is safe. | 701 // Synchronously reading files in /sys/block/zram0 is safe. |
533 ThreadRestrictions::ScopedAllowIO allow_io; | 702 ThreadRestrictions::ScopedAllowIO allow_io; |
534 | 703 |
535 base::FilePath zram_path("/sys/block/zram0"); | 704 base::FilePath zram_path("/sys/block/zram0"); |
536 uint64 orig_data_size = ReadFileToUint64(zram_path.Append("orig_data_size")); | 705 uint64 orig_data_size = ReadFileToUint64(zram_path.Append("orig_data_size")); |
537 if (orig_data_size <= 4096) { | 706 if (orig_data_size <= 4096) { |
538 // A single page is compressed at startup, and has a high compression | 707 // A single page is compressed at startup, and has a high compression |
539 // ratio. We ignore this as it doesn't indicate any real swapping. | 708 // ratio. We ignore this as it doesn't indicate any real swapping. |
540 swap_info->orig_data_size = 0; | 709 swap_info->orig_data_size = 0; |
541 swap_info->num_reads = 0; | 710 swap_info->num_reads = 0; |
542 swap_info->num_writes = 0; | 711 swap_info->num_writes = 0; |
543 swap_info->compr_data_size = 0; | 712 swap_info->compr_data_size = 0; |
544 swap_info->mem_used_total = 0; | 713 swap_info->mem_used_total = 0; |
545 return; | 714 return; |
546 } | 715 } |
547 swap_info->orig_data_size = orig_data_size; | 716 swap_info->orig_data_size = orig_data_size; |
548 swap_info->num_reads = ReadFileToUint64(zram_path.Append("num_reads")); | 717 swap_info->num_reads = ReadFileToUint64(zram_path.Append("num_reads")); |
549 swap_info->num_writes = ReadFileToUint64(zram_path.Append("num_writes")); | 718 swap_info->num_writes = ReadFileToUint64(zram_path.Append("num_writes")); |
550 swap_info->compr_data_size = | 719 swap_info->compr_data_size = |
551 ReadFileToUint64(zram_path.Append("compr_data_size")); | 720 ReadFileToUint64(zram_path.Append("compr_data_size")); |
552 swap_info->mem_used_total = | 721 swap_info->mem_used_total = |
553 ReadFileToUint64(zram_path.Append("mem_used_total")); | 722 ReadFileToUint64(zram_path.Append("mem_used_total")); |
554 } | 723 } |
555 #endif // defined(OS_CHROMEOS) | 724 #endif // defined(OS_CHROMEOS) |
556 | 725 |
557 } // namespace base | 726 } // namespace base |
OLD | NEW |