Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1560)

Side by Side Diff: base/process_util_openbsd.cc

Issue 8228005: openbsd and freebsd fixes for base (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixes after the comments from Mark Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
Mark Mentovai 2011/10/12 18:42:56 On a new file, the copyright year should be the cu
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_util.h"
6
7 #include <ctype.h>
8 #include <dirent.h>
9 #include <dlfcn.h>
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <sys/time.h>
13 #include <sys/types.h>
14 #include <sys/wait.h>
15 #include <sys/param.h>
16 #include <sys/sysctl.h>
17 #include <sys/user.h>
18 #include <time.h>
19 #include <unistd.h>
20
21 #include "base/file_util.h"
22 #include "base/logging.h"
23 #include "base/string_number_conversions.h"
24 #include "base/string_split.h"
25 #include "base/string_tokenizer.h"
26 #include "base/string_util.h"
27 #include "base/sys_info.h"
28 #include "base/threading/thread_restrictions.h"
29
30 namespace base {
31
32 ProcessId GetParentProcessId(ProcessHandle process) {
33 struct kinfo_proc info;
34 size_t length;
35 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process, sizeof(struct kinfo _proc), 0 };
Mark Mentovai 2011/10/12 18:42:56 No lines longer than 80 characters, per the style
36
37 if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) == -1)
Mark Mentovai 2011/10/12 18:42:56 Standardize on checking == -1 or < 0.
38 return -1;
39
40 mib[5] = (int)(length / sizeof(struct kinfo_proc));
Mark Mentovai 2011/10/12 18:42:56 Use C++<style>(casts), per the style guide.
41
42 if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
43 return -1;
44
45 return info.p_ppid;
46 }
47
48 FilePath GetProcessExecutablePath(ProcessHandle process) {
49 return FilePath(std::string("/usr/local/chrome/chrome"));
50 }
51
52 ProcessIterator::ProcessIterator(const ProcessFilter* filter)
53 : index_of_kinfo_proc_(),
54 filter_(filter) {
Mark Mentovai 2011/10/12 18:42:56 The “f” should be lined up under the “i” above it,
55
56 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_UID, getuid(), sizeof(struct kinf o_proc), 0 };
57
58 bool done = false;
59 int try_num = 1;
60 const int max_tries = 10;
61
62 do {
63 size_t len = 0;
64 if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) < 0) {
65 LOG(ERROR) << "failed to get the size needed for the process list";
66 kinfo_procs_.resize(0);
67 done = true;
68 } else {
69 size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc);
70 // Leave some spare room for process table growth (more could show up
71 // between when we check and now)
72 num_of_kinfo_proc += 16;
73 kinfo_procs_.resize(num_of_kinfo_proc);
74 len = num_of_kinfo_proc * sizeof(struct kinfo_proc);
75 if (sysctl(mib, arraysize(mib), &kinfo_procs_[0], &len, NULL, 0) < 0) {
76 // If we get a mem error, it just means we need a bigger buffer, so
77 // loop around again. Anything else is a real error and give up.
78 if (errno != ENOMEM) {
79 LOG(ERROR) << "failed to get the process list";
80 kinfo_procs_.resize(0);
81 done = true;
82 }
83 } else {
84 // Got the list, just make sure we're sized exactly right
85 size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc);
86 kinfo_procs_.resize(num_of_kinfo_proc);
87 done = true;
88 }
89 }
90 } while (!done && (try_num++ < max_tries));
91
92 if (!done) {
93 LOG(ERROR) << "failed to collect the process list in a few tries";
94 kinfo_procs_.resize(0);
95 }
96 }
97
98 ProcessIterator::~ProcessIterator() {
99 }
100
101 bool ProcessIterator::CheckForNextProcess() {
102 std::string data;
103 for (; index_of_kinfo_proc_ < kinfo_procs_.size(); ++index_of_kinfo_proc_) {
104 kinfo_proc& kinfo = kinfo_procs_[index_of_kinfo_proc_];
105
106 // Skip processes just awaiting collection
107 if ((kinfo.p_pid > 0) && (kinfo.p_stat == SZOMB))
108 continue;
109
110 int mib[] = { CTL_KERN, KERN_PROC_ARGS, kinfo.p_pid };
111
112 // Find out what size buffer we need.
113 size_t data_len = 0;
114 if (sysctl(mib, arraysize(mib), NULL, &data_len, NULL, 0) < 0) {
115 DVPLOG(1) << "failed to figure out the buffer size for a commandline";
116 continue;
117 }
118
119 data.resize(data_len);
120 if (sysctl(mib, arraysize(mib), &data[0], &data_len, NULL, 0) < 0) {
121 DVPLOG(1) << "failed to fetch a commandline";
122 continue;
123 }
124
125 // |data| contains all the command line parameters of the process, separated
126 // by blocks of one or more null characters. We tokenize |data| into a
127 // vector of strings using '\0' as a delimiter and populate
128 // |entry_.cmd_line_args_|.
129 std::string delimiters;
130 delimiters.push_back('\0');
131 Tokenize(data, delimiters, &entry_.cmd_line_args_);
132
133 // |data| starts with the full executable path followed by a null character.
134 // We search for the first instance of '\0' and extract everything before it
135 // to populate |entry_.exe_file_|.
136 size_t exec_name_end = data.find('\0');
137 if (exec_name_end == std::string::npos) {
138 LOG(ERROR) << "command line data didn't match expected format";
139 continue;
140 }
141
142 entry_.pid_ = kinfo.p_pid;
143 entry_.ppid_ = kinfo.p_ppid;
144 entry_.gid_ = kinfo.p__pgid;
145 size_t last_slash = data.rfind('/', exec_name_end);
146 if (last_slash == std::string::npos)
147 entry_.exe_file_.assign(data, 0, exec_name_end);
148 else
149 entry_.exe_file_.assign(data, last_slash + 1,
150 exec_name_end - last_slash - 1);
151 // Start w/ the next entry next time through
152 ++index_of_kinfo_proc_;
153 // Done
154 return true;
155 }
156 return false;
157 }
158
159 bool NamedProcessIterator::IncludeEntry() {
160 return (executable_name_ == entry().exe_file() &&
161 ProcessIterator::IncludeEntry());
162 }
163
164
165 ProcessMetrics::ProcessMetrics(ProcessHandle process)
166 : process_(process),
167 last_time_(0),
168 last_system_time_(0),
169 last_cpu_(0) {
170
171 processor_count_ = base::SysInfo::NumberOfProcessors();
172 }
173
174 // static
175 ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
176 return new ProcessMetrics(process);
177 }
178
179 size_t ProcessMetrics::GetPagefileUsage() const {
180 struct kinfo_proc info;
181 size_t length;
182 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_, sizeof(struct kinf o_proc), 0 };
183
184 if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) == -1)
185 return -1;
186
187 mib[5] = (int)(length / sizeof(struct kinfo_proc));
188
189 if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
190 return -1;
191
192 return (info.p_vm_tsize + info.p_vm_dsize + info.p_vm_ssize);
193 }
194
195 size_t ProcessMetrics::GetPeakPagefileUsage() const {
196
197 return 0;
198 }
199
200 size_t ProcessMetrics::GetWorkingSetSize() const {
201 struct kinfo_proc info;
202 size_t length;
203 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_, sizeof(struct kinf o_proc), 0 };
204
205 if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) == -1)
206 return -1;
207
208 mib[5] = (int)(length / sizeof(struct kinfo_proc));
209
210 if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
211 return -1;
212
213 return info.p_vm_rssize * getpagesize();
214 }
215
216 size_t ProcessMetrics::GetPeakWorkingSetSize() const {
217
218 return 0;
219 }
220
221 bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes,
222 size_t* shared_bytes) {
223 WorkingSetKBytes ws_usage;
224
225 if (!GetWorkingSetKBytes(&ws_usage))
226 return false;
227
228 if (private_bytes)
229 *private_bytes = ws_usage.priv << 10;
230
231 if (shared_bytes)
232 *shared_bytes = ws_usage.shared * 1024;
233
234 return true;
235 }
236
237 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
238 // TODO(bapt) be sure we can't be precise
239 size_t priv = GetWorkingSetSize();
240 if (!priv)
241 return false;
242 ws_usage->priv = priv / 1024;
243 ws_usage->shareable = 0;
244 ws_usage->shared = 0;
245
246 return true;
247 }
248
249 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
250 return false;
251 }
252
253 static int GetProcessCPU(pid_t pid) {
254 struct kinfo_proc info;
255 size_t length;
256 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid, sizeof(struct kinfo_pro c), 0 };
257
258 if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) == -1)
259 return -1;
260
261 mib[5] = (int)(length / sizeof(struct kinfo_proc));
262
263 if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
264 return 0;
265
266 return info.p_pctcpu;
267 }
268
269 double ProcessMetrics::GetCPUUsage() {
270 struct timeval now;
271
272 int retval = gettimeofday(&now, NULL);
273 if (retval)
274 return 0;
275
276 int64 time = TimeValToMicroseconds(now);
277
278 if (last_time_ == 0) {
279 // First call, just set the last values.
280 last_time_ = time;
281 last_cpu_ = GetProcessCPU(process_);
282 return 0;
283 }
284
285 int64 time_delta = time - last_time_;
286 DCHECK_NE(time_delta, 0);
287
288 if (time_delta == 0)
289 return 0;
290
291 int cpu = GetProcessCPU(process_);
292
293 last_time_ = time;
294 last_cpu_ = cpu;
295
296 double percentage = static_cast<double>((cpu * 100.0) / FSCALE);
297
298 return percentage;
299 }
300
301 size_t GetSystemCommitCharge() {
302 int mib[] = { CTL_VM, VM_METER };
303 int pagesize;
304 struct vmtotal vmtotal;
305 unsigned long mem_total, mem_free, mem_inactive;
306 size_t len = sizeof(vmtotal);
307
308 if (sysctl(mib, arraysize(mib), &vmtotal, &len, NULL, 0) < 0)
309 return 0;
310
311 mem_total = vmtotal.t_vm;
312 mem_free = vmtotal.t_free;
313 mem_inactive = vmtotal.t_vm - vmtotal.t_avm;
314
315 pagesize = getpagesize();
316
317 return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize);
318 }
319
320 void EnableTerminationOnOutOfMemory() {
321 }
322
323 void EnableTerminationOnHeapCorruption() {
324 }
325
326 } // namespace base
OLDNEW
« no previous file with comments | « base/process_util.h ('k') | base/process_util_unittest.cc » ('j') | base/sys_info_openbsd.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698