1// Copyright 2013 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_emulated.h"
6
7#include "base/lazy_instance.h"
8#include "base/memory/discardable_memory_provider.h"
9
10namespace base {
11
12namespace {
13
14base::LazyInstance<internal::DiscardableMemoryProvider>::Leaky g_provider =
15    LAZY_INSTANCE_INITIALIZER;
16
17}  // namespace
18
19namespace internal {
20
21DiscardableMemoryEmulated::DiscardableMemoryEmulated(size_t size)
22    : is_locked_(false) {
23  g_provider.Pointer()->Register(this, size);
24}
25
26DiscardableMemoryEmulated::~DiscardableMemoryEmulated() {
27  if (is_locked_)
28    Unlock();
29  g_provider.Pointer()->Unregister(this);
30}
31
32bool DiscardableMemoryEmulated::Initialize() {
33  return Lock() == DISCARDABLE_MEMORY_PURGED;
34}
35
36LockDiscardableMemoryStatus DiscardableMemoryEmulated::Lock() {
37  DCHECK(!is_locked_);
38
39  bool purged = false;
40  memory_ = g_provider.Pointer()->Acquire(this, &purged);
41  if (!memory_)
42    return DISCARDABLE_MEMORY_FAILED;
43
44  is_locked_ = true;
45  return purged ? DISCARDABLE_MEMORY_PURGED : DISCARDABLE_MEMORY_SUCCESS;
46}
47
48void DiscardableMemoryEmulated::Unlock() {
49  DCHECK(is_locked_);
50  g_provider.Pointer()->Release(this, memory_.Pass());
51  is_locked_ = false;
52}
53
54void* DiscardableMemoryEmulated::Memory() const {
55  DCHECK(memory_);
56  return memory_.get();
57}
58
59// static
60void DiscardableMemoryEmulated::PurgeForTesting() {
61  g_provider.Pointer()->PurgeAll();
62}
63
64}  // namespace internal
65}  // namespace base
66