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

Unified Diff: base/process/process_metrics_linux.cc

Issue 546193002: Add an 'Idle Wake Ups' metric to the Linux task manager, implement backend. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@wakeclean
Patch Set: rebase 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/process/process_metrics_linux.cc
diff --git a/base/process/process_metrics_linux.cc b/base/process/process_metrics_linux.cc
index be166e33e322959bb7d10111e0746dbe5680c27f..03cc7ebee9951f817af38c946e6e53a79c68c408 100644
--- a/base/process/process_metrics_linux.cc
+++ b/base/process/process_metrics_linux.cc
@@ -25,6 +25,15 @@ namespace base {
namespace {
+void TrimKeyValuePairs(StringPairs* pairs) {
+ DCHECK(pairs);
+ StringPairs& p_ref = *pairs;
+ for (size_t i = 0; i < p_ref.size(); ++i) {
+ TrimWhitespaceASCII(p_ref[i].first, TRIM_ALL, &p_ref[i].first);
+ TrimWhitespaceASCII(p_ref[i].second, TRIM_ALL, &p_ref[i].second);
+ }
+}
+
#if defined(OS_CHROMEOS)
// Read a file with a single number string and return the number as a uint64.
static uint64 ReadFileToUint64(const FilePath file) {
@@ -44,19 +53,19 @@ static uint64 ReadFileToUint64(const FilePath file) {
size_t ReadProcStatusAndGetFieldAsSizeT(pid_t pid, const std::string& field) {
std::string status;
{
- // Synchronously reading files in /proc is safe.
+ // Synchronously reading files in /proc does not hit the disk.
ThreadRestrictions::ScopedAllowIO allow_io;
FilePath stat_file = internal::GetProcPidDir(pid).Append("status");
if (!ReadFileToString(stat_file, &status))
return 0;
}
- std::vector<std::pair<std::string, std::string> > pairs;
+ StringPairs pairs;
SplitStringIntoKeyValuePairs(status, ':', '\n', &pairs);
+ TrimKeyValuePairs(&pairs);
for (size_t i = 0; i < pairs.size(); ++i) {
- std::string key, value_str;
- TrimWhitespaceASCII(pairs[i].first, TRIM_ALL, &key);
- TrimWhitespaceASCII(pairs[i].second, TRIM_ALL, &value_str);
+ const std::string& key = pairs[i].first;
+ const std::string& value_str = pairs[i].second;
if (key == field) {
std::vector<std::string> split_value_str;
SplitString(value_str, ' ', &split_value_str);
@@ -76,6 +85,40 @@ size_t ReadProcStatusAndGetFieldAsSizeT(pid_t pid, const std::string& field) {
return 0;
}
+#if defined(OS_LINUX)
+// Read /proc/<pid>/sched and look for |field|. On succes, return true and
+// write the value for |field| into |result|.
+// Only works for fields in the form of "field : uint_value"
+bool ReadProcSchedAndGetFieldAsUint64(pid_t pid,
+ const std::string& field,
+ uint64* result) {
+ std::string sched_data;
+ {
+ // Synchronously reading files in /proc does not hit the disk.
+ ThreadRestrictions::ScopedAllowIO allow_io;
+ FilePath sched_file = internal::GetProcPidDir(pid).Append("sched");
+ if (!ReadFileToString(sched_file, &sched_data))
+ return false;
+ }
+
+ StringPairs pairs;
+ SplitStringIntoKeyValuePairs(sched_data, ':', '\n', &pairs);
+ TrimKeyValuePairs(&pairs);
+ for (size_t i = 0; i < pairs.size(); ++i) {
+ const std::string& key = pairs[i].first;
+ const std::string& value_str = pairs[i].second;
+ if (key == field) {
+ uint64 value;
+ if (!StringToUint64(value_str, &value))
+ return false;
+ *result = value;
+ return true;
+ }
+ }
+ return false;
+}
+#endif // defined(OS_LINUX)
+
// Get the total CPU of a single process. Return value is number of jiffies
// on success or -1 on error.
int GetProcessCPU(pid_t pid) {
@@ -94,7 +137,7 @@ int GetProcessCPU(pid_t pid) {
if (!tid)
continue;
- // Synchronously reading files in /proc is safe.
+ // Synchronously reading files in /proc does not hit the disk.
ThreadRestrictions::ScopedAllowIO allow_io;
std::string stat;
@@ -197,7 +240,7 @@ double ProcessMetrics::GetCPUUsage() {
// To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING
// in your kernel configuration.
bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
- // Synchronously reading files in /proc is safe.
+ // Synchronously reading files in /proc does not hit the disk.
ThreadRestrictions::ScopedAllowIO allow_io;
std::string proc_io_contents;
@@ -208,12 +251,12 @@ bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
io_counters->OtherOperationCount = 0;
io_counters->OtherTransferCount = 0;
- std::vector<std::pair<std::string, std::string> > pairs;
+ StringPairs pairs;
SplitStringIntoKeyValuePairs(proc_io_contents, ':', '\n', &pairs);
+ TrimKeyValuePairs(&pairs);
for (size_t i = 0; i < pairs.size(); ++i) {
- std::string key, value_str;
- TrimWhitespaceASCII(pairs[i].first, TRIM_ALL, &key);
- TrimWhitespaceASCII(pairs[i].second, TRIM_ALL, &value_str);
+ const std::string& key = pairs[i].first;
+ const std::string& value_str = pairs[i].second;
uint64* target_counter = NULL;
if (key == "syscr")
target_counter = &io_counters->ReadOperationCount;
@@ -234,6 +277,9 @@ bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
ProcessMetrics::ProcessMetrics(ProcessHandle process)
: process_(process),
last_system_time_(0),
+#if defined(OS_LINUX)
+ last_absolute_idle_wakeups_(0),
+#endif
last_cpu_(0) {
processor_count_ = SysInfo::NumberOfProcessors();
}
@@ -315,7 +361,7 @@ bool ProcessMetrics::GetWorkingSetKBytesStatm(WorkingSetKBytes* ws_usage)
std::string statm;
{
FilePath statm_file = internal::GetProcPidDir(process_).Append("statm");
- // Synchronously reading files in /proc is safe.
+ // Synchronously reading files in /proc does not hit the disk.
ThreadRestrictions::ScopedAllowIO allow_io;
bool ret = ReadFileToString(statm_file, &statm);
if (!ret || statm.length() == 0)
@@ -717,7 +763,7 @@ bool IsValidDiskName(const std::string& candidate) {
}
bool GetSystemDiskInfo(SystemDiskInfo* diskinfo) {
- // Synchronously reading files in /proc is safe.
+ // Synchronously reading files in /proc does not hit the disk.
ThreadRestrictions::ScopedAllowIO allow_io;
FilePath diskinfo_file("/proc/diskstats");
@@ -814,7 +860,7 @@ scoped_ptr<Value> SwapInfo::ToValue() const {
}
void GetSwapInfo(SwapInfo* swap_info) {
- // Synchronously reading files in /sys/block/zram0 is safe.
+ // Synchronously reading files in /sys/block/zram0 does not hit the disk.
ThreadRestrictions::ScopedAllowIO allow_io;
FilePath zram_path("/sys/block/zram0");
@@ -839,4 +885,13 @@ void GetSwapInfo(SwapInfo* swap_info) {
}
#endif // defined(OS_CHROMEOS)
+#if defined(OS_LINUX)
+int ProcessMetrics::GetIdleWakeupsPerSecond() {
+ uint64 wake_ups;
+ const char kWakeupStat[] = "se.statistics.nr_wakeups";
+ return ReadProcSchedAndGetFieldAsUint64(process_, kWakeupStat, &wake_ups) ?
+ CalculateIdleWakeupsPerSecond(wake_ups) : 0;
+}
+#endif // defined(OS_LINUX)
+
} // namespace base
« 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