1 // Copyright 2015 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.
5 #include "base/memory/memory_pressure_monitor_mac.h"
8 #include <sys/sysctl.h>
10 #include "base/mac/mac_util.h"
15 MemoryPressureListener::MemoryPressureLevel
16 MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure(
17 int mac_memory_pressure
) {
18 switch (mac_memory_pressure
) {
19 case DISPATCH_MEMORYPRESSURE_NORMAL
:
20 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE
;
21 case DISPATCH_MEMORYPRESSURE_WARN
:
22 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE
;
23 case DISPATCH_MEMORYPRESSURE_CRITICAL
:
24 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL
;
26 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE
;
29 void MemoryPressureMonitor::NotifyMemoryPressureChanged(
30 dispatch_source_s
* event_source
) {
31 int mac_memory_pressure
= dispatch_source_get_data(event_source
);
32 MemoryPressureListener::MemoryPressureLevel memory_pressure_level
=
33 MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure
);
34 MemoryPressureListener::NotifyMemoryPressure(memory_pressure_level
);
37 MemoryPressureMonitor::MemoryPressureMonitor()
38 : memory_level_event_source_(nullptr) {
39 // _dispatch_source_type_memorypressure is not available prior to 10.9.
40 dispatch_source_type_t dispatch_source_memorypressure
=
41 static_cast<dispatch_source_type_t
>
42 (dlsym(RTLD_NEXT
, "_dispatch_source_type_memorypressure"));
43 if (dispatch_source_memorypressure
) {
44 // The MemoryPressureListener doesn't want to know about transitions to
45 // MEMORY_PRESSURE_LEVEL_NONE so don't watch for
46 // DISPATCH_MEMORYPRESSURE_NORMAL notifications.
47 memory_level_event_source_
.reset(
48 dispatch_source_create(dispatch_source_memorypressure
, 0,
49 DISPATCH_MEMORYPRESSURE_WARN
|
50 DISPATCH_MEMORYPRESSURE_CRITICAL
,
51 dispatch_get_global_queue(
52 DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0)));
54 dispatch_source_set_event_handler(memory_level_event_source_
.get(), ^{
55 NotifyMemoryPressureChanged(memory_level_event_source_
.get());
57 dispatch_retain(memory_level_event_source_
.get());
58 dispatch_resume(memory_level_event_source_
.get());
62 MemoryPressureMonitor::~MemoryPressureMonitor() {
65 MemoryPressureListener::MemoryPressureLevel
66 MemoryPressureMonitor::GetCurrentPressureLevel() const {
67 if (base::mac::IsOSMountainLionOrEarlier()) {
68 return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE
;
70 int mac_memory_pressure
;
71 size_t length
= sizeof(int);
72 sysctlbyname("kern.memorystatus_vm_pressure_level", &mac_memory_pressure
,
74 return MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure
);