Index: base/process_util_linux.cc |
=================================================================== |
--- base/process_util_linux.cc (revision 22256) |
+++ base/process_util_linux.cc (working copy) |
@@ -326,6 +326,71 @@ |
return 0; |
} |
+void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const { |
+ FilePath stat_file = |
+ 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
|
+ std::string maps; |
+ size_t file_mapped_size = 0; |
+ size_t anon_size = 0; |
+ size_t private_size = 0; |
Evan Martin
2009/08/03 05:16:11
you can declare these variables closer to where th
|
+ 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
|
+ return; |
+ |
+ std::vector<std::string> map_lines; |
+ SplitString(maps, '\n', &map_lines); |
+ for (std::vector<std::string>::iterator iter = map_lines.begin(); |
+ iter != map_lines.end(); ++iter) { |
+ if (*iter == "") { |
+ continue; |
+ } |
+ |
+ std::vector<std::string> fields; |
+ SplitString(*iter, ' ', &fields); |
+ if (fields.size() < 5) { |
+ LOG(ERROR) << "Badly formatted /proc/*/maps line: " << *iter; |
+ continue; |
+ } |
+ |
+ // First fields is memory range, which gives us size. Formatted as: |
+ // XXXXXXXX-XXXXXXXX |
+ unsigned int sep_pos = fields[0].find('-'); |
Evan Martin
2009/08/03 05:16:11
string::size_type here, i guess
|
+ if (sep_pos == std::string::npos) { |
+ LOG(ERROR) << "Badly formatted address range: " << fields[0]; |
+ continue; |
+ } |
+ int address_begin = HexStringToInt(fields[0].substr(0, sep_pos)); |
+ int address_end = HexStringToInt(fields[0].substr(sep_pos + 1)); |
+ if (address_end < address_begin) |
+ continue; |
+ size_t size = address_end - address_begin; |
+ |
+ // Second field is permissions formatted as: |
+ // [r-][w-][x-][ps] |
Evan Martin
2009/08/03 05:16:11
I think you have regex syntax here, right? might
|
+ // Where: |
+ // r = read |
+ // w = write |
+ // x = execute |
+ // p = private |
+ // s = shared |
+ if (fields[1][3] == 'p') |
+ private_size += size; |
+ |
+ // Fifth field is inode. If non-zero, this memory region is mapped by a |
+ // file. |
+ int inode = 0; |
+ StringToInt(fields[4], &inode); |
+ if (inode) { |
+ file_mapped_size += size; |
+ } else { |
+ anon_size += size; |
+ } |
+ } |
+ |
+ usage->priv = private_size / 1024; |
+ usage->image = file_mapped_size / 1024; |
+ usage->mapped = anon_size / 1024; |
+} |
+ |
// Private and Shared working set sizes are obtained from /proc/<pid>/smaps, |
// as in http://www.pixelbeat.org/scripts/ps_mem.py |
bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { |
@@ -367,13 +432,14 @@ |
} |
} |
ws_usage->priv = private_kb; |
- // Sharable is not calculated, as it does not provide interesting data. |
- ws_usage->shareable = 0; |
if (have_pss) { |
- ws_usage->shared = pss_kb - private_kb; |
+ ws_usage->shared = pss_kb - private_kb; |
} else { |
ws_usage->shared = shared_kb; |
} |
+ // Shared pages are sharable, so even if this isn't that useful, fill it in |
+ // with the most sensible value since the about:memory handler page needs it. |
+ ws_usage->shareable = ws_usage->shared; |
Joel Stanley (old)
2009/08/03 16:02:37
from chrome/browser/resources/about_memory.html, w
|
return true; |
} |