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/param.h>
      8 #include <sys/sysctl.h>
      9 
     10 namespace base {
     11 
     12 // static
     13 ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
     14   return new ProcessMetrics(process);
     15 }
     16 
     17 size_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 
     34 size_t ProcessMetrics::GetPeakPagefileUsage() const {
     35   return 0;
     36 }
     37 
     38 size_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 
     55 size_t ProcessMetrics::GetPeakWorkingSetSize() const {
     56   return 0;
     57 }
     58 
     59 bool 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 
     75 bool 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 
     87 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
     88   return false;
     89 }
     90 
     91 static 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 
    108 double ProcessMetrics::GetCPUUsage() {
    109   struct timeval now;
    110 
    111   int retval = gettimeofday(&now, NULL);
    112   if (retval)
    113     return 0;
    114 
    115   int64 time = TimeValToMicroseconds(now);
    116 
    117   if (last_time_ == 0) {
    118     // First call, just set the last values.
    119     last_time_ = time;
    120     last_cpu_ = GetProcessCPU(process_);
    121     return 0;
    122   }
    123 
    124   int64 time_delta = time - last_time_;
    125   DCHECK_NE(time_delta, 0);
    126 
    127   if (time_delta == 0)
    128     return 0;
    129 
    130   int cpu = GetProcessCPU(process_);
    131 
    132   last_time_ = time;
    133   last_cpu_ = cpu;
    134 
    135   double percentage = static_cast<double>((cpu * 100.0) / FSCALE);
    136 
    137   return percentage;
    138 }
    139 
    140 ProcessMetrics::ProcessMetrics(ProcessHandle process)
    141     : process_(process),
    142       last_time_(0),
    143       last_system_time_(0),
    144       last_cpu_(0) {
    145 
    146   processor_count_ = base::SysInfo::NumberOfProcessors();
    147 }
    148 
    149 size_t GetSystemCommitCharge() {
    150   int mib[] = { CTL_VM, VM_METER };
    151   int pagesize;
    152   struct vmtotal vmtotal;
    153   unsigned long mem_total, mem_free, mem_inactive;
    154   size_t len = sizeof(vmtotal);
    155 
    156   if (sysctl(mib, arraysize(mib), &vmtotal, &len, NULL, 0) < 0)
    157     return 0;
    158 
    159   mem_total = vmtotal.t_vm;
    160   mem_free = vmtotal.t_free;
    161   mem_inactive = vmtotal.t_vm - vmtotal.t_avm;
    162 
    163   pagesize = getpagesize();
    164 
    165   return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize);
    166 }
    167 
    168 }  // namespace base
    169