Home | History | Annotate | Download | only in process
      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/sysctl.h>
      8 #include <sys/user.h>
      9 #include <unistd.h>
     10 
     11 #include "base/sys_info.h"
     12 
     13 namespace base {
     14 
     15 ProcessMetrics::ProcessMetrics(ProcessHandle process)
     16     : process_(process),
     17       last_system_time_(0),
     18       last_cpu_(0) {
     19   processor_count_ = base::SysInfo::NumberOfProcessors();
     20 }
     21 
     22 // static
     23 ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
     24   return new ProcessMetrics(process);
     25 }
     26 
     27 size_t ProcessMetrics::GetPagefileUsage() const {
     28   struct kinfo_proc info;
     29   int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_ };
     30   size_t length = sizeof(info);
     31 
     32   if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
     33     return 0;
     34 
     35   return info.ki_size;
     36 }
     37 
     38 size_t ProcessMetrics::GetPeakPagefileUsage() const {
     39   return 0;
     40 }
     41 
     42 size_t ProcessMetrics::GetWorkingSetSize() const {
     43   struct kinfo_proc info;
     44   int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_ };
     45   size_t length = sizeof(info);
     46 
     47   if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
     48     return 0;
     49 
     50   return info.ki_rssize * getpagesize();
     51 }
     52 
     53 size_t ProcessMetrics::GetPeakWorkingSetSize() const {
     54   return 0;
     55 }
     56 
     57 bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes,
     58                                     size_t* shared_bytes) {
     59   WorkingSetKBytes ws_usage;
     60   if (!GetWorkingSetKBytes(&ws_usage))
     61     return false;
     62 
     63   if (private_bytes)
     64     *private_bytes = ws_usage.priv << 10;
     65 
     66   if (shared_bytes)
     67     *shared_bytes = ws_usage.shared * 1024;
     68 
     69   return true;
     70 }
     71 
     72 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
     73 // TODO(bapt) be sure we can't be precise
     74   size_t priv = GetWorkingSetSize();
     75   if (!priv)
     76     return false;
     77   ws_usage->priv = priv / 1024;
     78   ws_usage->shareable = 0;
     79   ws_usage->shared = 0;
     80 
     81   return true;
     82 }
     83 
     84 double ProcessMetrics::GetCPUUsage() {
     85   struct kinfo_proc info;
     86   int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_ };
     87   size_t length = sizeof(info);
     88 
     89   if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
     90     return 0;
     91 
     92   return (info.ki_pctcpu / FSCALE) * 100.0;
     93 }
     94 
     95 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
     96   return false;
     97 }
     98 
     99 size_t GetSystemCommitCharge() {
    100   int mib[2], pagesize;
    101   unsigned long mem_total, mem_free, mem_inactive;
    102   size_t length = sizeof(mem_total);
    103 
    104   if (sysctl(mib, arraysize(mib), &mem_total, &length, NULL, 0) < 0)
    105     return 0;
    106 
    107   length = sizeof(mem_free);
    108   if (sysctlbyname("vm.stats.vm.v_free_count", &mem_free, &length, NULL, 0) < 0)
    109     return 0;
    110 
    111   length = sizeof(mem_inactive);
    112   if (sysctlbyname("vm.stats.vm.v_inactive_count", &mem_inactive, &length,
    113       NULL, 0) < 0) {
    114     return 0;
    115   }
    116 
    117   pagesize = getpagesize();
    118 
    119   return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize);
    120 }
    121 
    122 }  // namespace base
    123