| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "tools/memory/simulator/system_metrics_provider_mac.h" |
| |
| #include <mach/mach.h> |
| #include <mach/mach_time.h> |
| |
| #include "base/apple/mach_logging.h" |
| #include "base/apple/scoped_mach_port.h" |
| #include "base/time/time.h" |
| #include "tools/memory/simulator/utils.h" |
| |
| namespace memory_simulator { |
| |
| SystemMetricsProviderMac::SystemMetricsProviderMac() = default; |
| SystemMetricsProviderMac::~SystemMetricsProviderMac() = default; |
| |
| std::vector<std::string> SystemMetricsProviderMac::GetMetricNames() { |
| return {"total(gb)", |
| "free(gb)", |
| "active(gb)", |
| "inactive(gb)", |
| "wired(gb)", |
| "purgeable_count(gb)", |
| "speculative(gb)", |
| "compressor(gb)", |
| "throttled(gb)", |
| "file_backed(gb)", |
| "anonymous(gb)", |
| "uncompressed_in_compressor(gb)", |
| "reactivations(mb/s)", |
| "pageins(mb/s)", |
| "pageouts(mb/s)", |
| "faults(mb/s)", |
| "cow_faults(mb/s)", |
| "cache_lookups(mb/s)", |
| "cache_hits(mb/s)", |
| "purges(mb/s)", |
| "decompressions(mb/s)", |
| "compressions(mb/s)", |
| "swapins(mb/s)", |
| "swapouts(mb/s)"}; |
| } |
| |
| std::map<std::string, double> SystemMetricsProviderMac::GetMetricValues( |
| base::TimeTicks now) { |
| std::map<std::string, double> metrics; |
| |
| struct host_basic_info hostinfo; |
| mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; |
| base::apple::ScopedMachSendRight host(mach_host_self()); |
| int result = host_info(host.get(), HOST_BASIC_INFO, |
| reinterpret_cast<host_info_t>(&hostinfo), &count); |
| CHECK_EQ(result, KERN_SUCCESS); |
| |
| CHECK_EQ(HOST_BASIC_INFO_COUNT, count); |
| metrics["total(gb)"] = BytesToGB(hostinfo.max_mem); |
| |
| vm_statistics64_data_t vm_info; |
| count = HOST_VM_INFO64_COUNT; |
| CHECK_EQ(host_statistics64(host.get(), HOST_VM_INFO64, |
| reinterpret_cast<host_info64_t>(&vm_info), &count), |
| KERN_SUCCESS); |
| CHECK_EQ(HOST_VM_INFO64_COUNT, count); |
| |
| // Free memory includes speculative memory. |
| metrics["free(gb)"] = PagesToGB(vm_info.free_count); |
| metrics["active(gb)"] = PagesToGB(vm_info.active_count); |
| metrics["inactive(gb)"] = PagesToGB(vm_info.inactive_count); |
| metrics["wired(gb)"] = PagesToGB(vm_info.wire_count); |
| metrics["purgeable_count(gb)"] = PagesToGB(vm_info.purgeable_count); |
| metrics["speculative(gb)"] = PagesToGB(vm_info.speculative_count); |
| metrics["compressor(gb)"] = PagesToGB(vm_info.compressor_page_count); |
| metrics["throttled(gb)"] = PagesToGB(vm_info.throttled_count); |
| metrics["file_backed(gb)"] = PagesToGB(vm_info.external_page_count); |
| metrics["anonymous(gb)"] = PagesToGB(vm_info.internal_page_count); |
| metrics["uncompressed_in_compressor(gb)"] = |
| PagesToGB(vm_info.total_uncompressed_pages_in_compressor); |
| |
| if (!prev_time_.is_null()) { |
| const base::TimeDelta elapsed = now - prev_time_; |
| |
| metrics["reactivations(mb/s)"] = PagesToMBPerSec( |
| prev_vm_info_.reactivations, vm_info.reactivations, elapsed); |
| metrics["pageins(mb/s)"] = |
| PagesToMBPerSec(prev_vm_info_.pageins, vm_info.pageins, elapsed); |
| metrics["pageouts(mb/s)"] = |
| PagesToMBPerSec(prev_vm_info_.pageouts, vm_info.pageouts, elapsed); |
| metrics["faults(mb/s)"] = |
| PagesToMBPerSec(prev_vm_info_.faults, vm_info.faults, elapsed); |
| metrics["cow_faults(mb/s)"] = |
| PagesToMBPerSec(prev_vm_info_.cow_faults, vm_info.cow_faults, elapsed); |
| metrics["cache_lookups(mb/s)"] = |
| PagesToMBPerSec(prev_vm_info_.lookups, vm_info.lookups, elapsed); |
| metrics["cache_hits(mb/s)"] = |
| PagesToMBPerSec(prev_vm_info_.hits, vm_info.hits, elapsed); |
| metrics["purges(mb/s)"] = |
| PagesToMBPerSec(prev_vm_info_.purges, vm_info.purges, elapsed); |
| metrics["decompressions(mb/s)"] = PagesToMBPerSec( |
| prev_vm_info_.decompressions, vm_info.decompressions, elapsed); |
| metrics["compressions(mb/s)"] = PagesToMBPerSec( |
| prev_vm_info_.compressions, vm_info.compressions, elapsed); |
| metrics["swapins(mb/s)"] = |
| PagesToMBPerSec(prev_vm_info_.swapins, vm_info.swapins, elapsed); |
| metrics["swapouts(mb/s)"] = |
| PagesToMBPerSec(prev_vm_info_.swapouts, vm_info.swapouts, elapsed); |
| } |
| |
| prev_time_ = now; |
| prev_vm_info_ = vm_info; |
| |
| return metrics; |
| } |
| |
| } // namespace memory_simulator |