190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/process/process_metrics.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <sys/param.h> 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <sys/sysctl.h> 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace base { 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) { 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return new ProcessMetrics(process); 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)size_t ProcessMetrics::GetPagefileUsage() const { 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct kinfo_proc info; 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t length; 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_, 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) sizeof(struct kinfo_proc), 0 }; 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return -1; 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mib[5] = (length / sizeof(struct kinfo_proc)); 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return -1; 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return (info.p_vm_tsize + info.p_vm_dsize + info.p_vm_ssize); 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)size_t ProcessMetrics::GetPeakPagefileUsage() const { 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 0; 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)size_t ProcessMetrics::GetWorkingSetSize() const { 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct kinfo_proc info; 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t length; 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_, 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) sizeof(struct kinfo_proc), 0 }; 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return -1; 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mib[5] = (length / sizeof(struct kinfo_proc)); 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return -1; 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return info.p_vm_rssize * getpagesize(); 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)size_t ProcessMetrics::GetPeakWorkingSetSize() const { 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 0; 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes, 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t* shared_bytes) { 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WorkingSetKBytes ws_usage; 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!GetWorkingSetKBytes(&ws_usage)) 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (private_bytes) 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *private_bytes = ws_usage.priv << 10; 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (shared_bytes) 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *shared_bytes = ws_usage.shared * 1024; 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(bapt): be sure we can't be precise 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t priv = GetWorkingSetSize(); 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!priv) 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ws_usage->priv = priv / 1024; 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ws_usage->shareable = 0; 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ws_usage->shared = 0; 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static int GetProcessCPU(pid_t pid) { 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct kinfo_proc info; 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t length; 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid, 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) sizeof(struct kinfo_proc), 0 }; 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return -1; 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mib[5] = (length / sizeof(struct kinfo_proc)); 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 0; 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return info.p_pctcpu; 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)double ProcessMetrics::GetCPUUsage() { 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct timeval now; 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int retval = gettimeofday(&now, NULL); 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (retval) 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 0; 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 time = TimeValToMicroseconds(now); 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (last_time_ == 0) { 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // First call, just set the last values. 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) last_time_ = time; 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) last_cpu_ = GetProcessCPU(process_); 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 0; 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 time_delta = time - last_time_; 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_NE(time_delta, 0); 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (time_delta == 0) 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 0; 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int cpu = GetProcessCPU(process_); 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) last_time_ = time; 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) last_cpu_ = cpu; 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) double percentage = static_cast<double>((cpu * 100.0) / FSCALE); 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return percentage; 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)ProcessMetrics::ProcessMetrics(ProcessHandle process) 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : process_(process), 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) last_time_(0), 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) last_system_time_(0), 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) last_cpu_(0) { 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) processor_count_ = base::SysInfo::NumberOfProcessors(); 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)size_t GetSystemCommitCharge() { 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int mib[] = { CTL_VM, VM_METER }; 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int pagesize; 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct vmtotal vmtotal; 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) unsigned long mem_total, mem_free, mem_inactive; 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t len = sizeof(vmtotal); 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (sysctl(mib, arraysize(mib), &vmtotal, &len, NULL, 0) < 0) 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 0; 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mem_total = vmtotal.t_vm; 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mem_free = vmtotal.t_free; 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mem_inactive = vmtotal.t_vm - vmtotal.t_avm; 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) pagesize = getpagesize(); 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize); 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace base 169