Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / base / memory / discardable_memory_manager.h
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 #ifndef BASE_MEMORY_DISCARDABLE_MEMORY_MANAGER_H_
6 #define BASE_MEMORY_DISCARDABLE_MEMORY_MANAGER_H_
7
8 #include "base/base_export.h"
9 #include "base/containers/hash_tables.h"
10 #include "base/containers/mru_cache.h"
11 #include "base/memory/memory_pressure_listener.h"
12 #include "base/synchronization/lock.h"
13
14 namespace base {
15 class DiscardableMemory;
16 }  // namespace base
17
18 #if defined(COMPILER_GCC)
19 namespace BASE_HASH_NAMESPACE {
20 template <>
21 struct hash<const base::DiscardableMemory*> {
22   size_t operator()(const base::DiscardableMemory* ptr) const {
23     return hash<size_t>()(reinterpret_cast<size_t>(ptr));
24   }
25 };
26 }  // namespace BASE_HASH_NAMESPACE
27 #endif  // COMPILER
28
29 namespace base {
30 namespace internal {
31
32 // The DiscardableMemoryManager manages a collection of emulated
33 // DiscardableMemory instances. It is used on platforms that do not support
34 // discardable memory natively. It keeps track of all DiscardableMemory
35 // instances (in case they need to be purged), and the total amount of
36 // allocated memory (in case this forces a purge).
37 //
38 // When notified of memory pressure, the manager either purges the LRU
39 // memory -- if the pressure is moderate -- or all discardable memory
40 // if the pressure is critical.
41 //
42 // NB - this class is an implementation detail. It has been exposed for testing
43 // purposes. You should not need to use this class directly.
44 class BASE_EXPORT_PRIVATE DiscardableMemoryManager {
45  public:
46   DiscardableMemoryManager();
47   ~DiscardableMemoryManager();
48
49   // Call this to register memory pressure listener. Must be called on a
50   // thread with a MessageLoop current.
51   void RegisterMemoryPressureListener();
52
53   // Call this to unregister memory pressure listener.
54   void UnregisterMemoryPressureListener();
55
56   // The maximum number of bytes of discardable memory that may be allocated
57   // before we force a purge. If this amount is zero, it is interpreted as
58   // having no limit at all.
59   void SetDiscardableMemoryLimit(size_t bytes);
60
61   // Sets the amount of memory to keep when we're under moderate pressure.
62   void SetBytesToKeepUnderModeratePressure(size_t bytes);
63
64   // Adds the given discardable memory to the manager's collection.
65   void Register(const DiscardableMemory* discardable, size_t bytes);
66
67   // Removes the given discardable memory from the manager's collection.
68   void Unregister(const DiscardableMemory* discardable);
69
70   // Returns NULL if an error occurred. Otherwise, returns the backing buffer
71   // and sets |purged| to indicate whether or not the backing buffer has been
72   // purged since last use.
73   scoped_ptr<uint8, FreeDeleter> Acquire(
74       const DiscardableMemory* discardable, bool* purged);
75
76   // Release a previously acquired backing buffer. This gives the buffer back
77   // to the manager where it can be purged if necessary.
78   void Release(const DiscardableMemory* discardable,
79                scoped_ptr<uint8, FreeDeleter> memory);
80
81   // Purges all discardable memory.
82   void PurgeAll();
83
84   // Returns true if discardable memory has been added to the manager's
85   // collection. This should only be used by tests.
86   bool IsRegisteredForTest(const DiscardableMemory* discardable) const;
87
88   // Returns true if discardable memory can be purged. This should only
89   // be used by tests.
90   bool CanBePurgedForTest(const DiscardableMemory* discardable) const;
91
92   // Returns total amount of allocated discardable memory. This should only
93   // be used by tests.
94   size_t GetBytesAllocatedForTest() const;
95
96  private:
97   struct Allocation {
98    explicit Allocation(size_t bytes)
99        : bytes(bytes),
100          memory(NULL) {
101    }
102
103     size_t bytes;
104     uint8* memory;
105   };
106   typedef HashingMRUCache<const DiscardableMemory*, Allocation> AllocationMap;
107
108   // This can be called as a hint that the system is under memory pressure.
109   void OnMemoryPressure(
110       MemoryPressureListener::MemoryPressureLevel pressure_level);
111
112   // Purges until discardable memory usage is within
113   // |bytes_to_keep_under_moderate_pressure_|.
114   void Purge();
115
116   // Purges least recently used memory until usage is less or equal to |limit|.
117   // Caller must acquire |lock_| prior to calling this function.
118   void PurgeLRUWithLockAcquiredUntilUsageIsWithin(size_t limit);
119
120   // Ensures that we don't allocate beyond our memory limit.
121   // Caller must acquire |lock_| prior to calling this function.
122   void EnforcePolicyWithLockAcquired();
123
124   // Needs to be held when accessing members.
125   mutable Lock lock_;
126
127   // A MRU cache of all allocated bits of discardable memory. Used for purging.
128   AllocationMap allocations_;
129
130   // The total amount of allocated discardable memory.
131   size_t bytes_allocated_;
132
133   // The maximum number of bytes of discardable memory that may be allocated.
134   size_t discardable_memory_limit_;
135
136   // Under moderate memory pressure, we will purge until usage is within this
137   // limit.
138   size_t bytes_to_keep_under_moderate_pressure_;
139
140   // Allows us to be respond when the system reports that it is under memory
141   // pressure.
142   scoped_ptr<MemoryPressureListener> memory_pressure_listener_;
143
144   DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryManager);
145 };
146
147 }  // namespace internal
148 }  // namespace base
149
150 #endif  // BASE_MEMORY_DISCARDABLE_MEMORY_MANAGER_H_