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#include "base/memory/discardable_memory_ashmem.h"
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/memory/discardable_memory_ashmem_allocator.h"
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace base {
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace internal {
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuDiscardableMemoryAshmem::DiscardableMemoryAshmem(
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    size_t bytes,
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DiscardableMemoryAshmemAllocator* allocator,
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DiscardableMemoryManager* manager)
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    : bytes_(bytes),
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      allocator_(allocator),
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      manager_(manager),
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      is_locked_(false) {
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  manager_->Register(this, bytes_);
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuDiscardableMemoryAshmem::~DiscardableMemoryAshmem() {
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (is_locked_)
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Unlock();
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  manager_->Unregister(this);
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool DiscardableMemoryAshmem::Initialize() {
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return Lock() != DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuDiscardableMemoryLockStatus DiscardableMemoryAshmem::Lock() {
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!is_locked_);
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool purged = false;
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!manager_->AcquireLock(this, &purged))
395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  is_locked_ = true;
425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return purged ? DISCARDABLE_MEMORY_LOCK_STATUS_PURGED
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                : DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS;
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DiscardableMemoryAshmem::Unlock() {
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(is_locked_);
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  manager_->ReleaseLock(this);
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  is_locked_ = false;
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid* DiscardableMemoryAshmem::Memory() const {
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(is_locked_);
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK(ashmem_chunk_);
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return ashmem_chunk_->Memory();
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool DiscardableMemoryAshmem::AllocateAndAcquireLock() {
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (ashmem_chunk_)
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return ashmem_chunk_->Lock();
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ashmem_chunk_ = allocator_->Allocate(bytes_);
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return false;
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DiscardableMemoryAshmem::ReleaseLock() {
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ashmem_chunk_->Unlock();
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DiscardableMemoryAshmem::Purge() {
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ashmem_chunk_.reset();
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace internal
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace base
76