2 * Copyright 2013 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "SkPurgeableMemoryBlock.h"
10 #include "android/ashmem.h"
14 bool SkPurgeableMemoryBlock::IsSupported() {
19 bool SkPurgeableMemoryBlock::PlatformSupportsPurgingAllUnpinnedBlocks() {
23 bool SkPurgeableMemoryBlock::PurgeAllUnpinnedBlocks() {
27 bool SkPurgeableMemoryBlock::purge() {
30 ashmem_purge_all_caches(fFD);
38 // ashmem likes lengths on page boundaries.
39 static size_t round_to_page_size(size_t size) {
40 const size_t mask = getpagesize() - 1;
41 size_t newSize = (size + mask) & ~mask;
45 SkPurgeableMemoryBlock::SkPurgeableMemoryBlock(size_t size)
47 , fSize(round_to_page_size(size))
52 SkPurgeableMemoryBlock::~SkPurgeableMemoryBlock() {
59 void* SkPurgeableMemoryBlock::pin(SkPurgeableMemoryBlock::PinResult* pinResult) {
62 int fd = ashmem_create_region(NULL, fSize);
64 SkDebugf("ashmem_create_region failed\n");
68 int err = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
70 SkDebugf("ashmem_set_prot_region failed\n");
75 void* addr = mmap(NULL, fSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
76 if (-1 == (long) addr) {
77 SkDebugf("mmap failed\n");
83 (void) ashmem_pin_region(fd, 0, 0);
84 *pinResult = kUninitialized_PinResult;
87 int pin = ashmem_pin_region(fFD, 0, 0);
88 if (ASHMEM_NOT_PURGED == pin) {
90 *pinResult = kRetained_PinResult;
91 } else if (ASHMEM_WAS_PURGED == pin) {
93 *pinResult = kUninitialized_PinResult;
105 void SkPurgeableMemoryBlock::unpin() {
107 ashmem_unpin_region(fFD, 0, 0);