Index: base/process/process_metrics_linux.cc |
diff --git a/base/process/process_metrics_linux.cc b/base/process/process_metrics_linux.cc |
index b52d356edc4b3e7b01625b2fca7bd447402e8709..e947fe066865f48135fde46530b48078832ee0c4 100644 |
--- a/base/process/process_metrics_linux.cc |
+++ b/base/process/process_metrics_linux.cc |
@@ -5,11 +5,14 @@ |
#include "base/process/process_metrics.h" |
#include <dirent.h> |
+#include <fcntl.h> |
+#include <sys/stat.h> |
#include <sys/time.h> |
#include <sys/types.h> |
#include <unistd.h> |
#include "base/file_util.h" |
+#include "base/files/memory_mapped_file.h" |
#include "base/logging.h" |
#include "base/process/internal_linux.h" |
#include "base/string_util.h" |
@@ -156,44 +159,12 @@ bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes, |
return true; |
} |
-// Private and Shared working set sizes are obtained from /proc/<pid>/statm. |
bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { |
- // Use statm instead of smaps because smaps is: |
- // a) Large and slow to parse. |
- // b) Unavailable in the SUID sandbox. |
- |
- // First we need to get the page size, since everything is measured in pages. |
- // For details, see: man 5 proc. |
- const int page_size_kb = getpagesize() / 1024; |
- if (page_size_kb <= 0) |
- return false; |
- |
- std::string statm; |
- { |
- FilePath statm_file = internal::GetProcPidDir(process_).Append("statm"); |
- // Synchronously reading files in /proc is safe. |
- ThreadRestrictions::ScopedAllowIO allow_io; |
- bool ret = file_util::ReadFileToString(statm_file, &statm); |
- if (!ret || statm.length() == 0) |
- return false; |
- } |
- |
- std::vector<std::string> statm_vec; |
- SplitString(statm, ' ', &statm_vec); |
- if (statm_vec.size() != 7) |
- return false; // Not the format we expect. |
- |
- int statm_rss, statm_shared; |
- StringToInt(statm_vec[1], &statm_rss); |
- StringToInt(statm_vec[2], &statm_shared); |
- |
- ws_usage->priv = (statm_rss - statm_shared) * page_size_kb; |
- ws_usage->shared = statm_shared * page_size_kb; |
- |
- // Sharable is not calculated, as it does not provide interesting data. |
- ws_usage->shareable = 0; |
- |
- return true; |
+#if defined(OS_CHROMEOS) |
+ if (GetWorkingSetKBytesTotmaps(ws_usage)) |
+ return true; |
+#endif |
+ return GetWorkingSetKBytesStatm(ws_usage); |
} |
double ProcessMetrics::GetCPUUsage() { |
@@ -292,6 +263,94 @@ ProcessMetrics::ProcessMetrics(ProcessHandle process) |
processor_count_ = base::SysInfo::NumberOfProcessors(); |
} |
+#if defined(OS_CHROMEOS) |
+// Private, Shared and Proportional working set sizes are obtained from |
+// /proc/<pid>/totmaps |
+bool ProcessMetrics::GetWorkingSetKBytesTotmaps(WorkingSetKBytes *ws_usage) |
+ const { |
+ // The format of /proc/<pid>/totmaps is: |
+ // |
+ // Rss: 6120 kB |
+ // Pss: 3335 kB |
+ // Shared_Clean: 1008 kB |
+ // Shared_Dirty: 4012 kB |
+ // Private_Clean: 4 kB |
+ // Private_Dirty: 1096 kB |
+ // ... |
+ const size_t kPssIndex = 4; |
+ const size_t kPrivate_CleanIndex = 13; |
+ const size_t kPrivate_DirtyIndex = 16; |
+ |
+ std::string totmaps_data; |
+ { |
+ FilePath totmaps_file = internal::GetProcPidDir(process_).Append("totmaps"); |
+ ThreadRestrictions::ScopedAllowIO allow_io; |
+ bool ret = file_util::ReadFileToString(totmaps_file, &totmaps_data); |
+ if (!ret || totmaps_data.length() == 0) |
+ return false; |
+ } |
+ |
+ std::vector<std::string> totmaps_fields; |
+ SplitStringAlongWhitespace(totmaps_data, &totmaps_fields); |
+ |
+ DCHECK_EQ(totmaps_fields[kPssIndex-1], "Pss:"); |
Lei Zhang
2013/05/28 03:37:41
nit: prefer DCHECK_EQ(expected, actual)
|
+ DCHECK_EQ(totmaps_fields[kPrivate_CleanIndex-1], "Private_Clean:"); |
+ DCHECK_EQ(totmaps_fields[kPrivate_DirtyIndex-1], "Private_Dirty:"); |
+ |
+ int pss, private_clean, private_dirty; |
+ base::StringToInt(totmaps_fields[kPssIndex], &pss); |
Lei Zhang
2013/05/28 03:37:41
nit: already in namespace base, no need for base::
Lei Zhang
2013/05/28 03:37:41
StringToInt() can fail - check return result.
Get
|
+ base::StringToInt(totmaps_fields[kPrivate_CleanIndex], &private_clean); |
+ base::StringToInt(totmaps_fields[kPrivate_DirtyIndex], &private_dirty); |
+ |
+ ws_usage->priv = private_clean + private_dirty; |
+ ws_usage->shared = pss; |
+ ws_usage->shareable = 0; |
+ |
+ return true; |
+} |
+#endif |
+ |
+// Private and Shared working set sizes are obtained from /proc/<pid>/statm. |
+bool ProcessMetrics::GetWorkingSetKBytesStatm(WorkingSetKBytes* ws_usage) |
+ const { |
+ // Use statm instead of smaps because smaps is: |
+ // a) Large and slow to parse. |
+ // b) Unavailable in the SUID sandbox. |
+ |
+ // First we need to get the page size, since everything is measured in pages. |
+ // For details, see: man 5 proc. |
+ const int page_size_kb = getpagesize() / 1024; |
+ if (page_size_kb <= 0) |
+ return false; |
+ |
+ std::string statm; |
+ { |
+ FilePath statm_file = internal::GetProcPidDir(process_).Append("statm"); |
+ // Synchronously reading files in /proc is safe. |
+ ThreadRestrictions::ScopedAllowIO allow_io; |
+ bool ret = file_util::ReadFileToString(statm_file, &statm); |
+ if (!ret || statm.length() == 0) |
+ return false; |
+ } |
+ |
+ std::vector<std::string> statm_vec; |
+ SplitString(statm, ' ', &statm_vec); |
+ if (statm_vec.size() != 7) |
+ return false; // Not the format we expect. |
+ |
+ int statm_rss, statm_shared; |
+ StringToInt(statm_vec[1], &statm_rss); |
+ StringToInt(statm_vec[2], &statm_shared); |
+ |
+ ws_usage->priv = (statm_rss - statm_shared) * page_size_kb; |
+ ws_usage->shared = statm_shared * page_size_kb; |
+ |
+ // Sharable is not calculated, as it does not provide interesting data. |
+ ws_usage->shareable = 0; |
+ |
+ return true; |
+} |
+ |
size_t GetSystemCommitCharge() { |
SystemMemoryInfoKB meminfo; |
if (!GetSystemMemoryInfo(&meminfo)) |