Upstream version 9.37.195.0
[platform/framework/web/crosswalk.git] / src / base / memory / discardable_memory_emulated.cc
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_manager.h"
9
10 namespace base {
11 namespace {
12
13 // This is admittedly pretty magical.
14 const size_t kEmulatedMemoryLimit = 512 * 1024 * 1024;
15 const size_t kEmulatedSoftMemoryLimit = 32 * 1024 * 1024;
16 const size_t kEmulatedBytesToKeepUnderModeratePressure = 4 * 1024 * 1024;
17 const size_t kEmulatedHardMemoryLimitExpirationTimeMs = 1000;
18
19 struct SharedState {
20   SharedState()
21       : manager(kEmulatedMemoryLimit,
22                 kEmulatedSoftMemoryLimit,
23                 kEmulatedBytesToKeepUnderModeratePressure,
24                 TimeDelta::FromMilliseconds(
25                     kEmulatedHardMemoryLimitExpirationTimeMs)) {}
26
27   internal::DiscardableMemoryManager manager;
28 };
29 LazyInstance<SharedState>::Leaky g_shared_state = LAZY_INSTANCE_INITIALIZER;
30
31 }  // namespace
32
33 namespace internal {
34
35 DiscardableMemoryEmulated::DiscardableMemoryEmulated(size_t bytes)
36     : bytes_(bytes),
37       is_locked_(false) {
38   g_shared_state.Pointer()->manager.Register(this, bytes);
39 }
40
41 DiscardableMemoryEmulated::~DiscardableMemoryEmulated() {
42   if (is_locked_)
43     Unlock();
44   g_shared_state.Pointer()->manager.Unregister(this);
45 }
46
47 // static
48 void DiscardableMemoryEmulated::RegisterMemoryPressureListeners() {
49   g_shared_state.Pointer()->manager.RegisterMemoryPressureListener();
50 }
51
52 // static
53 void DiscardableMemoryEmulated::UnregisterMemoryPressureListeners() {
54   g_shared_state.Pointer()->manager.UnregisterMemoryPressureListener();
55 }
56
57 // static
58 bool DiscardableMemoryEmulated::ReduceMemoryUsage() {
59   return g_shared_state.Pointer()->manager.ReduceMemoryUsage();
60 }
61
62 // static
63 void DiscardableMemoryEmulated::PurgeForTesting() {
64   g_shared_state.Pointer()->manager.PurgeAll();
65 }
66
67 bool DiscardableMemoryEmulated::Initialize() {
68   return Lock() != DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
69 }
70
71 DiscardableMemoryLockStatus DiscardableMemoryEmulated::Lock() {
72   DCHECK(!is_locked_);
73
74   bool purged = false;
75   if (!g_shared_state.Pointer()->manager.AcquireLock(this, &purged))
76     return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
77
78   is_locked_ = true;
79   return purged ? DISCARDABLE_MEMORY_LOCK_STATUS_PURGED
80                 : DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS;
81 }
82
83 void DiscardableMemoryEmulated::Unlock() {
84   DCHECK(is_locked_);
85   g_shared_state.Pointer()->manager.ReleaseLock(this);
86   is_locked_ = false;
87 }
88
89 void* DiscardableMemoryEmulated::Memory() const {
90   DCHECK(is_locked_);
91   DCHECK(memory_);
92   return memory_.get();
93 }
94
95 bool DiscardableMemoryEmulated::AllocateAndAcquireLock() {
96   if (memory_)
97     return true;
98
99   memory_.reset(new uint8[bytes_]);
100   return false;
101 }
102
103 void DiscardableMemoryEmulated::Purge() {
104   memory_.reset();
105 }
106
107 }  // namespace internal
108 }  // namespace base