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 10 namespace base { 11 12 // static 13 ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) { 14 return new ProcessMetrics(process); 15 } 16 17 size_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 34 size_t ProcessMetrics::GetPeakPagefileUsage() const { 35 return 0; 36 } 37 38 size_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 55 size_t ProcessMetrics::GetPeakWorkingSetSize() const { 56 return 0; 57 } 58 59 bool 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 75 bool 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 87 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { 88 return false; 89 } 90 91 static 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 108 double ProcessMetrics::GetCPUUsage() { 109 struct timeval now; 110 111 int retval = gettimeofday(&now, NULL); 112 if (retval) 113 return 0; 114 115 int64 time = TimeValToMicroseconds(now); 116 117 if (last_time_ == 0) { 118 // First call, just set the last values. 119 last_time_ = time; 120 last_cpu_ = GetProcessCPU(process_); 121 return 0; 122 } 123 124 int64 time_delta = time - last_time_; 125 DCHECK_NE(time_delta, 0); 126 127 if (time_delta == 0) 128 return 0; 129 130 int cpu = GetProcessCPU(process_); 131 132 last_time_ = time; 133 last_cpu_ = cpu; 134 135 double percentage = static_cast<double>((cpu * 100.0) / FSCALE); 136 137 return percentage; 138 } 139 140 ProcessMetrics::ProcessMetrics(ProcessHandle process) 141 : process_(process), 142 last_time_(0), 143 last_system_time_(0), 144 last_cpu_(0) { 145 146 processor_count_ = base::SysInfo::NumberOfProcessors(); 147 } 148 149 size_t GetSystemCommitCharge() { 150 int mib[] = { CTL_VM, VM_METER }; 151 int pagesize; 152 struct vmtotal vmtotal; 153 unsigned long mem_total, mem_free, mem_inactive; 154 size_t len = sizeof(vmtotal); 155 156 if (sysctl(mib, arraysize(mib), &vmtotal, &len, NULL, 0) < 0) 157 return 0; 158 159 mem_total = vmtotal.t_vm; 160 mem_free = vmtotal.t_free; 161 mem_inactive = vmtotal.t_vm - vmtotal.t_avm; 162 163 pagesize = getpagesize(); 164 165 return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize); 166 } 167 168 } // namespace base 169