1/* 2 * Copyright (C) 2011 Apple Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef MemoryPressureHandler_h 27#define MemoryPressureHandler_h 28 29#include <atomic> 30#include <time.h> 31#include <wtf/FastMalloc.h> 32 33#if PLATFORM(IOS) 34#include <wtf/ThreadingPrimitives.h> 35#endif 36 37namespace WebCore { 38 39#if PLATFORM(IOS) 40enum MemoryPressureReason { 41 MemoryPressureReasonNone = 0 << 0, 42 MemoryPressureReasonVMPressure = 1 << 0, 43 MemoryPressureReasonVMStatus = 1 << 1, 44}; 45#endif 46 47typedef void (*LowMemoryHandler)(bool critical); 48 49class MemoryPressureHandler { 50 WTF_MAKE_FAST_ALLOCATED; 51public: 52 friend MemoryPressureHandler& memoryPressureHandler(); 53 54 void install(); 55 56 void setLowMemoryHandler(LowMemoryHandler handler) 57 { 58 ASSERT(!m_installed); 59 m_lowMemoryHandler = handler; 60 } 61 62 bool isUnderMemoryPressure() const { return m_underMemoryPressure; } 63 void setUnderMemoryPressure(bool b) { m_underMemoryPressure = b; } 64 65#if PLATFORM(IOS) 66 // FIXME: Can we share more of this with OpenSource? 67 void installMemoryReleaseBlock(void (^releaseMemoryBlock)(), bool clearPressureOnMemoryRelease = true); 68 void setReceivedMemoryPressure(MemoryPressureReason); 69 void clearMemoryPressure(); 70 bool shouldWaitForMemoryClearMessage(); 71 void respondToMemoryPressureIfNeeded(); 72#endif 73 74 class ReliefLogger { 75 public: 76 explicit ReliefLogger(const char *log) 77 : m_logString(log) 78 , m_initialMemory(s_loggingEnabled ? platformMemoryUsage() : 0) 79 { 80 } 81 82 ~ReliefLogger() 83 { 84 if (s_loggingEnabled) 85 platformLog(); 86 } 87 88 const char* logString() const { return m_logString; } 89 static void setLoggingEnabled(bool enabled) { s_loggingEnabled = enabled; } 90 static bool loggingEnabled() { return s_loggingEnabled; } 91 92 private: 93 size_t platformMemoryUsage(); 94 void platformLog(); 95 96 const char* m_logString; 97 size_t m_initialMemory; 98 99 static bool s_loggingEnabled; 100 }; 101 102 static void releaseMemory(bool critical); 103 104private: 105 static void releaseNoncriticalMemory(); 106 static void releaseCriticalMemory(); 107 108 void uninstall(); 109 110 void holdOff(unsigned); 111 112 MemoryPressureHandler(); 113 ~MemoryPressureHandler(); 114 115 void respondToMemoryPressure(bool critical); 116 static void platformReleaseMemory(bool critical); 117 118 bool m_installed; 119 time_t m_lastRespondTime; 120 LowMemoryHandler m_lowMemoryHandler; 121 122 std::atomic<bool> m_underMemoryPressure; 123 124#if PLATFORM(IOS) 125 uint32_t m_memoryPressureReason; 126 bool m_clearPressureOnMemoryRelease; 127 void (^m_releaseMemoryBlock)(); 128 CFRunLoopObserverRef m_observer; 129 Mutex m_observerMutex; 130#endif 131}; 132 133// Function to obtain the global memory pressure object. 134MemoryPressureHandler& memoryPressureHandler(); 135 136} // namespace WebCore 137 138#endif // MemoryPressureHandler_h 139