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