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.
5 #include "base/process/process_metrics.h"
8 #include <sys/sysctl.h>
13 ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
14 return new ProcessMetrics(process);
17 size_t ProcessMetrics::GetPagefileUsage() const {
18 struct kinfo_proc info;
20 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_,
21 sizeof(struct kinfo_proc), 0 };
23 if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
26 mib[5] = (length / sizeof(struct kinfo_proc));
28 if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
31 return (info.p_vm_tsize + info.p_vm_dsize + info.p_vm_ssize);
34 size_t ProcessMetrics::GetPeakPagefileUsage() const {
38 size_t ProcessMetrics::GetWorkingSetSize() const {
39 struct kinfo_proc info;
41 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_,
42 sizeof(struct kinfo_proc), 0 };
44 if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
47 mib[5] = (length / sizeof(struct kinfo_proc));
49 if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
52 return info.p_vm_rssize * getpagesize();
55 size_t ProcessMetrics::GetPeakWorkingSetSize() const {
59 bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes,
60 size_t* shared_bytes) {
61 WorkingSetKBytes ws_usage;
63 if (!GetWorkingSetKBytes(&ws_usage))
67 *private_bytes = ws_usage.priv << 10;
70 *shared_bytes = ws_usage.shared * 1024;
75 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
76 // TODO(bapt): be sure we can't be precise
77 size_t priv = GetWorkingSetSize();
80 ws_usage->priv = priv / 1024;
81 ws_usage->shareable = 0;
87 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
91 static int GetProcessCPU(pid_t pid) {
92 struct kinfo_proc info;
94 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid,
95 sizeof(struct kinfo_proc), 0 };
97 if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
100 mib[5] = (length / sizeof(struct kinfo_proc));
102 if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
105 return info.p_pctcpu;
108 double ProcessMetrics::GetCPUUsage() {
111 int retval = gettimeofday(&now, NULL);
115 int64 time = TimeValToMicroseconds(now);
117 if (last_time_ == 0) {
118 // First call, just set the last values.
120 last_cpu_ = GetProcessCPU(process_);
124 int64 time_delta = time - last_time_;
125 DCHECK_NE(time_delta, 0);
130 int cpu = GetProcessCPU(process_);
135 double percentage = static_cast<double>((cpu * 100.0) / FSCALE);
140 ProcessMetrics::ProcessMetrics(ProcessHandle process)
143 last_system_time_(0),
146 processor_count_ = base::SysInfo::NumberOfProcessors();
149 size_t GetSystemCommitCharge() {
150 int mib[] = { CTL_VM, VM_METER };
152 struct vmtotal vmtotal;
153 unsigned long mem_total, mem_free, mem_inactive;
154 size_t len = sizeof(vmtotal);
156 if (sysctl(mib, arraysize(mib), &vmtotal, &len, NULL, 0) < 0)
159 mem_total = vmtotal.t_vm;
160 mem_free = vmtotal.t_free;
161 mem_inactive = vmtotal.t_vm - vmtotal.t_avm;
163 pagesize = getpagesize();
165 return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize);