summaryrefslogtreecommitdiffstats
path: root/base/memory/discardable_memory_allocator_android.cc
diff options
context:
space:
mode:
authorpliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-25 18:24:46 +0000
committerpliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-25 18:24:46 +0000
commit73786be789262f72114030ccba586d898184a1ba (patch)
tree0394c9d8d3eb09d49ede314b742120f7ee470f32 /base/memory/discardable_memory_allocator_android.cc
parentad65a3ee540552ecca50ebbf9382f1a4c718d383 (diff)
downloadchromium_src-73786be789262f72114030ccba586d898184a1ba.zip
chromium_src-73786be789262f72114030ccba586d898184a1ba.tar.gz
chromium_src-73786be789262f72114030ccba586d898184a1ba.tar.bz2
Make size of ashmem regions based on device's physical memory.
Ashmem regions created by the ashmem allocator used to be fixed to 32 MBytes which can be a little small for high-end devices. This change makes the allocator create ashmem regions of those sizes: - 64 MBytes for 512 MBytes devices - 128 MBytes for 1 GByte devices - 256 MBytes for 2 GBytes... This also adds an error code path in case ashmem creation fails which may happen if the address space is too fragmented. In this case the allocator repetitively retries by dividing the ashmem region size by 2 until the ashmem region reaches 32 MBytes (which is the minimum). TBR=bulach@chromium.org Review URL: https://codereview.chromium.org/119923002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@242497 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/memory/discardable_memory_allocator_android.cc')
-rw-r--r--base/memory/discardable_memory_allocator_android.cc34
1 files changed, 23 insertions, 11 deletions
diff --git a/base/memory/discardable_memory_allocator_android.cc b/base/memory/discardable_memory_allocator_android.cc
index 5e10817..a0a3aff 100644
--- a/base/memory/discardable_memory_allocator_android.cc
+++ b/base/memory/discardable_memory_allocator_android.cc
@@ -44,6 +44,8 @@ namespace {
// issues.
const size_t kMaxChunkFragmentationBytes = 4096 - 1;
+const size_t kMinAshmemRegionSize = 32 * 1024 * 1024;
+
} // namespace
namespace internal {
@@ -104,6 +106,7 @@ class DiscardableMemoryAllocator::AshmemRegion {
size_t size,
const std::string& name,
DiscardableMemoryAllocator* allocator) {
+ DCHECK_EQ(size, internal::AlignToNextPage(size));
int fd;
void* base;
if (!internal::CreateAshmemRegion(name.c_str(), size, &fd, &base))
@@ -364,8 +367,12 @@ DiscardableMemoryAllocator::DiscardableAshmemChunk::~DiscardableAshmemChunk() {
ashmem_region_->OnChunkDeletion(address_, size_);
}
-DiscardableMemoryAllocator::DiscardableMemoryAllocator(const std::string& name)
- : name_(name) {
+DiscardableMemoryAllocator::DiscardableMemoryAllocator(
+ const std::string& name,
+ size_t ashmem_region_size)
+ : name_(name),
+ ashmem_region_size_(std::max(kMinAshmemRegionSize, ashmem_region_size)) {
+ DCHECK_GE(ashmem_region_size_, kMinAshmemRegionSize);
}
DiscardableMemoryAllocator::~DiscardableMemoryAllocator() {
@@ -389,16 +396,21 @@ scoped_ptr<DiscardableMemory> DiscardableMemoryAllocator::Allocate(
if (memory)
return memory.Pass();
}
- scoped_ptr<AshmemRegion> new_region(
- AshmemRegion::Create(
- std::max(static_cast<size_t>(kMinAshmemRegionSize), aligned_size),
- name_.c_str(), this));
- if (!new_region) {
- // TODO(pliard): consider adding an histogram to see how often this happens.
- return scoped_ptr<DiscardableMemory>();
+ // The creation of the (large) ashmem region might fail if the address space
+ // is too fragmented. In case creation fails the allocator retries by
+ // repetitively dividing the size by 2.
+ const size_t min_region_size = std::max(kMinAshmemRegionSize, aligned_size);
+ for (size_t region_size = std::max(ashmem_region_size_, aligned_size);
+ region_size >= min_region_size; region_size /= 2) {
+ scoped_ptr<AshmemRegion> new_region(
+ AshmemRegion::Create(region_size, name_.c_str(), this));
+ if (!new_region)
+ continue;
+ ashmem_regions_.push_back(new_region.release());
+ return ashmem_regions_.back()->Allocate_Locked(size, aligned_size);
}
- ashmem_regions_.push_back(new_region.release());
- return ashmem_regions_.back()->Allocate_Locked(size, aligned_size);
+ // TODO(pliard): consider adding an histogram to see how often this happens.
+ return scoped_ptr<DiscardableMemory>();
}
void DiscardableMemoryAllocator::DeleteAshmemRegion_Locked(