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

Side by Side Diff: base/process_util_linux.cc

Issue 3056029: Move the number conversions from string_util to a new file.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « base/json/json_writer.cc ('k') | base/simple_thread.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/process_util.h" 5 #include "base/process_util.h"
6 6
7 #include <ctype.h> 7 #include <ctype.h>
8 #include <dirent.h> 8 #include <dirent.h>
9 #include <dlfcn.h> 9 #include <dlfcn.h>
10 #include <errno.h> 10 #include <errno.h>
11 #include <fcntl.h> 11 #include <fcntl.h>
12 #include <sys/time.h> 12 #include <sys/time.h>
13 #include <sys/types.h> 13 #include <sys/types.h>
14 #include <sys/wait.h> 14 #include <sys/wait.h>
15 #include <time.h> 15 #include <time.h>
16 #include <unistd.h> 16 #include <unistd.h>
17 17
18 #include "base/file_util.h" 18 #include "base/file_util.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/string_number_conversions.h"
20 #include "base/string_tokenizer.h" 21 #include "base/string_tokenizer.h"
21 #include "base/string_util.h" 22 #include "base/string_util.h"
22 #include "base/sys_info.h" 23 #include "base/sys_info.h"
23 24
24 namespace { 25 namespace {
25 26
26 enum ParsingState { 27 enum ParsingState {
27 KEY_NAME, 28 KEY_NAME,
28 KEY_VALUE 29 KEY_VALUE
29 }; 30 };
30 31
31 // Reads /proc/<pid>/stat and populates |proc_stats| with the values split by 32 // Reads /proc/<pid>/stat and populates |proc_stats| with the values split by
32 // spaces. 33 // spaces.
33 void GetProcStats(pid_t pid, std::vector<std::string>* proc_stats) { 34 void GetProcStats(pid_t pid, std::vector<std::string>* proc_stats) {
34 FilePath stat_file("/proc"); 35 FilePath stat_file("/proc");
35 stat_file = stat_file.Append(IntToString(pid)); 36 stat_file = stat_file.Append(base::IntToString(pid));
36 stat_file = stat_file.Append("stat"); 37 stat_file = stat_file.Append("stat");
37 std::string mem_stats; 38 std::string mem_stats;
38 if (!file_util::ReadFileToString(stat_file, &mem_stats)) 39 if (!file_util::ReadFileToString(stat_file, &mem_stats))
39 return; 40 return;
40 SplitString(mem_stats, ' ', proc_stats); 41 SplitString(mem_stats, ' ', proc_stats);
41 } 42 }
42 43
43 } // namespace 44 } // namespace
44 45
45 namespace base { 46 namespace base {
46 47
47 ProcessId GetParentProcessId(ProcessHandle process) { 48 ProcessId GetParentProcessId(ProcessHandle process) {
48 FilePath stat_file("/proc"); 49 FilePath stat_file("/proc");
49 stat_file = stat_file.Append(IntToString(process)); 50 stat_file = stat_file.Append(base::IntToString(process));
50 stat_file = stat_file.Append("status"); 51 stat_file = stat_file.Append("status");
51 std::string status; 52 std::string status;
52 if (!file_util::ReadFileToString(stat_file, &status)) 53 if (!file_util::ReadFileToString(stat_file, &status))
53 return -1; 54 return -1;
54 55
55 StringTokenizer tokenizer(status, ":\n"); 56 StringTokenizer tokenizer(status, ":\n");
56 ParsingState state = KEY_NAME; 57 ParsingState state = KEY_NAME;
57 std::string last_key_name; 58 std::string last_key_name;
58 while (tokenizer.GetNext()) { 59 while (tokenizer.GetNext()) {
59 switch (state) { 60 switch (state) {
60 case KEY_NAME: 61 case KEY_NAME:
61 last_key_name = tokenizer.token(); 62 last_key_name = tokenizer.token();
62 state = KEY_VALUE; 63 state = KEY_VALUE;
63 break; 64 break;
64 case KEY_VALUE: 65 case KEY_VALUE:
65 DCHECK(!last_key_name.empty()); 66 DCHECK(!last_key_name.empty());
66 if (last_key_name == "PPid") { 67 if (last_key_name == "PPid") {
67 pid_t ppid = StringToInt(tokenizer.token()); 68 int ppid;
69 base::StringToInt(tokenizer.token(), &ppid);
68 return ppid; 70 return ppid;
69 } 71 }
70 state = KEY_NAME; 72 state = KEY_NAME;
71 break; 73 break;
72 } 74 }
73 } 75 }
74 NOTREACHED(); 76 NOTREACHED();
75 return -1; 77 return -1;
76 } 78 }
77 79
78 FilePath GetProcessExecutablePath(ProcessHandle process) { 80 FilePath GetProcessExecutablePath(ProcessHandle process) {
79 FilePath stat_file("/proc"); 81 FilePath stat_file("/proc");
80 stat_file = stat_file.Append(IntToString(process)); 82 stat_file = stat_file.Append(base::IntToString(process));
81 stat_file = stat_file.Append("exe"); 83 stat_file = stat_file.Append("exe");
82 char exename[2048]; 84 char exename[2048];
83 ssize_t len = readlink(stat_file.value().c_str(), exename, sizeof(exename)); 85 ssize_t len = readlink(stat_file.value().c_str(), exename, sizeof(exename));
84 if (len < 1) { 86 if (len < 1) {
85 // No such process. Happens frequently in e.g. TerminateAllChromeProcesses 87 // No such process. Happens frequently in e.g. TerminateAllChromeProcesses
86 return FilePath(); 88 return FilePath();
87 } 89 }
88 return FilePath(std::string(exename, len)); 90 return FilePath(std::string(exename, len));
89 } 91 }
90 92
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 // static 200 // static
199 ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) { 201 ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
200 return new ProcessMetrics(process); 202 return new ProcessMetrics(process);
201 } 203 }
202 204
203 // On linux, we return vsize. 205 // On linux, we return vsize.
204 size_t ProcessMetrics::GetPagefileUsage() const { 206 size_t ProcessMetrics::GetPagefileUsage() const {
205 std::vector<std::string> proc_stats; 207 std::vector<std::string> proc_stats;
206 GetProcStats(process_, &proc_stats); 208 GetProcStats(process_, &proc_stats);
207 const size_t kVmSize = 22; 209 const size_t kVmSize = 22;
208 if (proc_stats.size() > kVmSize) 210 if (proc_stats.size() > kVmSize) {
209 return static_cast<size_t>(StringToInt(proc_stats[kVmSize])); 211 int vm_size;
212 base::StringToInt(proc_stats[kVmSize], &vm_size);
213 return static_cast<size_t>(vm_size);
214 }
210 return 0; 215 return 0;
211 } 216 }
212 217
213 // On linux, we return the high water mark of vsize. 218 // On linux, we return the high water mark of vsize.
214 size_t ProcessMetrics::GetPeakPagefileUsage() const { 219 size_t ProcessMetrics::GetPeakPagefileUsage() const {
215 std::vector<std::string> proc_stats; 220 std::vector<std::string> proc_stats;
216 GetProcStats(process_, &proc_stats); 221 GetProcStats(process_, &proc_stats);
217 const size_t kVmPeak = 21; 222 const size_t kVmPeak = 21;
218 if (proc_stats.size() > kVmPeak) 223 if (proc_stats.size() > kVmPeak) {
219 return static_cast<size_t>(StringToInt(proc_stats[kVmPeak])); 224 int vm_peak;
225 if (base::StringToInt(proc_stats[kVmPeak], &vm_peak))
226 return vm_peak;
227 }
220 return 0; 228 return 0;
221 } 229 }
222 230
223 // On linux, we return RSS. 231 // On linux, we return RSS.
224 size_t ProcessMetrics::GetWorkingSetSize() const { 232 size_t ProcessMetrics::GetWorkingSetSize() const {
225 std::vector<std::string> proc_stats; 233 std::vector<std::string> proc_stats;
226 GetProcStats(process_, &proc_stats); 234 GetProcStats(process_, &proc_stats);
227 const size_t kVmRss = 23; 235 const size_t kVmRss = 23;
228 if (proc_stats.size() > kVmRss) { 236 if (proc_stats.size() > kVmRss) {
229 size_t num_pages = static_cast<size_t>(StringToInt(proc_stats[kVmRss])); 237 int num_pages;
230 return num_pages * getpagesize(); 238 if (base::StringToInt(proc_stats[kVmRss], &num_pages))
239 return static_cast<size_t>(num_pages) * getpagesize();
231 } 240 }
232 return 0; 241 return 0;
233 } 242 }
234 243
235 // On linux, we return the high water mark of RSS. 244 // On linux, we return the high water mark of RSS.
236 size_t ProcessMetrics::GetPeakWorkingSetSize() const { 245 size_t ProcessMetrics::GetPeakWorkingSetSize() const {
237 std::vector<std::string> proc_stats; 246 std::vector<std::string> proc_stats;
238 GetProcStats(process_, &proc_stats); 247 GetProcStats(process_, &proc_stats);
239 const size_t kVmHwm = 23; 248 const size_t kVmHwm = 23;
240 if (proc_stats.size() > kVmHwm) { 249 if (proc_stats.size() > kVmHwm) {
241 size_t num_pages = static_cast<size_t>(StringToInt(proc_stats[kVmHwm])); 250 int num_pages;
242 return num_pages * getpagesize(); 251 base::StringToInt(proc_stats[kVmHwm], &num_pages);
252 return static_cast<size_t>(num_pages) * getpagesize();
243 } 253 }
244 return 0; 254 return 0;
245 } 255 }
246 256
247 bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes, 257 bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes,
248 size_t* shared_bytes) { 258 size_t* shared_bytes) {
249 WorkingSetKBytes ws_usage; 259 WorkingSetKBytes ws_usage;
250 if (!GetWorkingSetKBytes(&ws_usage)) 260 if (!GetWorkingSetKBytes(&ws_usage))
251 return false; 261 return false;
252 262
253 if (private_bytes) 263 if (private_bytes)
254 *private_bytes = ws_usage.priv << 10; 264 *private_bytes = ws_usage.priv << 10;
255 265
256 if (shared_bytes) 266 if (shared_bytes)
257 *shared_bytes = ws_usage.shared * 1024; 267 *shared_bytes = ws_usage.shared * 1024;
258 268
259 return true; 269 return true;
260 } 270 }
261 271
262 // Private and Shared working set sizes are obtained from /proc/<pid>/smaps. 272 // Private and Shared working set sizes are obtained from /proc/<pid>/smaps.
263 // When that's not available, use the values from /proc<pid>/statm as a 273 // When that's not available, use the values from /proc<pid>/statm as a
264 // close approximation. 274 // close approximation.
265 // See http://www.pixelbeat.org/scripts/ps_mem.py 275 // See http://www.pixelbeat.org/scripts/ps_mem.py
266 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { 276 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
267 FilePath stat_file = 277 FilePath stat_file =
268 FilePath("/proc").Append(IntToString(process_)).Append("smaps"); 278 FilePath("/proc").Append(base::IntToString(process_)).Append("smaps");
269 std::string smaps; 279 std::string smaps;
270 int private_kb = 0; 280 int private_kb = 0;
271 int pss_kb = 0; 281 int pss_kb = 0;
272 bool have_pss = false; 282 bool have_pss = false;
273 if (file_util::ReadFileToString(stat_file, &smaps) && smaps.length() > 0) { 283 if (file_util::ReadFileToString(stat_file, &smaps) && smaps.length() > 0) {
274 const std::string private_prefix = "Private_"; 284 const std::string private_prefix = "Private_";
275 const std::string pss_prefix = "Pss"; 285 const std::string pss_prefix = "Pss";
276 StringTokenizer tokenizer(smaps, ":\n"); 286 StringTokenizer tokenizer(smaps, ":\n");
277 StringPiece last_key_name; 287 StringPiece last_key_name;
278 ParsingState state = KEY_NAME; 288 ParsingState state = KEY_NAME;
279 while (tokenizer.GetNext()) { 289 while (tokenizer.GetNext()) {
280 switch (state) { 290 switch (state) {
281 case KEY_NAME: 291 case KEY_NAME:
282 last_key_name = tokenizer.token_piece(); 292 last_key_name = tokenizer.token_piece();
283 state = KEY_VALUE; 293 state = KEY_VALUE;
284 break; 294 break;
285 case KEY_VALUE: 295 case KEY_VALUE:
286 if (last_key_name.empty()) { 296 if (last_key_name.empty()) {
287 NOTREACHED(); 297 NOTREACHED();
288 return false; 298 return false;
289 } 299 }
290 if (last_key_name.starts_with(private_prefix)) { 300 if (last_key_name.starts_with(private_prefix)) {
291 private_kb += StringToInt(tokenizer.token()); 301 int cur;
302 base::StringToInt(tokenizer.token(), &cur);
303 private_kb += cur;
292 } else if (last_key_name.starts_with(pss_prefix)) { 304 } else if (last_key_name.starts_with(pss_prefix)) {
293 have_pss = true; 305 have_pss = true;
294 pss_kb += StringToInt(tokenizer.token()); 306 int cur;
307 base::StringToInt(tokenizer.token(), &cur);
308 pss_kb += cur;
295 } 309 }
296 state = KEY_NAME; 310 state = KEY_NAME;
297 break; 311 break;
298 } 312 }
299 } 313 }
300 } else { 314 } else {
301 // Try statm if smaps is empty because of the SUID sandbox. 315 // Try statm if smaps is empty because of the SUID sandbox.
302 // First we need to get the page size though. 316 // First we need to get the page size though.
303 int page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; 317 int page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024;
304 if (page_size_kb <= 0) 318 if (page_size_kb <= 0)
305 return false; 319 return false;
306 320
307 stat_file = 321 stat_file =
308 FilePath("/proc").Append(IntToString(process_)).Append("statm"); 322 FilePath("/proc").Append(base::IntToString(process_)).Append("statm");
309 std::string statm; 323 std::string statm;
310 if (!file_util::ReadFileToString(stat_file, &statm) || statm.length() == 0) 324 if (!file_util::ReadFileToString(stat_file, &statm) || statm.length() == 0)
311 return false; 325 return false;
312 326
313 std::vector<std::string> statm_vec; 327 std::vector<std::string> statm_vec;
314 SplitString(statm, ' ', &statm_vec); 328 SplitString(statm, ' ', &statm_vec);
315 if (statm_vec.size() != 7) 329 if (statm_vec.size() != 7)
316 return false; // Not the format we expect. 330 return false; // Not the format we expect.
317 private_kb = StringToInt(statm_vec[1]) - StringToInt(statm_vec[2]); 331
318 private_kb *= page_size_kb; 332 int statm1, statm2;
333 base::StringToInt(statm_vec[1], &statm1);
334 base::StringToInt(statm_vec[2], &statm2);
335 private_kb = (statm1 - statm2) * page_size_kb;
319 } 336 }
320 ws_usage->priv = private_kb; 337 ws_usage->priv = private_kb;
321 // Sharable is not calculated, as it does not provide interesting data. 338 // Sharable is not calculated, as it does not provide interesting data.
322 ws_usage->shareable = 0; 339 ws_usage->shareable = 0;
323 340
324 ws_usage->shared = 0; 341 ws_usage->shared = 0;
325 if (have_pss) 342 if (have_pss)
326 ws_usage->shared = pss_kb; 343 ws_usage->shared = pss_kb;
327 return true; 344 return true;
328 } 345 }
329 346
330 // To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING 347 // To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING
331 // in your kernel configuration. 348 // in your kernel configuration.
332 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { 349 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
333 std::string proc_io_contents; 350 std::string proc_io_contents;
334 FilePath io_file("/proc"); 351 FilePath io_file("/proc");
335 io_file = io_file.Append(IntToString(process_)); 352 io_file = io_file.Append(base::IntToString(process_));
336 io_file = io_file.Append("io"); 353 io_file = io_file.Append("io");
337 if (!file_util::ReadFileToString(io_file, &proc_io_contents)) 354 if (!file_util::ReadFileToString(io_file, &proc_io_contents))
338 return false; 355 return false;
339 356
340 (*io_counters).OtherOperationCount = 0; 357 (*io_counters).OtherOperationCount = 0;
341 (*io_counters).OtherTransferCount = 0; 358 (*io_counters).OtherTransferCount = 0;
342 359
343 StringTokenizer tokenizer(proc_io_contents, ": \n"); 360 StringTokenizer tokenizer(proc_io_contents, ": \n");
344 ParsingState state = KEY_NAME; 361 ParsingState state = KEY_NAME;
345 std::string last_key_name; 362 std::string last_key_name;
346 while (tokenizer.GetNext()) { 363 while (tokenizer.GetNext()) {
347 switch (state) { 364 switch (state) {
348 case KEY_NAME: 365 case KEY_NAME:
349 last_key_name = tokenizer.token(); 366 last_key_name = tokenizer.token();
350 state = KEY_VALUE; 367 state = KEY_VALUE;
351 break; 368 break;
352 case KEY_VALUE: 369 case KEY_VALUE:
353 DCHECK(!last_key_name.empty()); 370 DCHECK(!last_key_name.empty());
354 if (last_key_name == "syscr") { 371 if (last_key_name == "syscr") {
355 (*io_counters).ReadOperationCount = StringToInt64(tokenizer.token()); 372 base::StringToInt64(tokenizer.token(),
373 reinterpret_cast<int64*>(&(*io_counters).ReadOperationCount));
356 } else if (last_key_name == "syscw") { 374 } else if (last_key_name == "syscw") {
357 (*io_counters).WriteOperationCount = StringToInt64(tokenizer.token()); 375 base::StringToInt64(tokenizer.token(),
376 reinterpret_cast<int64*>(&(*io_counters).WriteOperationCount));
358 } else if (last_key_name == "rchar") { 377 } else if (last_key_name == "rchar") {
359 (*io_counters).ReadTransferCount = StringToInt64(tokenizer.token()); 378 base::StringToInt64(tokenizer.token(),
379 reinterpret_cast<int64*>(&(*io_counters).ReadTransferCount));
360 } else if (last_key_name == "wchar") { 380 } else if (last_key_name == "wchar") {
361 (*io_counters).WriteTransferCount = StringToInt64(tokenizer.token()); 381 base::StringToInt64(tokenizer.token(),
382 reinterpret_cast<int64*>(&(*io_counters).WriteTransferCount));
362 } 383 }
363 state = KEY_NAME; 384 state = KEY_NAME;
364 break; 385 break;
365 } 386 }
366 } 387 }
367 return true; 388 return true;
368 } 389 }
369 390
370 391
371 // Exposed for testing. 392 // Exposed for testing.
372 int ParseProcStatCPU(const std::string& input) { 393 int ParseProcStatCPU(const std::string& input) {
373 // /proc/<pid>/stat contains the process name in parens. In case the 394 // /proc/<pid>/stat contains the process name in parens. In case the
374 // process name itself contains parens, skip past them. 395 // process name itself contains parens, skip past them.
375 std::string::size_type rparen = input.rfind(')'); 396 std::string::size_type rparen = input.rfind(')');
376 if (rparen == std::string::npos) 397 if (rparen == std::string::npos)
377 return -1; 398 return -1;
378 399
379 // From here, we expect a bunch of space-separated fields, where the 400 // From here, we expect a bunch of space-separated fields, where the
380 // 0-indexed 11th and 12th are utime and stime. On two different machines 401 // 0-indexed 11th and 12th are utime and stime. On two different machines
381 // I found 42 and 39 fields, so let's just expect the ones we need. 402 // I found 42 and 39 fields, so let's just expect the ones we need.
382 std::vector<std::string> fields; 403 std::vector<std::string> fields;
383 SplitString(input.substr(rparen + 2), ' ', &fields); 404 SplitString(input.substr(rparen + 2), ' ', &fields);
384 if (fields.size() < 13) 405 if (fields.size() < 13)
385 return -1; // Output not in the format we expect. 406 return -1; // Output not in the format we expect.
386 407
387 return StringToInt(fields[11]) + StringToInt(fields[12]); 408 int fields11, fields12;
409 base::StringToInt(fields[11], &fields11);
410 base::StringToInt(fields[12], &fields12);
411 return fields11 + fields12;
388 } 412 }
389 413
390 // Get the total CPU of a single process. Return value is number of jiffies 414 // Get the total CPU of a single process. Return value is number of jiffies
391 // on success or -1 on error. 415 // on success or -1 on error.
392 static int GetProcessCPU(pid_t pid) { 416 static int GetProcessCPU(pid_t pid) {
393 // Use /proc/<pid>/task to find all threads and parse their /stat file. 417 // Use /proc/<pid>/task to find all threads and parse their /stat file.
394 FilePath path = FilePath(StringPrintf("/proc/%d/task/", pid)); 418 FilePath path = FilePath(StringPrintf("/proc/%d/task/", pid));
395 419
396 DIR* dir = opendir(path.value().c_str()); 420 DIR* dir = opendir(path.value().c_str());
397 if (!dir) { 421 if (!dir) {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 LOG(WARNING) << "Failed to parse /proc/meminfo. Only found " << 515 LOG(WARNING) << "Failed to parse /proc/meminfo. Only found " <<
492 meminfo_fields.size() << " fields."; 516 meminfo_fields.size() << " fields.";
493 return 0; 517 return 0;
494 } 518 }
495 519
496 DCHECK_EQ(meminfo_fields[kMemTotalIndex-1], "MemTotal:"); 520 DCHECK_EQ(meminfo_fields[kMemTotalIndex-1], "MemTotal:");
497 DCHECK_EQ(meminfo_fields[kMemFreeIndex-1], "MemFree:"); 521 DCHECK_EQ(meminfo_fields[kMemFreeIndex-1], "MemFree:");
498 DCHECK_EQ(meminfo_fields[kMemBuffersIndex-1], "Buffers:"); 522 DCHECK_EQ(meminfo_fields[kMemBuffersIndex-1], "Buffers:");
499 DCHECK_EQ(meminfo_fields[kMemCacheIndex-1], "Cached:"); 523 DCHECK_EQ(meminfo_fields[kMemCacheIndex-1], "Cached:");
500 524
501 size_t result_in_kb; 525 int mem_total, mem_free, mem_buffers, mem_cache;
502 result_in_kb = StringToInt(meminfo_fields[kMemTotalIndex]); 526 base::StringToInt(meminfo_fields[kMemTotalIndex], &mem_total);
503 result_in_kb -= StringToInt(meminfo_fields[kMemFreeIndex]); 527 base::StringToInt(meminfo_fields[kMemFreeIndex], &mem_free);
504 result_in_kb -= StringToInt(meminfo_fields[kMemBuffersIndex]); 528 base::StringToInt(meminfo_fields[kMemBuffersIndex], &mem_buffers);
505 result_in_kb -= StringToInt(meminfo_fields[kMemCacheIndex]); 529 base::StringToInt(meminfo_fields[kMemCacheIndex], &mem_cache);
506 530
507 return result_in_kb; 531 return mem_total - mem_free - mem_buffers - mem_cache;
508 } 532 }
509 533
510 namespace { 534 namespace {
511 535
512 void OnNoMemorySize(size_t size) { 536 void OnNoMemorySize(size_t size) {
513 if (size != 0) 537 if (size != 0)
514 LOG(FATAL) << "Out of memory, size = " << size; 538 LOG(FATAL) << "Out of memory, size = " << size;
515 LOG(FATAL) << "Out of memory."; 539 LOG(FATAL) << "Out of memory.";
516 } 540 }
517 541
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 std::set_new_handler(&OnNoMemory); 630 std::set_new_handler(&OnNoMemory);
607 // If we're using glibc's allocator, the above functions will override 631 // If we're using glibc's allocator, the above functions will override
608 // malloc and friends and make them die on out of memory. 632 // malloc and friends and make them die on out of memory.
609 } 633 }
610 634
611 bool AdjustOOMScore(ProcessId process, int score) { 635 bool AdjustOOMScore(ProcessId process, int score) {
612 if (score < 0 || score > 15) 636 if (score < 0 || score > 15)
613 return false; 637 return false;
614 638
615 FilePath oom_adj("/proc"); 639 FilePath oom_adj("/proc");
616 oom_adj = oom_adj.Append(Int64ToString(process)); 640 oom_adj = oom_adj.Append(base::Int64ToString(process));
617 oom_adj = oom_adj.AppendASCII("oom_adj"); 641 oom_adj = oom_adj.AppendASCII("oom_adj");
618 642
619 if (!file_util::PathExists(oom_adj)) 643 if (!file_util::PathExists(oom_adj))
620 return false; 644 return false;
621 645
622 std::string score_str = IntToString(score); 646 std::string score_str = base::IntToString(score);
623 return (static_cast<int>(score_str.length()) == 647 return (static_cast<int>(score_str.length()) ==
624 file_util::WriteFile(oom_adj, score_str.c_str(), score_str.length())); 648 file_util::WriteFile(oom_adj, score_str.c_str(), score_str.length()));
625 } 649 }
626 650
627 } // namespace base 651 } // namespace base
OLDNEW
« no previous file with comments | « base/json/json_writer.cc ('k') | base/simple_thread.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698