3 --- base/process_util_netbsd.cc.orig 2011-04-26 05:17:12.000000000 +0000
4 +++ base/process_util_netbsd.cc
6 +// Copyright (c) 2009 The Chromium Authors. All rights reserved.
7 +// Use of this source code is governed by a BSD-style license that can be
8 +// found in the LICENSE file.
10 +#include "base/process_util.h"
17 +#include <sys/time.h>
18 +#include <sys/types.h>
19 +#include <sys/wait.h>
20 +#include <sys/param.h>
21 +#include <sys/sysctl.h>
22 +#include <sys/user.h>
26 +#include "base/file_util.h"
27 +#include "base/logging.h"
28 +#include "base/string_number_conversions.h"
29 +#include "base/string_split.h"
30 +#include "base/string_tokenizer.h"
31 +#include "base/string_util.h"
32 +#include "base/sys_info.h"
33 +#include "base/threading/thread_restrictions.h"
37 +ProcessId GetParentProcessId(ProcessHandle process) {
38 + struct kinfo_proc2 info;
40 + size_t info_size = sizeof(info);
44 + mib[2] = KERN_PROC_PID;
47 + mib[5] = 400; /* XXX */
49 + if (sysctl(mib, 6, &info, &info_size, NULL, 0) < 0)
55 +FilePath GetProcessExecutablePath(ProcessHandle process) {
56 + printf("%s\n", __PRETTY_FUNCTION__);
58 + FilePath stat_file("/proc");
59 + stat_file = stat_file.Append(base::IntToString(process));
60 + stat_file = stat_file.Append("exe");
62 + if (!file_util::ReadSymbolicLink(stat_file, &exe_name)) {
63 + // No such process. Happens frequently in e.g. TerminateAllChromeProcesses
69 +ProcessIterator::ProcessIterator(const ProcessFilter* filter)
70 + : index_of_kinfo_proc_(),
75 + printf("%s\n", __PRETTY_FUNCTION__);
79 + mib[2] = KERN_PROC_UID;
81 + mib[4] = sizeof(struct kinfo_proc2);
86 + const int max_tries = 10;
90 + if (sysctl(mib, 6, NULL, &len, NULL, 0) <0 ){
91 + LOG(ERROR) << "failed to get the size needed for the process list";
92 + kinfo_procs_.resize(0);
95 + size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc2);
96 + // Leave some spare room for process table growth (more could show up
97 + // between when we check and now)
98 + num_of_kinfo_proc += 16;
99 + kinfo_procs_.resize(num_of_kinfo_proc);
100 + len = num_of_kinfo_proc * sizeof(struct kinfo_proc2);
101 + if (sysctl(mib, 6, &kinfo_procs_[0], &len, NULL, 0) <0) {
102 + // If we get a mem error, it just means we need a bigger buffer, so
103 + // loop around again. Anything else is a real error and give up.
104 + if (errno != ENOMEM) {
105 + LOG(ERROR) << "failed to get the process list";
106 + kinfo_procs_.resize(0);
110 + // Got the list, just make sure we're sized exactly right
111 + size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc2);
112 + kinfo_procs_.resize(num_of_kinfo_proc);
116 + } while (!done && (try_num++ < max_tries));
119 + LOG(ERROR) << "failed to collect the process list in a few tries";
120 + kinfo_procs_.resize(0);
124 +ProcessIterator::~ProcessIterator() {
127 +bool ProcessIterator::CheckForNextProcess() {
130 + printf("%s\n", __PRETTY_FUNCTION__);
132 + for (; index_of_kinfo_proc_ < kinfo_procs_.size(); ++ index_of_kinfo_proc_) {
135 + struct kinfo_proc2 kinfo = kinfo_procs_[index_of_kinfo_proc_];
137 + if ((kinfo.p_pid > 0) && (kinfo.p_stat == SZOMB))
141 + mib[1] = KERN_PROC_ARGS;
142 + mib[2] = kinfo.p_pid;
145 + if (sysctl(mib, 3, NULL, &len, NULL, 0) < 0) {
146 + LOG(ERROR) << "failed to figure out the buffer size for a command line";
152 + if (sysctl(mib, 3, &data[0], &len, NULL, 0) < 0) {
153 + LOG(ERROR) << "failed to fetch a commandline";
157 + std::string delimiters;
158 + delimiters.push_back('\0');
159 + Tokenize(data, delimiters, &entry_.cmd_line_args_);
161 + size_t exec_name_end = data.find('\0');
162 + if (exec_name_end == std::string::npos) {
163 + LOG(ERROR) << "command line data didn't match expected format";
167 + entry_.pid_ = kinfo.p_pid;
168 + entry_.ppid_ = kinfo.p_ppid;
169 + entry_.gid_ = kinfo.p__pgid;
171 + size_t last_slash = data.rfind('/', exec_name_end);
172 + if (last_slash == std::string::npos)
173 + entry_.exe_file_.assign(data, 0, exec_name_end);
175 + entry_.exe_file_.assign(data, last_slash + 1,
176 + exec_name_end - last_slash - 1);
178 + // Start w/ the next entry next time through
179 + ++index_of_kinfo_proc_;
186 +bool NamedProcessIterator::IncludeEntry() {
187 + return (executable_name_ == entry().exe_file() &&
188 + ProcessIterator::IncludeEntry());
192 +ProcessMetrics::ProcessMetrics(ProcessHandle process)
193 + : process_(process),
195 + last_system_time_(0),
198 + processor_count_ = base::SysInfo::NumberOfProcessors();
202 +ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
203 + return new ProcessMetrics(process);
206 +size_t ProcessMetrics::GetPagefileUsage() const {
207 + struct kinfo_proc2 info;
209 + size_t info_size = sizeof(info);
212 + mib[1] = KERN_PROC;
213 + mib[2] = KERN_PROC_PID;
215 + mib[4] = info_size;
216 + mib[5] = 400; /* XXX */
218 + if (sysctl(mib, 6, &info, &info_size, NULL, 0) < 0)
221 + return (info.p_vm_tsize + info.p_vm_dsize + info.p_vm_ssize);
224 +size_t ProcessMetrics::GetPeakPagefileUsage() const {
225 + printf("%s\n", __PRETTY_FUNCTION__);
230 +size_t ProcessMetrics::GetWorkingSetSize() const {
231 + struct kinfo_proc2 info;
233 + size_t info_size = sizeof(info);
236 + mib[1] = KERN_PROC;
237 + mib[2] = KERN_PROC_PID;
239 + mib[4] = info_size;
240 + mib[5] = 400; /* XXX */
242 + if (sysctl(mib, 6, &info, &info_size, NULL, 0) < 0)
245 + return info.p_vm_rssize * getpagesize();
248 +size_t ProcessMetrics::GetPeakWorkingSetSize() const {
249 + printf("%s\n", __PRETTY_FUNCTION__);
254 +bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes,
255 + size_t* shared_bytes) {
256 + WorkingSetKBytes ws_usage;
258 + if (!GetWorkingSetKBytes(&ws_usage))
262 + *private_bytes = ws_usage.priv << 10;
265 + *shared_bytes = ws_usage.shared * 1024;
270 +bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
271 +// TODO(bapt) be sure we can't be precise
272 + size_t priv = GetWorkingSetSize();
275 + ws_usage->priv = priv / 1024;
276 + ws_usage->shareable = 0;
277 + ws_usage->shared = 0;
282 +bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
286 +static int GetProcessCPU(pid_t pid) {
287 + struct kinfo_proc2 info;
289 + size_t info_size = sizeof(info);
292 + mib[1] = KERN_PROC;
293 + mib[2] = KERN_PROC_PID;
295 + mib[4] = info_size;
296 + mib[5] = 400; /* XXX */
298 + if (sysctl(mib, 6, &info, &info_size, NULL, 0) < 0)
301 + return info.p_pctcpu;
304 +double ProcessMetrics::GetCPUUsage() {
305 + struct timeval now;
307 + int retval = gettimeofday(&now, NULL);
311 + int64 time = TimeValToMicroseconds(now);
313 + if (last_time_ == 0) {
314 + // First call, just set the last values.
316 + last_cpu_ = GetProcessCPU(process_);
320 + int64 time_delta = time - last_time_;
321 + DCHECK_NE(time_delta, 0);
323 + if (time_delta == 0)
326 + int cpu = GetProcessCPU(process_);
331 + double percentage = static_cast<double>((cpu * 100.0) / FSCALE);
336 +size_t GetSystemCommitCharge() {
337 + int mib[2], pagesize;
338 + struct vmtotal vmtotal;
339 + unsigned long mem_total, mem_free, mem_inactive;
340 + size_t len = sizeof(vmtotal);
342 + printf("%s\n", __PRETTY_FUNCTION__);
347 + if (sysctl(mib, 2, &vmtotal, &len, NULL, 0) < 0)
350 + mem_total = vmtotal.t_vm;
351 + mem_free = vmtotal.t_free;
352 + mem_inactive = vmtotal.t_vm - vmtotal.t_avm;
354 + pagesize = getpagesize();
356 + return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize);
359 +void EnableTerminationOnOutOfMemory() {