• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors
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 <limits.h>
8 #include <mach/task.h>
9 #include <mach/vm_region.h>
10 #include <malloc/malloc.h>
11 #include <stddef.h>
12 
13 #include "base/check_op.h"
14 #include "base/mac/scoped_mach_port.h"
15 #include "base/memory/ptr_util.h"
16 #include "base/notreached.h"
17 #include "base/numerics/safe_conversions.h"
18 #include "build/blink_buildflags.h"
19 
20 namespace base {
21 
ProcessMetrics(ProcessHandle process)22 ProcessMetrics::ProcessMetrics(ProcessHandle process) {}
23 
24 // static
CreateProcessMetrics(ProcessHandle process)25 std::unique_ptr<ProcessMetrics> ProcessMetrics::CreateProcessMetrics(
26     ProcessHandle process) {
27   return WrapUnique(new ProcessMetrics(process));
28 }
29 
GetCumulativeCPUUsage()30 TimeDelta ProcessMetrics::GetCumulativeCPUUsage() {
31   NOTIMPLEMENTED();
32   return TimeDelta();
33 }
34 
35 // The blink code path pulls in process_metrics_posix.cc which
36 // is used for the following implementations.
37 #if !BUILDFLAG(USE_BLINK)
38 
GetMaxFds()39 size_t GetMaxFds() {
40   static const rlim_t kSystemDefaultMaxFds = 256;
41   rlim_t max_fds;
42   struct rlimit nofile;
43   if (getrlimit(RLIMIT_NOFILE, &nofile)) {
44     // Error case: Take a best guess.
45     max_fds = kSystemDefaultMaxFds;
46   } else {
47     max_fds = nofile.rlim_cur;
48   }
49 
50   if (max_fds > INT_MAX)
51     max_fds = INT_MAX;
52 
53   return static_cast<size_t>(max_fds);
54 }
55 
IncreaseFdLimitTo(unsigned int max_descriptors)56 void IncreaseFdLimitTo(unsigned int max_descriptors) {
57   // Unimplemented.
58 }
59 
GetMallocUsage()60 size_t ProcessMetrics::GetMallocUsage() {
61   malloc_statistics_t stats;
62   malloc_zone_statistics(nullptr, &stats);
63   return stats.size_in_use;
64 }
65 #endif  // !BUILDFLAG(USE_BLINK)
66 
67 // Bytes committed by the system.
GetSystemCommitCharge()68 size_t GetSystemCommitCharge() {
69   NOTIMPLEMENTED();
70   return 0;
71 }
72 
GetSystemMemoryInfo(SystemMemoryInfoKB * meminfo)73 bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo) {
74   struct host_basic_info hostinfo;
75   mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
76   base::mac::ScopedMachSendRight host(mach_host_self());
77   int result = host_info(host.get(), HOST_BASIC_INFO,
78                          reinterpret_cast<host_info_t>(&hostinfo), &count);
79   if (result != KERN_SUCCESS)
80     return false;
81 
82   DCHECK_EQ(HOST_BASIC_INFO_COUNT, count);
83   meminfo->total = static_cast<int>(hostinfo.max_mem / 1024);
84 
85   vm_statistics64_data_t vm_info;
86   count = HOST_VM_INFO64_COUNT;
87 
88   if (host_statistics64(host.get(), HOST_VM_INFO64,
89                         reinterpret_cast<host_info64_t>(&vm_info),
90                         &count) != KERN_SUCCESS) {
91     return false;
92   }
93   DCHECK_EQ(HOST_VM_INFO64_COUNT, count);
94 
95   // Check that PAGE_SIZE is divisible by 1024 (2^10).
96   CHECK_EQ(PAGE_SIZE, (PAGE_SIZE >> 10) << 10);
97   meminfo->free = saturated_cast<int>(
98       PAGE_SIZE / 1024 * (vm_info.free_count - vm_info.speculative_count));
99   meminfo->speculative =
100       saturated_cast<int>(PAGE_SIZE / 1024 * vm_info.speculative_count);
101   meminfo->file_backed =
102       saturated_cast<int>(PAGE_SIZE / 1024 * vm_info.external_page_count);
103   meminfo->purgeable =
104       saturated_cast<int>(PAGE_SIZE / 1024 * vm_info.purgeable_count);
105 
106   return true;
107 }
108 
ParseOutputFromVMRegion(kern_return_t kr)109 MachVMRegionResult ParseOutputFromVMRegion(kern_return_t kr) {
110   if (kr == KERN_INVALID_ADDRESS) {
111     // We're at the end of the address space.
112     return MachVMRegionResult::Finished;
113   } else if (kr != KERN_SUCCESS) {
114     return MachVMRegionResult::Error;
115   }
116   return MachVMRegionResult::Success;
117 }
118 
GetBasicInfo(mach_port_t task,mach_vm_size_t * size,mach_vm_address_t * address,vm_region_basic_info_64 * info)119 MachVMRegionResult GetBasicInfo(mach_port_t task,
120                                 mach_vm_size_t* size,
121                                 mach_vm_address_t* address,
122                                 vm_region_basic_info_64* info) {
123   mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
124   mac::ScopedMachSendRight object_name;
125   kern_return_t kr =
126       vm_region_64(task, reinterpret_cast<vm_address_t*>(address),
127                    reinterpret_cast<vm_size_t*>(size), VM_REGION_BASIC_INFO_64,
128                    reinterpret_cast<vm_region_info_t>(info), &info_count,
129                    mac::ScopedMachSendRight::Receiver(object_name).get());
130   return ParseOutputFromVMRegion(kr);
131 }
132 
133 }  // namespace base
134