• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 kEmulatedHardMemoryLimitExpirationTimeMs = 1000;
17 
18 struct SharedState {
SharedStatebase::__anon86984cde0111::SharedState19   SharedState()
20       : manager(kEmulatedMemoryLimit,
21                 kEmulatedSoftMemoryLimit,
22                 TimeDelta::FromMilliseconds(
23                     kEmulatedHardMemoryLimitExpirationTimeMs)) {}
24 
25   internal::DiscardableMemoryManager manager;
26 };
27 LazyInstance<SharedState>::Leaky g_shared_state = LAZY_INSTANCE_INITIALIZER;
28 
29 }  // namespace
30 
31 namespace internal {
32 
DiscardableMemoryEmulated(size_t bytes)33 DiscardableMemoryEmulated::DiscardableMemoryEmulated(size_t bytes)
34     : bytes_(bytes),
35       is_locked_(false) {
36   g_shared_state.Pointer()->manager.Register(this, bytes);
37 }
38 
~DiscardableMemoryEmulated()39 DiscardableMemoryEmulated::~DiscardableMemoryEmulated() {
40   if (is_locked_)
41     Unlock();
42   g_shared_state.Pointer()->manager.Unregister(this);
43 }
44 
45 // static
ReduceMemoryUsage()46 bool DiscardableMemoryEmulated::ReduceMemoryUsage() {
47   return g_shared_state.Pointer()->manager.ReduceMemoryUsage();
48 }
49 
50 // static
ReduceMemoryUsageUntilWithinLimit(size_t bytes)51 void DiscardableMemoryEmulated::ReduceMemoryUsageUntilWithinLimit(
52     size_t bytes) {
53   g_shared_state.Pointer()->manager.ReduceMemoryUsageUntilWithinLimit(bytes);
54 }
55 
56 // static
PurgeForTesting()57 void DiscardableMemoryEmulated::PurgeForTesting() {
58   g_shared_state.Pointer()->manager.PurgeAll();
59 }
60 
Initialize()61 bool DiscardableMemoryEmulated::Initialize() {
62   return Lock() != DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
63 }
64 
Lock()65 DiscardableMemoryLockStatus DiscardableMemoryEmulated::Lock() {
66   DCHECK(!is_locked_);
67 
68   bool purged = false;
69   if (!g_shared_state.Pointer()->manager.AcquireLock(this, &purged))
70     return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
71 
72   is_locked_ = true;
73   return purged ? DISCARDABLE_MEMORY_LOCK_STATUS_PURGED
74                 : DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS;
75 }
76 
Unlock()77 void DiscardableMemoryEmulated::Unlock() {
78   DCHECK(is_locked_);
79   g_shared_state.Pointer()->manager.ReleaseLock(this);
80   is_locked_ = false;
81 }
82 
Memory() const83 void* DiscardableMemoryEmulated::Memory() const {
84   DCHECK(is_locked_);
85   DCHECK(memory_);
86   return memory_.get();
87 }
88 
AllocateAndAcquireLock()89 bool DiscardableMemoryEmulated::AllocateAndAcquireLock() {
90   if (memory_)
91     return true;
92 
93   memory_.reset(new uint8[bytes_]);
94   return false;
95 }
96 
Purge()97 void DiscardableMemoryEmulated::Purge() {
98   memory_.reset();
99 }
100 
101 }  // namespace internal
102 }  // namespace base
103