Index: base/mac/memory_pressure_monitor_mac.cc |
diff --git a/base/mac/memory_pressure_monitor_mac.cc b/base/mac/memory_pressure_monitor_mac.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..81727bb4a244a4336e72a7ccb2b8253792909170 |
--- /dev/null |
+++ b/base/mac/memory_pressure_monitor_mac.cc |
@@ -0,0 +1,76 @@ |
+// 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/mac/memory_pressure_monitor_mac.h" |
+ |
+#include <dlfcn.h> |
+#include <sys/sysctl.h> |
+ |
+#include "base/mac/mac_util.h" |
+ |
+namespace base { |
+ |
+MemoryPressureListener::MemoryPressureLevel |
+MemoryPressureMonitorMac::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 MemoryPressureMonitorMac::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); |
+} |
+ |
+MemoryPressureMonitorMac::MemoryPressureMonitorMac() |
+ : 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<dispatch_source_type_t> |
+ (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()); |
+ } |
+} |
+ |
+MemoryPressureMonitorMac::~MemoryPressureMonitorMac() { |
+} |
+ |
+MemoryPressureListener::MemoryPressureLevel |
+MemoryPressureMonitorMac::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 base |