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

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

Issue 1384363002: [NOT TO COMMIT YET] Using proc/pid/status file contents to get process metrics in linux. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@smaps_fscan
Patch Set: Renames and fixes. Created 5 years, 2 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
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>
(...skipping 30 matching lines...) Expand all
41 if (!ReadFileToString(file, &file_as_string)) 41 if (!ReadFileToString(file, &file_as_string))
42 return 0; 42 return 0;
43 TrimWhitespaceASCII(file_as_string, TRIM_ALL, &file_as_string); 43 TrimWhitespaceASCII(file_as_string, TRIM_ALL, &file_as_string);
44 uint64 file_as_uint64 = 0; 44 uint64 file_as_uint64 = 0;
45 if (!StringToUint64(file_as_string, &file_as_uint64)) 45 if (!StringToUint64(file_as_string, &file_as_uint64))
46 return 0; 46 return 0;
47 return file_as_uint64; 47 return file_as_uint64;
48 } 48 }
49 #endif 49 #endif
50 50
51 // Read /proc/<pid>/status and return the value for |field|, or 0 on failure. 51 // Parse the contents of status file and return the value of the field
52 // Only works for fields in the form of "Field: value kB". 52 // requested.
53 size_t ReadProcStatusAndGetFieldAsSizeT(pid_t pid, const std::string& field) { 53 size_t ParseProcStatsAndGetFieldAsSizeT(const char* status_contents,
Lei Zhang 2015/10/06 21:09:00 Just use StringPiece instead of const char* ? Then
ssid 2015/10/07 09:12:15 changed to string
54 std::string status; 54 const std::string& field) {
55 {
56 // Synchronously reading files in /proc does not hit the disk.
57 ThreadRestrictions::ScopedAllowIO allow_io;
58 FilePath stat_file = internal::GetProcPidDir(pid).Append("status");
59 if (!ReadFileToString(stat_file, &status))
60 return 0;
61 }
62
63 StringPairs pairs; 55 StringPairs pairs;
64 SplitStringIntoKeyValuePairs(status, ':', '\n', &pairs); 56 SplitStringIntoKeyValuePairs(status_contents, ':', '\n', &pairs);
65 TrimKeyValuePairs(&pairs); 57 TrimKeyValuePairs(&pairs);
66 for (size_t i = 0; i < pairs.size(); ++i) { 58 for (size_t i = 0; i < pairs.size(); ++i) {
67 const std::string& key = pairs[i].first; 59 const std::string& key = pairs[i].first;
68 const std::string& value_str = pairs[i].second; 60 const std::string& value_str = pairs[i].second;
69 if (key == field) { 61 if (key == field) {
70 std::vector<StringPiece> split_value_str = SplitStringPiece( 62 std::vector<StringPiece> split_value_str = SplitStringPiece(
71 value_str, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 63 value_str, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
72 if (split_value_str.size() != 2 || split_value_str[1] != "kB") { 64 if (split_value_str.size() != 2 || split_value_str[1] != "kB") {
73 NOTREACHED(); 65 NOTREACHED();
74 return 0; 66 return 0;
75 } 67 }
76 size_t value; 68 size_t value;
77 if (!StringToSizeT(split_value_str[0], &value)) { 69 if (!StringToSizeT(split_value_str[0], &value)) {
78 NOTREACHED(); 70 NOTREACHED();
79 return 0; 71 return 0;
80 } 72 }
81 return value; 73 return value;
82 } 74 }
83 } 75 }
84 NOTREACHED(); 76 NOTREACHED();
85 return 0; 77 return 0;
86 } 78 }
87 79
80 // Read /proc/<pid>/status and return the value for |field|, or 0 on failure.
81 // Only works for fields in the form of "Field: value kB".
82 size_t ReadProcStatusAndGetFieldAsSizeT(pid_t pid, const std::string& field) {
83 std::string status;
84 {
85 // Synchronously reading files in /proc does not hit the disk.
86 ThreadRestrictions::ScopedAllowIO allow_io;
87 FilePath stat_file = internal::GetProcPidDir(pid).Append("status");
88 if (!ReadFileToString(stat_file, &status))
89 return 0;
90 }
91 return ParseProcStatsAndGetFieldAsSizeT(status.c_str(), field);
92 }
93
94 // Read file descriptor passed file descritor of /proc/<pid>/status and return
95 // the value for |field|, or 0 on failure.
96 // Only works for fields in the form of "Field: value kB".
97 size_t ReadProcStatusFdAndGetFieldAsSizeT(PlatformFile proc_status_fd,
Lei Zhang 2015/10/06 21:09:00 /proc/<pid>/status isn't that big, right? Why both
ssid 2015/10/07 09:12:14 yes, I moved the reading part to other file and no
98 const std::string& field) {
99 const size_t kMaxStatFileSize = 1 << 12;
Lei Zhang 2015/10/06 21:09:00 Easier to just write 4096?
ssid 2015/10/07 09:12:15 Done.
100 char status_data[kMaxStatFileSize];
101 status_data[0] = '\0';
102 lseek(proc_status_fd, 0, SEEK_SET);
Lei Zhang 2015/10/06 21:09:00 Check return value?
ssid 2015/10/07 09:12:15 Done.
103 ReadFromFD(proc_status_fd, status_data, kMaxStatFileSize);
Lei Zhang 2015/10/06 21:09:00 Ditto, check this return value in place of the nex
ssid 2015/10/07 09:12:14 Done.
104 if (strlen(status_data) == 0)
105 return 0;
106 return ParseProcStatsAndGetFieldAsSizeT(status_data, field);
107 }
108
88 #if defined(OS_LINUX) 109 #if defined(OS_LINUX)
89 // Read /proc/<pid>/sched and look for |field|. On succes, return true and 110 // Read /proc/<pid>/sched and look for |field|. On succes, return true and
90 // write the value for |field| into |result|. 111 // write the value for |field| into |result|.
91 // Only works for fields in the form of "field : uint_value" 112 // Only works for fields in the form of "field : uint_value"
92 bool ReadProcSchedAndGetFieldAsUint64(pid_t pid, 113 bool ReadProcSchedAndGetFieldAsUint64(pid_t pid,
93 const std::string& field, 114 const std::string& field,
94 uint64* result) { 115 uint64* result) {
95 std::string sched_data; 116 std::string sched_data;
96 { 117 {
97 // Synchronously reading files in /proc does not hit the disk. 118 // Synchronously reading files in /proc does not hit the disk.
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 ws_usage->shareable = 0; 407 ws_usage->shareable = 0;
387 408
388 #if defined(OS_CHROMEOS) 409 #if defined(OS_CHROMEOS)
389 // Can't get swapped memory from statm. 410 // Can't get swapped memory from statm.
390 ws_usage->swapped = 0; 411 ws_usage->swapped = 0;
391 #endif 412 #endif
392 413
393 return ret; 414 return ret;
394 } 415 }
395 416
417 size_t ProcessMetrics::GetWorkingSetSize(int proc_status_fd) const {
418 return ReadProcStatusFdAndGetFieldAsSizeT(proc_status_fd, "VmRSS") * 1024;
419 }
420
421 size_t ProcessMetrics::GetPeakWorkingSetSize(int proc_status_fd) const {
422 return ReadProcStatusFdAndGetFieldAsSizeT(proc_status_fd, "VmHWM") * 1024;
423 }
424
396 size_t GetSystemCommitCharge() { 425 size_t GetSystemCommitCharge() {
397 SystemMemoryInfoKB meminfo; 426 SystemMemoryInfoKB meminfo;
398 if (!GetSystemMemoryInfo(&meminfo)) 427 if (!GetSystemMemoryInfo(&meminfo))
399 return 0; 428 return 0;
400 return meminfo.total - meminfo.free - meminfo.buffers - meminfo.cached; 429 return meminfo.total - meminfo.free - meminfo.buffers - meminfo.cached;
401 } 430 }
402 431
403 int ParseProcStatCPU(const std::string& input) { 432 int ParseProcStatCPU(const std::string& input) {
404 // |input| may be empty if the process disappeared somehow. 433 // |input| may be empty if the process disappeared somehow.
405 // e.g. http://crbug.com/145811. 434 // e.g. http://crbug.com/145811.
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 #if defined(OS_LINUX) 933 #if defined(OS_LINUX)
905 int ProcessMetrics::GetIdleWakeupsPerSecond() { 934 int ProcessMetrics::GetIdleWakeupsPerSecond() {
906 uint64 wake_ups; 935 uint64 wake_ups;
907 const char kWakeupStat[] = "se.statistics.nr_wakeups"; 936 const char kWakeupStat[] = "se.statistics.nr_wakeups";
908 return ReadProcSchedAndGetFieldAsUint64(process_, kWakeupStat, &wake_ups) ? 937 return ReadProcSchedAndGetFieldAsUint64(process_, kWakeupStat, &wake_ups) ?
909 CalculateIdleWakeupsPerSecond(wake_ups) : 0; 938 CalculateIdleWakeupsPerSecond(wake_ups) : 0;
910 } 939 }
911 #endif // defined(OS_LINUX) 940 #endif // defined(OS_LINUX)
912 941
913 } // namespace base 942 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698