process_metrics_openbsd.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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