discardable_memory_android.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright (c) 2013 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. 4 5#include "base/memory/discardable_memory.h" 6 7#include "base/android/sys_utils.h" 8#include "base/basictypes.h" 9#include "base/compiler_specific.h" 10#include "base/lazy_instance.h" 11#include "base/logging.h" 12#include "base/memory/discardable_memory_ashmem.h" 13#include "base/memory/discardable_memory_ashmem_allocator.h" 14#include "base/memory/discardable_memory_emulated.h" 15#include "base/memory/discardable_memory_malloc.h" 16 17namespace base { 18namespace { 19 20const char kAshmemAllocatorName[] = "DiscardableMemoryAshmemAllocator"; 21 22// For Ashmem, have the DiscardableMemoryManager trigger userspace eviction 23// when address space usage gets too high (e.g. 512 MBytes). 24const size_t kAshmemMemoryLimit = 512 * 1024 * 1024; 25 26size_t GetOptimalAshmemRegionSizeForAllocator() { 27 // Note that this may do some I/O (without hitting the disk though) so it 28 // should not be called on the critical path. 29 return base::android::SysUtils::AmountOfPhysicalMemoryKB() * 1024 / 8; 30} 31 32// Holds the shared state used for allocations. 33struct SharedState { 34 SharedState() 35 : manager(kAshmemMemoryLimit, kAshmemMemoryLimit), 36 allocator(kAshmemAllocatorName, 37 GetOptimalAshmemRegionSizeForAllocator()) {} 38 39 internal::DiscardableMemoryManager manager; 40 internal::DiscardableMemoryAshmemAllocator allocator; 41}; 42LazyInstance<SharedState>::Leaky g_shared_state = LAZY_INSTANCE_INITIALIZER; 43 44} // namespace 45 46// static 47void DiscardableMemory::RegisterMemoryPressureListeners() { 48 internal::DiscardableMemoryEmulated::RegisterMemoryPressureListeners(); 49} 50 51// static 52void DiscardableMemory::UnregisterMemoryPressureListeners() { 53 internal::DiscardableMemoryEmulated::UnregisterMemoryPressureListeners(); 54} 55 56// static 57void DiscardableMemory::GetSupportedTypes( 58 std::vector<DiscardableMemoryType>* types) { 59 const DiscardableMemoryType supported_types[] = { 60 DISCARDABLE_MEMORY_TYPE_ASHMEM, 61 DISCARDABLE_MEMORY_TYPE_EMULATED, 62 DISCARDABLE_MEMORY_TYPE_MALLOC 63 }; 64 types->assign(supported_types, supported_types + arraysize(supported_types)); 65} 66 67// static 68scoped_ptr<DiscardableMemory> DiscardableMemory::CreateLockedMemoryWithType( 69 DiscardableMemoryType type, size_t size) { 70 switch (type) { 71 case DISCARDABLE_MEMORY_TYPE_NONE: 72 case DISCARDABLE_MEMORY_TYPE_MAC: 73 return scoped_ptr<DiscardableMemory>(); 74 case DISCARDABLE_MEMORY_TYPE_ASHMEM: { 75 SharedState* const shared_state = g_shared_state.Pointer(); 76 scoped_ptr<internal::DiscardableMemoryAshmem> memory( 77 new internal::DiscardableMemoryAshmem( 78 size, &shared_state->allocator, &shared_state->manager)); 79 if (!memory->Initialize()) 80 return scoped_ptr<DiscardableMemory>(); 81 82 return memory.PassAs<DiscardableMemory>(); 83 } 84 case DISCARDABLE_MEMORY_TYPE_EMULATED: { 85 scoped_ptr<internal::DiscardableMemoryEmulated> memory( 86 new internal::DiscardableMemoryEmulated(size)); 87 if (!memory->Initialize()) 88 return scoped_ptr<DiscardableMemory>(); 89 90 return memory.PassAs<DiscardableMemory>(); 91 } 92 case DISCARDABLE_MEMORY_TYPE_MALLOC: { 93 scoped_ptr<internal::DiscardableMemoryMalloc> memory( 94 new internal::DiscardableMemoryMalloc(size)); 95 if (!memory->Initialize()) 96 return scoped_ptr<DiscardableMemory>(); 97 98 return memory.PassAs<DiscardableMemory>(); 99 } 100 } 101 102 NOTREACHED(); 103 return scoped_ptr<DiscardableMemory>(); 104} 105 106// static 107void DiscardableMemory::PurgeForTesting() { 108 g_shared_state.Pointer()->manager.PurgeAll(); 109 internal::DiscardableMemoryEmulated::PurgeForTesting(); 110} 111 112} // namespace base 113