// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/memory/memory_pressure_monitor_mac.h" #include #include #include #include "base/mac/mac_util.h" namespace base { namespace mac { MemoryPressureListener::MemoryPressureLevel MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure( int mac_memory_pressure) { switch (mac_memory_pressure) { case DISPATCH_MEMORYPRESSURE_NORMAL: return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; case DISPATCH_MEMORYPRESSURE_WARN: return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE; case DISPATCH_MEMORYPRESSURE_CRITICAL: return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL; } return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; } void MemoryPressureMonitor::NotifyMemoryPressureChanged( dispatch_source_s* event_source) { int mac_memory_pressure = dispatch_source_get_data(event_source); MemoryPressureListener::MemoryPressureLevel memory_pressure_level = MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure); MemoryPressureListener::NotifyMemoryPressure(memory_pressure_level); } MemoryPressureMonitor::MemoryPressureMonitor() : memory_level_event_source_(nullptr) { // _dispatch_source_type_memorypressure is not available prior to 10.9. dispatch_source_type_t dispatch_source_memorypressure = static_cast (dlsym(RTLD_NEXT, "_dispatch_source_type_memorypressure")); if (dispatch_source_memorypressure) { // The MemoryPressureListener doesn't want to know about transitions to // MEMORY_PRESSURE_LEVEL_NONE so don't watch for // DISPATCH_MEMORYPRESSURE_NORMAL notifications. memory_level_event_source_.reset( dispatch_source_create(dispatch_source_memorypressure, 0, DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))); dispatch_source_set_event_handler(memory_level_event_source_.get(), ^{ NotifyMemoryPressureChanged(memory_level_event_source_.get()); }); dispatch_retain(memory_level_event_source_.get()); dispatch_resume(memory_level_event_source_.get()); } } MemoryPressureMonitor::~MemoryPressureMonitor() { } MemoryPressureListener::MemoryPressureLevel MemoryPressureMonitor::GetCurrentPressureLevel() const { if (base::mac::IsOSMountainLionOrEarlier()) { return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; } int mac_memory_pressure; size_t length = sizeof(int); sysctlbyname("kern.memorystatus_vm_pressure_level", &mac_memory_pressure, &length, nullptr, 0); return MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure); } } // namespace mac } // namespace base