Home | History | Annotate | Download | only in memory
      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/basictypes.h"
      8 #include "base/compiler_specific.h"
      9 #include "base/lazy_instance.h"
     10 #include "base/logging.h"
     11 #include "base/memory/discardable_memory_ashmem.h"
     12 #include "base/memory/discardable_memory_ashmem_allocator.h"
     13 #include "base/memory/discardable_memory_emulated.h"
     14 #include "base/memory/discardable_memory_malloc.h"
     15 #include "base/sys_info.h"
     16 
     17 namespace base {
     18 namespace {
     19 
     20 const 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).
     24 const size_t kAshmemMemoryLimit = 512 * 1024 * 1024;
     25 
     26 size_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::SysInfo::AmountOfPhysicalMemory() / 8;
     30 }
     31 
     32 // Holds the shared state used for allocations.
     33 struct SharedState {
     34   SharedState()
     35       : manager(kAshmemMemoryLimit, kAshmemMemoryLimit, TimeDelta::Max()),
     36         allocator(kAshmemAllocatorName,
     37                   GetOptimalAshmemRegionSizeForAllocator()) {}
     38 
     39   internal::DiscardableMemoryManager manager;
     40   internal::DiscardableMemoryAshmemAllocator allocator;
     41 };
     42 LazyInstance<SharedState>::Leaky g_shared_state = LAZY_INSTANCE_INITIALIZER;
     43 
     44 }  // namespace
     45 
     46 // static
     47 bool DiscardableMemory::ReduceMemoryUsage() {
     48   return internal::DiscardableMemoryEmulated::ReduceMemoryUsage();
     49 }
     50 
     51 // static
     52 void DiscardableMemory::GetSupportedTypes(
     53     std::vector<DiscardableMemoryType>* types) {
     54   const DiscardableMemoryType supported_types[] = {
     55     DISCARDABLE_MEMORY_TYPE_ASHMEM,
     56     DISCARDABLE_MEMORY_TYPE_EMULATED,
     57     DISCARDABLE_MEMORY_TYPE_MALLOC
     58   };
     59   types->assign(supported_types, supported_types + arraysize(supported_types));
     60 }
     61 
     62 // static
     63 scoped_ptr<DiscardableMemory> DiscardableMemory::CreateLockedMemoryWithType(
     64     DiscardableMemoryType type, size_t size) {
     65   switch (type) {
     66     case DISCARDABLE_MEMORY_TYPE_NONE:
     67     case DISCARDABLE_MEMORY_TYPE_MAC:
     68       return scoped_ptr<DiscardableMemory>();
     69     case DISCARDABLE_MEMORY_TYPE_ASHMEM: {
     70       SharedState* const shared_state = g_shared_state.Pointer();
     71       scoped_ptr<internal::DiscardableMemoryAshmem> memory(
     72           new internal::DiscardableMemoryAshmem(
     73               size, &shared_state->allocator, &shared_state->manager));
     74       if (!memory->Initialize())
     75         return scoped_ptr<DiscardableMemory>();
     76 
     77       return memory.PassAs<DiscardableMemory>();
     78     }
     79     case DISCARDABLE_MEMORY_TYPE_EMULATED: {
     80       scoped_ptr<internal::DiscardableMemoryEmulated> memory(
     81           new internal::DiscardableMemoryEmulated(size));
     82       if (!memory->Initialize())
     83         return scoped_ptr<DiscardableMemory>();
     84 
     85       return memory.PassAs<DiscardableMemory>();
     86     }
     87     case DISCARDABLE_MEMORY_TYPE_MALLOC: {
     88       scoped_ptr<internal::DiscardableMemoryMalloc> memory(
     89           new internal::DiscardableMemoryMalloc(size));
     90       if (!memory->Initialize())
     91         return scoped_ptr<DiscardableMemory>();
     92 
     93       return memory.PassAs<DiscardableMemory>();
     94     }
     95   }
     96 
     97   NOTREACHED();
     98   return scoped_ptr<DiscardableMemory>();
     99 }
    100 
    101 // static
    102 void DiscardableMemory::PurgeForTesting() {
    103   g_shared_state.Pointer()->manager.PurgeAll();
    104   internal::DiscardableMemoryEmulated::PurgeForTesting();
    105 }
    106 
    107 }  // namespace base
    108