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() {
109 TimeTicks time
= TimeTicks::Now();
111 if (last_cpu_
== 0) {
112 // First call, just set the last values.
113 last_cpu_time_
= time
;
114 last_cpu_
= GetProcessCPU(process_
);
118 int64 time_delta
= (time
- last_cpu_time_
).InMicroseconds();
119 DCHECK_NE(time_delta
, 0);
124 int cpu
= GetProcessCPU(process_
);
126 last_cpu_time_
= time
;
129 double percentage
= static_cast<double>((cpu
* 100.0) / FSCALE
);
134 ProcessMetrics::ProcessMetrics(ProcessHandle process
)
136 last_system_time_(0),
139 processor_count_
= base::SysInfo::NumberOfProcessors();
142 size_t GetSystemCommitCharge() {
143 int mib
[] = { CTL_VM
, VM_METER
};
145 struct vmtotal vmtotal
;
146 unsigned long mem_total
, mem_free
, mem_inactive
;
147 size_t len
= sizeof(vmtotal
);
149 if (sysctl(mib
, arraysize(mib
), &vmtotal
, &len
, NULL
, 0) < 0)
152 mem_total
= vmtotal
.t_vm
;
153 mem_free
= vmtotal
.t_free
;
154 mem_inactive
= vmtotal
.t_vm
- vmtotal
.t_avm
;
156 pagesize
= getpagesize();
158 return mem_total
- (mem_free
*pagesize
) - (mem_inactive
*pagesize
);