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

Side by Side Diff: base/process/process_metrics_linux.cc

Issue 549753002: Cleanup bits of base::ProcessMetrics. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix a comment Created 6 years, 3 months 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
« no previous file with comments | « base/process/process_metrics.cc ('k') | base/process/process_metrics_mac.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
11 #include <sys/types.h> 11 #include <sys/types.h>
12 #include <unistd.h> 12 #include <unistd.h>
13 13
14 #include "base/files/file_util.h" 14 #include "base/files/file_util.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/process/internal_linux.h" 16 #include "base/process/internal_linux.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_split.h" 18 #include "base/strings/string_split.h"
19 #include "base/strings/string_tokenizer.h" 19 #include "base/strings/string_tokenizer.h"
20 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
21 #include "base/sys_info.h" 21 #include "base/sys_info.h"
22 #include "base/threading/thread_restrictions.h" 22 #include "base/threading/thread_restrictions.h"
23 23
24 namespace base { 24 namespace base {
25 25
26 namespace { 26 namespace {
27 27
28 enum ParsingState { 28 #if defined(OS_CHROMEOS)
29 KEY_NAME,
30 KEY_VALUE
31 };
32
33 #ifdef OS_CHROMEOS
34 // Read a file with a single number string and return the number as a uint64. 29 // Read a file with a single number string and return the number as a uint64.
35 static uint64 ReadFileToUint64(const base::FilePath file) { 30 static uint64 ReadFileToUint64(const FilePath file) {
36 std::string file_as_string; 31 std::string file_as_string;
37 if (!ReadFileToString(file, &file_as_string)) 32 if (!ReadFileToString(file, &file_as_string))
38 return 0; 33 return 0;
39 base::TrimWhitespaceASCII(file_as_string, base::TRIM_ALL, &file_as_string); 34 TrimWhitespaceASCII(file_as_string, TRIM_ALL, &file_as_string);
40 uint64 file_as_uint64 = 0; 35 uint64 file_as_uint64 = 0;
41 if (!base::StringToUint64(file_as_string, &file_as_uint64)) 36 if (!StringToUint64(file_as_string, &file_as_uint64))
42 return 0; 37 return 0;
43 return file_as_uint64; 38 return file_as_uint64;
44 } 39 }
45 #endif 40 #endif
46 41
47 // Read /proc/<pid>/status and returns the value for |field|, or 0 on failure. 42 // Read /proc/<pid>/status and return the value for |field|, or 0 on failure.
48 // Only works for fields in the form of "Field: value kB". 43 // Only works for fields in the form of "Field: value kB".
49 size_t ReadProcStatusAndGetFieldAsSizeT(pid_t pid, const std::string& field) { 44 size_t ReadProcStatusAndGetFieldAsSizeT(pid_t pid, const std::string& field) {
50 FilePath stat_file = internal::GetProcPidDir(pid).Append("status");
51 std::string status; 45 std::string status;
52 { 46 {
53 // Synchronously reading files in /proc is safe. 47 // Synchronously reading files in /proc is safe.
54 ThreadRestrictions::ScopedAllowIO allow_io; 48 ThreadRestrictions::ScopedAllowIO allow_io;
49 FilePath stat_file = internal::GetProcPidDir(pid).Append("status");
55 if (!ReadFileToString(stat_file, &status)) 50 if (!ReadFileToString(stat_file, &status))
56 return 0; 51 return 0;
57 } 52 }
58 53
59 StringTokenizer tokenizer(status, ":\n"); 54 std::vector<std::pair<std::string, std::string> > pairs;
60 ParsingState state = KEY_NAME; 55 SplitStringIntoKeyValuePairs(status, ':', '\n', &pairs);
61 StringPiece last_key_name; 56 for (size_t i = 0; i < pairs.size(); ++i) {
62 while (tokenizer.GetNext()) { 57 std::string key, value_str;
63 switch (state) { 58 TrimWhitespaceASCII(pairs[i].first, TRIM_ALL, &key);
64 case KEY_NAME: 59 TrimWhitespaceASCII(pairs[i].second, TRIM_ALL, &value_str);
65 last_key_name = tokenizer.token_piece(); 60 if (key == field) {
66 state = KEY_VALUE; 61 std::vector<std::string> split_value_str;
67 break; 62 SplitString(value_str, ' ', &split_value_str);
68 case KEY_VALUE: 63 if (split_value_str.size() != 2 || split_value_str[1] != "kB") {
69 DCHECK(!last_key_name.empty()); 64 NOTREACHED();
70 if (last_key_name == field) { 65 return 0;
71 std::string value_str; 66 }
72 tokenizer.token_piece().CopyToString(&value_str); 67 size_t value;
73 std::string value_str_trimmed; 68 if (!StringToSizeT(split_value_str[0], &value)) {
74 base::TrimWhitespaceASCII(value_str, base::TRIM_ALL, 69 NOTREACHED();
75 &value_str_trimmed); 70 return 0;
76 std::vector<std::string> split_value_str; 71 }
77 SplitString(value_str_trimmed, ' ', &split_value_str); 72 return value;
78 if (split_value_str.size() != 2 || split_value_str[1] != "kB") {
79 NOTREACHED();
80 return 0;
81 }
82 size_t value;
83 if (!StringToSizeT(split_value_str[0], &value)) {
84 NOTREACHED();
85 return 0;
86 }
87 return value;
88 }
89 state = KEY_NAME;
90 break;
91 } 73 }
92 } 74 }
93 NOTREACHED(); 75 NOTREACHED();
94 return 0; 76 return 0;
95 } 77 }
96 78
97 // Get the total CPU of a single process. Return value is number of jiffies 79 // Get the total CPU of a single process. Return value is number of jiffies
98 // on success or -1 on error. 80 // on success or -1 on error.
99 int GetProcessCPU(pid_t pid) { 81 int GetProcessCPU(pid_t pid) {
100 // Use /proc/<pid>/task to find all threads and parse their /stat file. 82 // Use /proc/<pid>/task to find all threads and parse their /stat file.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 // in your kernel configuration. 198 // in your kernel configuration.
217 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { 199 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
218 // Synchronously reading files in /proc is safe. 200 // Synchronously reading files in /proc is safe.
219 ThreadRestrictions::ScopedAllowIO allow_io; 201 ThreadRestrictions::ScopedAllowIO allow_io;
220 202
221 std::string proc_io_contents; 203 std::string proc_io_contents;
222 FilePath io_file = internal::GetProcPidDir(process_).Append("io"); 204 FilePath io_file = internal::GetProcPidDir(process_).Append("io");
223 if (!ReadFileToString(io_file, &proc_io_contents)) 205 if (!ReadFileToString(io_file, &proc_io_contents))
224 return false; 206 return false;
225 207
226 (*io_counters).OtherOperationCount = 0; 208 io_counters->OtherOperationCount = 0;
227 (*io_counters).OtherTransferCount = 0; 209 io_counters->OtherTransferCount = 0;
228 210
229 StringTokenizer tokenizer(proc_io_contents, ": \n"); 211 std::vector<std::pair<std::string, std::string> > pairs;
230 ParsingState state = KEY_NAME; 212 SplitStringIntoKeyValuePairs(proc_io_contents, ':', '\n', &pairs);
231 StringPiece last_key_name; 213 for (size_t i = 0; i < pairs.size(); ++i) {
232 while (tokenizer.GetNext()) { 214 std::string key, value_str;
233 switch (state) { 215 TrimWhitespaceASCII(pairs[i].first, TRIM_ALL, &key);
234 case KEY_NAME: 216 TrimWhitespaceASCII(pairs[i].second, TRIM_ALL, &value_str);
235 last_key_name = tokenizer.token_piece(); 217 uint64* target_counter = NULL;
236 state = KEY_VALUE; 218 if (key == "syscr")
237 break; 219 target_counter = &io_counters->ReadOperationCount;
238 case KEY_VALUE: 220 else if (key == "syscw")
239 DCHECK(!last_key_name.empty()); 221 target_counter = &io_counters->WriteOperationCount;
240 if (last_key_name == "syscr") { 222 else if (key == "rchar")
241 StringToInt64(tokenizer.token_piece(), 223 target_counter = &io_counters->ReadTransferCount;
242 reinterpret_cast<int64*>(&(*io_counters).ReadOperationCount)); 224 else if (key == "wchar")
243 } else if (last_key_name == "syscw") { 225 target_counter = &io_counters->WriteTransferCount;
244 StringToInt64(tokenizer.token_piece(), 226 if (!target_counter)
245 reinterpret_cast<int64*>(&(*io_counters).WriteOperationCount)); 227 continue;
246 } else if (last_key_name == "rchar") { 228 bool converted = StringToUint64(value_str, target_counter);
247 StringToInt64(tokenizer.token_piece(), 229 DCHECK(converted);
248 reinterpret_cast<int64*>(&(*io_counters).ReadTransferCount));
249 } else if (last_key_name == "wchar") {
250 StringToInt64(tokenizer.token_piece(),
251 reinterpret_cast<int64*>(&(*io_counters).WriteTransferCount));
252 }
253 state = KEY_NAME;
254 break;
255 }
256 } 230 }
257 return true; 231 return true;
258 } 232 }
259 233
260 ProcessMetrics::ProcessMetrics(ProcessHandle process) 234 ProcessMetrics::ProcessMetrics(ProcessHandle process)
261 : process_(process), 235 : process_(process),
262 last_system_time_(0), 236 last_system_time_(0),
263 last_cpu_(0) { 237 last_cpu_(0) {
264 processor_count_ = base::SysInfo::NumberOfProcessors(); 238 processor_count_ = SysInfo::NumberOfProcessors();
265 } 239 }
266 240
267 #if defined(OS_CHROMEOS) 241 #if defined(OS_CHROMEOS)
268 // Private, Shared and Proportional working set sizes are obtained from 242 // Private, Shared and Proportional working set sizes are obtained from
269 // /proc/<pid>/totmaps 243 // /proc/<pid>/totmaps
270 bool ProcessMetrics::GetWorkingSetKBytesTotmaps(WorkingSetKBytes *ws_usage) 244 bool ProcessMetrics::GetWorkingSetKBytesTotmaps(WorkingSetKBytes *ws_usage)
271 const { 245 const {
272 // The format of /proc/<pid>/totmaps is: 246 // The format of /proc/<pid>/totmaps is:
273 // 247 //
274 // Rss: 6120 kB 248 // Rss: 6120 kB
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 447
474 #ifdef OS_CHROMEOS 448 #ifdef OS_CHROMEOS
475 shmem = 0; 449 shmem = 0;
476 slab = 0; 450 slab = 0;
477 gem_objects = -1; 451 gem_objects = -1;
478 gem_size = -1; 452 gem_size = -1;
479 #endif 453 #endif
480 } 454 }
481 455
482 scoped_ptr<Value> SystemMemoryInfoKB::ToValue() const { 456 scoped_ptr<Value> SystemMemoryInfoKB::ToValue() const {
483 scoped_ptr<DictionaryValue> res(new base::DictionaryValue()); 457 scoped_ptr<DictionaryValue> res(new DictionaryValue());
484 458
485 res->SetInteger("total", total); 459 res->SetInteger("total", total);
486 res->SetInteger("free", free); 460 res->SetInteger("free", free);
487 res->SetInteger("buffers", buffers); 461 res->SetInteger("buffers", buffers);
488 res->SetInteger("cached", cached); 462 res->SetInteger("cached", cached);
489 res->SetInteger("active_anon", active_anon); 463 res->SetInteger("active_anon", active_anon);
490 res->SetInteger("inactive_anon", inactive_anon); 464 res->SetInteger("inactive_anon", inactive_anon);
491 res->SetInteger("active_file", active_file); 465 res->SetInteger("active_file", active_file);
492 res->SetInteger("inactive_file", inactive_file); 466 res->SetInteger("inactive_file", inactive_file);
493 res->SetInteger("swap_total", swap_total); 467 res->SetInteger("swap_total", swap_total);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 meminfo->total = 0; 499 meminfo->total = 0;
526 500
527 std::vector<std::string> meminfo_lines; 501 std::vector<std::string> meminfo_lines;
528 Tokenize(meminfo_data, "\n", &meminfo_lines); 502 Tokenize(meminfo_data, "\n", &meminfo_lines);
529 for (std::vector<std::string>::iterator it = meminfo_lines.begin(); 503 for (std::vector<std::string>::iterator it = meminfo_lines.begin();
530 it != meminfo_lines.end(); ++it) { 504 it != meminfo_lines.end(); ++it) {
531 std::vector<std::string> tokens; 505 std::vector<std::string> tokens;
532 SplitStringAlongWhitespace(*it, &tokens); 506 SplitStringAlongWhitespace(*it, &tokens);
533 // HugePages_* only has a number and no suffix so we can't rely on 507 // HugePages_* only has a number and no suffix so we can't rely on
534 // there being exactly 3 tokens. 508 // there being exactly 3 tokens.
535 if (tokens.size() > 1) { 509 if (tokens.size() <= 1) {
536 if (tokens[0] == "MemTotal:") {
537 StringToInt(tokens[1], &meminfo->total);
538 continue;
539 } if (tokens[0] == "MemFree:") {
540 StringToInt(tokens[1], &meminfo->free);
541 continue;
542 } if (tokens[0] == "Buffers:") {
543 StringToInt(tokens[1], &meminfo->buffers);
544 continue;
545 } if (tokens[0] == "Cached:") {
546 StringToInt(tokens[1], &meminfo->cached);
547 continue;
548 } if (tokens[0] == "Active(anon):") {
549 StringToInt(tokens[1], &meminfo->active_anon);
550 continue;
551 } if (tokens[0] == "Inactive(anon):") {
552 StringToInt(tokens[1], &meminfo->inactive_anon);
553 continue;
554 } if (tokens[0] == "Active(file):") {
555 StringToInt(tokens[1], &meminfo->active_file);
556 continue;
557 } if (tokens[0] == "Inactive(file):") {
558 StringToInt(tokens[1], &meminfo->inactive_file);
559 continue;
560 } if (tokens[0] == "SwapTotal:") {
561 StringToInt(tokens[1], &meminfo->swap_total);
562 continue;
563 } if (tokens[0] == "SwapFree:") {
564 StringToInt(tokens[1], &meminfo->swap_free);
565 continue;
566 } if (tokens[0] == "Dirty:") {
567 StringToInt(tokens[1], &meminfo->dirty);
568 continue;
569 #if defined(OS_CHROMEOS)
570 // Chrome OS has a tweaked kernel that allows us to query Shmem, which is
571 // usually video memory otherwise invisible to the OS.
572 } if (tokens[0] == "Shmem:") {
573 StringToInt(tokens[1], &meminfo->shmem);
574 continue;
575 } if (tokens[0] == "Slab:") {
576 StringToInt(tokens[1], &meminfo->slab);
577 continue;
578 #endif
579 }
580 } else
581 DLOG(WARNING) << "meminfo: tokens: " << tokens.size() 510 DLOG(WARNING) << "meminfo: tokens: " << tokens.size()
582 << " malformed line: " << *it; 511 << " malformed line: " << *it;
512 continue;
513 }
514
515 int* target = NULL;
516 if (tokens[0] == "MemTotal:")
517 target = &meminfo->total;
518 else if (tokens[0] == "MemFree:")
519 target = &meminfo->free;
520 else if (tokens[0] == "Buffers:")
521 target = &meminfo->buffers;
522 else if (tokens[0] == "Cached:")
523 target = &meminfo->cached;
524 else if (tokens[0] == "Active(anon):")
525 target = &meminfo->active_anon;
526 else if (tokens[0] == "Inactive(anon):")
527 target = &meminfo->inactive_anon;
528 else if (tokens[0] == "Active(file):")
529 target = &meminfo->active_file;
530 else if (tokens[0] == "Inactive(file):")
531 target = &meminfo->inactive_file;
532 else if (tokens[0] == "SwapTotal:")
533 target = &meminfo->swap_total;
534 else if (tokens[0] == "SwapFree:")
535 target = &meminfo->swap_free;
536 else if (tokens[0] == "Dirty:")
537 target = &meminfo->dirty;
538 #if defined(OS_CHROMEOS)
539 // Chrome OS has a tweaked kernel that allows us to query Shmem, which is
540 // usually video memory otherwise invisible to the OS.
541 else if (tokens[0] == "Shmem:")
542 target = &meminfo->shmem;
543 else if (tokens[0] == "Slab:")
544 target = &meminfo->slab;
545 #endif
546 if (target)
547 StringToInt(tokens[1], target);
583 } 548 }
584 549
585 // Make sure we got a valid MemTotal. 550 // Make sure we got a valid MemTotal.
586 if (!meminfo->total) 551 return meminfo->total > 0;
587 return false;
588
589 return true;
590 } 552 }
591 553
592 // exposed for testing 554 // exposed for testing
593 bool ParseProcVmstat(const std::string& vmstat_data, 555 bool ParseProcVmstat(const std::string& vmstat_data,
594 SystemMemoryInfoKB* meminfo) { 556 SystemMemoryInfoKB* meminfo) {
595 // The format of /proc/vmstat is: 557 // The format of /proc/vmstat is:
596 // 558 //
597 // nr_free_pages 299878 559 // nr_free_pages 299878
598 // nr_inactive_anon 239863 560 // nr_inactive_anon 239863
599 // nr_active_anon 1318966 561 // nr_active_anon 1318966
600 // nr_inactive_file 2015629 562 // nr_inactive_file 2015629
601 // ... 563 // ...
602 // 564 //
603 // We iterate through the whole file because the position of the 565 // We iterate through the whole file because the position of the
604 // fields are dependent on the kernel version and configuration. 566 // fields are dependent on the kernel version and configuration.
605 567
606 std::vector<std::string> vmstat_lines; 568 std::vector<std::string> vmstat_lines;
607 Tokenize(vmstat_data, "\n", &vmstat_lines); 569 Tokenize(vmstat_data, "\n", &vmstat_lines);
608 for (std::vector<std::string>::iterator it = vmstat_lines.begin(); 570 for (std::vector<std::string>::iterator it = vmstat_lines.begin();
609 it != vmstat_lines.end(); ++it) { 571 it != vmstat_lines.end(); ++it) {
610 std::vector<std::string> tokens; 572 std::vector<std::string> tokens;
611 SplitString(*it, ' ', &tokens); 573 SplitString(*it, ' ', &tokens);
612 if (tokens.size() == 2) { 574 if (tokens.size() != 2)
613 if (tokens[0] == "pswpin") { 575 continue;
614 StringToInt(tokens[1], &meminfo->pswpin); 576
615 continue; 577 if (tokens[0] == "pswpin") {
616 } if (tokens[0] == "pswpout") { 578 StringToInt(tokens[1], &meminfo->pswpin);
617 StringToInt(tokens[1], &meminfo->pswpout); 579 } else if (tokens[0] == "pswpout") {
618 continue; 580 StringToInt(tokens[1], &meminfo->pswpout);
619 } if (tokens[0] == "pgmajfault") 581 } else if (tokens[0] == "pgmajfault") {
620 StringToInt(tokens[1], &meminfo->pgmajfault); 582 StringToInt(tokens[1], &meminfo->pgmajfault);
621 } 583 }
622 } 584 }
623 585
624 return true; 586 return true;
625 } 587 }
626 588
627 bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo) { 589 bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo) {
628 // Synchronously reading files in /proc is safe. 590 // Synchronously reading files in /proc and /sys are safe.
629 ThreadRestrictions::ScopedAllowIO allow_io; 591 ThreadRestrictions::ScopedAllowIO allow_io;
630 592
631 // Used memory is: total - free - buffers - caches 593 // Used memory is: total - free - buffers - caches
632 FilePath meminfo_file("/proc/meminfo"); 594 FilePath meminfo_file("/proc/meminfo");
633 std::string meminfo_data; 595 std::string meminfo_data;
634 if (!ReadFileToString(meminfo_file, &meminfo_data)) { 596 if (!ReadFileToString(meminfo_file, &meminfo_data)) {
635 DLOG(WARNING) << "Failed to open " << meminfo_file.value(); 597 DLOG(WARNING) << "Failed to open " << meminfo_file.value();
636 return false; 598 return false;
637 } 599 }
638 600
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 writes = 0; 662 writes = 0;
701 writes_merged = 0; 663 writes_merged = 0;
702 sectors_written = 0; 664 sectors_written = 0;
703 write_time = 0; 665 write_time = 0;
704 io = 0; 666 io = 0;
705 io_time = 0; 667 io_time = 0;
706 weighted_io_time = 0; 668 weighted_io_time = 0;
707 } 669 }
708 670
709 scoped_ptr<Value> SystemDiskInfo::ToValue() const { 671 scoped_ptr<Value> SystemDiskInfo::ToValue() const {
710 scoped_ptr<DictionaryValue> res(new base::DictionaryValue()); 672 scoped_ptr<DictionaryValue> res(new DictionaryValue());
711 673
712 // Write out uint64 variables as doubles. 674 // Write out uint64 variables as doubles.
713 // Note: this may discard some precision, but for JS there's no other option. 675 // Note: this may discard some precision, but for JS there's no other option.
714 res->SetDouble("reads", static_cast<double>(reads)); 676 res->SetDouble("reads", static_cast<double>(reads));
715 res->SetDouble("reads_merged", static_cast<double>(reads_merged)); 677 res->SetDouble("reads_merged", static_cast<double>(reads_merged));
716 res->SetDouble("sectors_read", static_cast<double>(sectors_read)); 678 res->SetDouble("sectors_read", static_cast<double>(sectors_read));
717 res->SetDouble("read_time", static_cast<double>(read_time)); 679 res->SetDouble("read_time", static_cast<double>(read_time));
718 res->SetDouble("writes", static_cast<double>(writes)); 680 res->SetDouble("writes", static_cast<double>(writes));
719 res->SetDouble("writes_merged", static_cast<double>(writes_merged)); 681 res->SetDouble("writes_merged", static_cast<double>(writes_merged));
720 res->SetDouble("sectors_written", static_cast<double>(sectors_written)); 682 res->SetDouble("sectors_written", static_cast<double>(sectors_written));
721 res->SetDouble("write_time", static_cast<double>(write_time)); 683 res->SetDouble("write_time", static_cast<double>(write_time));
722 res->SetDouble("io", static_cast<double>(io)); 684 res->SetDouble("io", static_cast<double>(io));
723 res->SetDouble("io_time", static_cast<double>(io_time)); 685 res->SetDouble("io_time", static_cast<double>(io_time));
724 res->SetDouble("weighted_io_time", static_cast<double>(weighted_io_time)); 686 res->SetDouble("weighted_io_time", static_cast<double>(weighted_io_time));
725 687
726 return res.PassAs<Value>(); 688 return res.PassAs<Value>();
727 } 689 }
728 690
729 bool IsValidDiskName(const std::string& candidate) { 691 bool IsValidDiskName(const std::string& candidate) {
730 if (candidate.length() < 3) 692 if (candidate.length() < 3)
731 return false; 693 return false;
732 if (candidate.substr(0,2) == "sd" || candidate.substr(0,2) == "hd") { 694 if (candidate[1] == 'd' &&
733 // [sh]d[a-z]+ case 695 (candidate[0] == 'h' || candidate[0] == 's' || candidate[0] == 'v')) {
734 for (size_t i = 2; i < candidate.length(); i++) { 696 // [hsv]d[a-z]+ case
697 for (size_t i = 2; i < candidate.length(); ++i) {
735 if (!islower(candidate[i])) 698 if (!islower(candidate[i]))
736 return false; 699 return false;
737 } 700 }
738 } else { 701 return true;
739 if (candidate.length() < 7) {
740 return false;
741 }
742 if (candidate.substr(0,6) == "mmcblk") {
743 // mmcblk[0-9]+ case
744 for (size_t i = 6; i < candidate.length(); i++) {
745 if (!isdigit(candidate[i]))
746 return false;
747 }
748 } else {
749 return false;
750 }
751 } 702 }
752 703
704 const char kMMCName[] = "mmcblk";
705 const size_t kMMCNameLen = strlen(kMMCName);
706 if (candidate.length() < kMMCNameLen + 1)
707 return false;
708 if (candidate.compare(0, kMMCNameLen, kMMCName) != 0)
709 return false;
710
711 // mmcblk[0-9]+ case
712 for (size_t i = kMMCNameLen; i < candidate.length(); ++i) {
713 if (!isdigit(candidate[i]))
714 return false;
715 }
753 return true; 716 return true;
754 } 717 }
755 718
756 bool GetSystemDiskInfo(SystemDiskInfo* diskinfo) { 719 bool GetSystemDiskInfo(SystemDiskInfo* diskinfo) {
757 // Synchronously reading files in /proc is safe. 720 // Synchronously reading files in /proc is safe.
758 ThreadRestrictions::ScopedAllowIO allow_io; 721 ThreadRestrictions::ScopedAllowIO allow_io;
759 722
760 FilePath diskinfo_file("/proc/diskstats"); 723 FilePath diskinfo_file("/proc/diskstats");
761 std::string diskinfo_data; 724 std::string diskinfo_data;
762 if (!ReadFileToString(diskinfo_file, &diskinfo_data)) { 725 if (!ReadFileToString(diskinfo_file, &diskinfo_data)) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 else 810 else
848 res->SetDouble("compression_ratio", 0); 811 res->SetDouble("compression_ratio", 0);
849 812
850 return res.PassAs<Value>(); 813 return res.PassAs<Value>();
851 } 814 }
852 815
853 void GetSwapInfo(SwapInfo* swap_info) { 816 void GetSwapInfo(SwapInfo* swap_info) {
854 // Synchronously reading files in /sys/block/zram0 is safe. 817 // Synchronously reading files in /sys/block/zram0 is safe.
855 ThreadRestrictions::ScopedAllowIO allow_io; 818 ThreadRestrictions::ScopedAllowIO allow_io;
856 819
857 base::FilePath zram_path("/sys/block/zram0"); 820 FilePath zram_path("/sys/block/zram0");
858 uint64 orig_data_size = ReadFileToUint64(zram_path.Append("orig_data_size")); 821 uint64 orig_data_size = ReadFileToUint64(zram_path.Append("orig_data_size"));
859 if (orig_data_size <= 4096) { 822 if (orig_data_size <= 4096) {
860 // A single page is compressed at startup, and has a high compression 823 // A single page is compressed at startup, and has a high compression
861 // ratio. We ignore this as it doesn't indicate any real swapping. 824 // ratio. We ignore this as it doesn't indicate any real swapping.
862 swap_info->orig_data_size = 0; 825 swap_info->orig_data_size = 0;
863 swap_info->num_reads = 0; 826 swap_info->num_reads = 0;
864 swap_info->num_writes = 0; 827 swap_info->num_writes = 0;
865 swap_info->compr_data_size = 0; 828 swap_info->compr_data_size = 0;
866 swap_info->mem_used_total = 0; 829 swap_info->mem_used_total = 0;
867 return; 830 return;
868 } 831 }
869 swap_info->orig_data_size = orig_data_size; 832 swap_info->orig_data_size = orig_data_size;
870 swap_info->num_reads = ReadFileToUint64(zram_path.Append("num_reads")); 833 swap_info->num_reads = ReadFileToUint64(zram_path.Append("num_reads"));
871 swap_info->num_writes = ReadFileToUint64(zram_path.Append("num_writes")); 834 swap_info->num_writes = ReadFileToUint64(zram_path.Append("num_writes"));
872 swap_info->compr_data_size = 835 swap_info->compr_data_size =
873 ReadFileToUint64(zram_path.Append("compr_data_size")); 836 ReadFileToUint64(zram_path.Append("compr_data_size"));
874 swap_info->mem_used_total = 837 swap_info->mem_used_total =
875 ReadFileToUint64(zram_path.Append("mem_used_total")); 838 ReadFileToUint64(zram_path.Append("mem_used_total"));
876 } 839 }
877 #endif // defined(OS_CHROMEOS) 840 #endif // defined(OS_CHROMEOS)
878 841
879 } // namespace base 842 } // namespace base
OLDNEW
« no previous file with comments | « base/process/process_metrics.cc ('k') | base/process/process_metrics_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698