1// Copyright 2014 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_ashmem.h"
6
7#include "base/memory/discardable_memory_ashmem_allocator.h"
8
9namespace base {
10namespace internal {
11
12DiscardableMemoryAshmem::DiscardableMemoryAshmem(
13    size_t bytes,
14    DiscardableMemoryAshmemAllocator* allocator,
15    DiscardableMemoryManager* manager)
16    : bytes_(bytes),
17      allocator_(allocator),
18      manager_(manager),
19      is_locked_(false) {
20  manager_->Register(this, bytes_);
21}
22
23DiscardableMemoryAshmem::~DiscardableMemoryAshmem() {
24  if (is_locked_)
25    Unlock();
26
27  manager_->Unregister(this);
28}
29
30bool DiscardableMemoryAshmem::Initialize() {
31  return Lock() != DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
32}
33
34DiscardableMemoryLockStatus DiscardableMemoryAshmem::Lock() {
35  DCHECK(!is_locked_);
36
37  bool purged = false;
38  if (!manager_->AcquireLock(this, &purged))
39    return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
40
41  is_locked_ = true;
42  return purged ? DISCARDABLE_MEMORY_LOCK_STATUS_PURGED
43                : DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS;
44}
45
46void DiscardableMemoryAshmem::Unlock() {
47  DCHECK(is_locked_);
48  manager_->ReleaseLock(this);
49  is_locked_ = false;
50}
51
52void* DiscardableMemoryAshmem::Memory() const {
53  DCHECK(is_locked_);
54  DCHECK(ashmem_chunk_);
55  return ashmem_chunk_->Memory();
56}
57
58bool DiscardableMemoryAshmem::AllocateAndAcquireLock() {
59  if (ashmem_chunk_)
60    return ashmem_chunk_->Lock();
61
62  ashmem_chunk_ = allocator_->Allocate(bytes_);
63  return false;
64}
65
66void DiscardableMemoryAshmem::ReleaseLock() {
67  ashmem_chunk_->Unlock();
68}
69
70void DiscardableMemoryAshmem::Purge() {
71  ashmem_chunk_.reset();
72}
73
74}  // namespace internal
75}  // namespace base
76