15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved. 25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be 35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file. 45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#ifndef BASE_MEMORY_DISCARDABLE_MEMORY_ASHMEM_ALLOCATOR_H_ 65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#define BASE_MEMORY_DISCARDABLE_MEMORY_ASHMEM_ALLOCATOR_H_ 75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <string> 95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/base_export.h" 115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/basictypes.h" 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/memory/scoped_ptr.h" 135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/memory/scoped_vector.h" 145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/synchronization/lock.h" 155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace base { 175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace internal { 185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass AshmemRegion; 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Internal class, whose instances are returned to the client of the allocator 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// (e.g. DiscardableMemoryAshmem), that mimicks the DiscardableMemory interface. 235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass BASE_EXPORT_PRIVATE DiscardableAshmemChunk { 245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ~DiscardableAshmemChunk(); 265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Returns whether the memory is still resident. 285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool Lock(); 295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void Unlock(); 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void* Memory() const; 335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu friend class AshmemRegion; 365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DiscardableAshmemChunk(AshmemRegion* ashmem_region, 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int fd, 395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void* address, 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size_t offset, 415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size_t size); 425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu AshmemRegion* const ashmem_region_; 445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const int fd_; 455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void* const address_; 465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const size_t offset_; 475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const size_t size_; 485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool locked_; 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DISALLOW_COPY_AND_ASSIGN(DiscardableAshmemChunk); 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Ashmem regions are backed by a file (descriptor) therefore they are a limited 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// resource. This allocator minimizes the problem by allocating large ashmem 555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// regions internally and returning smaller chunks to the client. 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Allocated chunks are systematically aligned on a page boundary therefore this 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// allocator should not be used for small allocations. 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass BASE_EXPORT_PRIVATE DiscardableMemoryAshmemAllocator { 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Note that |name| is only used for debugging/measurement purposes. 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // |ashmem_region_size| is the size that will be used to create the underlying 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // ashmem regions and is expected to be greater or equal than 32 MBytes. 635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DiscardableMemoryAshmemAllocator(const std::string& name, 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size_t ashmem_region_size); 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ~DiscardableMemoryAshmemAllocator(); 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Note that the allocator must outlive the returned DiscardableAshmemChunk 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // instance. 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<DiscardableAshmemChunk> Allocate(size_t size); 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Returns the size of the last ashmem region which was created. This is used 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // for testing only. 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size_t last_ashmem_region_size() const; 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu friend class AshmemRegion; 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void DeleteAshmemRegion_Locked(AshmemRegion* region); 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string name_; 825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const size_t ashmem_region_size_; 835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu mutable Lock lock_; 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size_t last_ashmem_region_size_; 855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ScopedVector<AshmemRegion> ashmem_regions_; 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryAshmemAllocator); 885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} // namespace internal 915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} // namespace base 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif // BASE_MEMORY_DISCARDABLE_MEMORY_ASHMEM_ALLOCATOR_H_ 94