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 3// found in the LICENSE file. 4 5#include "base/process/process_metrics.h" 6 7#include <sys/param.h> 8#include <sys/sysctl.h> 9 10namespace base { 11 12// static 13ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) { 14 return new ProcessMetrics(process); 15} 16 17size_t ProcessMetrics::GetPagefileUsage() const { 18 struct kinfo_proc info; 19 size_t length; 20 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_, 21 sizeof(struct kinfo_proc), 0 }; 22 23 if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) 24 return -1; 25 26 mib[5] = (length / sizeof(struct kinfo_proc)); 27 28 if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) 29 return -1; 30 31 return (info.p_vm_tsize + info.p_vm_dsize + info.p_vm_ssize); 32} 33 34size_t ProcessMetrics::GetPeakPagefileUsage() const { 35 return 0; 36} 37 38size_t ProcessMetrics::GetWorkingSetSize() const { 39 struct kinfo_proc info; 40 size_t length; 41 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_, 42 sizeof(struct kinfo_proc), 0 }; 43 44 if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) 45 return -1; 46 47 mib[5] = (length / sizeof(struct kinfo_proc)); 48 49 if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) 50 return -1; 51 52 return info.p_vm_rssize * getpagesize(); 53} 54 55size_t ProcessMetrics::GetPeakWorkingSetSize() const { 56 return 0; 57} 58 59bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes, 60 size_t* shared_bytes) { 61 WorkingSetKBytes ws_usage; 62 63 if (!GetWorkingSetKBytes(&ws_usage)) 64 return false; 65 66 if (private_bytes) 67 *private_bytes = ws_usage.priv << 10; 68 69 if (shared_bytes) 70 *shared_bytes = ws_usage.shared * 1024; 71 72 return true; 73} 74 75bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { 76 // TODO(bapt): be sure we can't be precise 77 size_t priv = GetWorkingSetSize(); 78 if (!priv) 79 return false; 80 ws_usage->priv = priv / 1024; 81 ws_usage->shareable = 0; 82 ws_usage->shared = 0; 83 84 return true; 85} 86 87bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { 88 return false; 89} 90 91static int GetProcessCPU(pid_t pid) { 92 struct kinfo_proc info; 93 size_t length; 94 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid, 95 sizeof(struct kinfo_proc), 0 }; 96 97 if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) 98 return -1; 99 100 mib[5] = (length / sizeof(struct kinfo_proc)); 101 102 if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) 103 return 0; 104 105 return info.p_pctcpu; 106} 107 108double ProcessMetrics::GetCPUUsage() { 109 TimeTicks time = TimeTicks::Now(); 110 111 if (last_cpu_ == 0) { 112 // First call, just set the last values. 113 last_cpu_time_ = time; 114 last_cpu_ = GetProcessCPU(process_); 115 return 0; 116 } 117 118 int64 time_delta = (time - last_cpu_time_).InMicroseconds(); 119 DCHECK_NE(time_delta, 0); 120 121 if (time_delta == 0) 122 return 0; 123 124 int cpu = GetProcessCPU(process_); 125 126 last_cpu_time_ = time; 127 last_cpu_ = cpu; 128 129 double percentage = static_cast<double>((cpu * 100.0) / FSCALE); 130 131 return percentage; 132} 133 134ProcessMetrics::ProcessMetrics(ProcessHandle process) 135 : process_(process), 136 last_system_time_(0), 137 last_cpu_(0) { 138 139 processor_count_ = base::SysInfo::NumberOfProcessors(); 140} 141 142size_t GetSystemCommitCharge() { 143 int mib[] = { CTL_VM, VM_METER }; 144 int pagesize; 145 struct vmtotal vmtotal; 146 unsigned long mem_total, mem_free, mem_inactive; 147 size_t len = sizeof(vmtotal); 148 149 if (sysctl(mib, arraysize(mib), &vmtotal, &len, NULL, 0) < 0) 150 return 0; 151 152 mem_total = vmtotal.t_vm; 153 mem_free = vmtotal.t_free; 154 mem_inactive = vmtotal.t_vm - vmtotal.t_avm; 155 156 pagesize = getpagesize(); 157 158 return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize); 159} 160 161} // namespace base 162