Index: base/memory/discardable_memory_provider.h |
diff --git a/base/memory/discardable_memory_provider.h b/base/memory/discardable_memory_provider.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..005cc1dfc86bcf876af727bf560e7c02f516f47d |
--- /dev/null |
+++ b/base/memory/discardable_memory_provider.h |
@@ -0,0 +1,151 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef BASE_MEMORY_DISCARDABLE_MEMORY_PROVIDER_H_ |
+#define BASE_MEMORY_DISCARDABLE_MEMORY_PROVIDER_H_ |
+ |
+#include "base/base_export.h" |
+#include "base/containers/hash_tables.h" |
+#include "base/containers/mru_cache.h" |
+#include "base/memory/memory_pressure_listener.h" |
+#include "base/synchronization/lock.h" |
+ |
+namespace base { |
+class DiscardableMemory; |
+} // namespace base |
+ |
+#if defined(COMPILER_GCC) |
+namespace BASE_HASH_NAMESPACE { |
+template <> |
+struct hash<const base::DiscardableMemory*> { |
+ size_t operator()(const base::DiscardableMemory* ptr) const { |
+ return hash<size_t>()(reinterpret_cast<size_t>(ptr)); |
+ } |
+}; |
+} // namespace BASE_HASH_NAMESPACE |
+#endif // COMPILER |
+ |
+namespace base { |
+namespace internal { |
+ |
+// The DiscardableMemoryProvider manages a collection of emulated |
+// DiscardableMemory instances. It is used on platforms that do not support |
+// discardable memory natively. It keeps track of all DiscardableMemory |
+// instances (in case they need to be purged), and the total amount of |
+// allocated memory (in case this forces a purge). |
+// |
+// When notified of memory pressure, the provider either purges the LRU |
+// memory -- if the pressure is moderate -- or all discardable memory |
+// if the pressure is critical. |
+// |
+// NB - this class is an implementation detail. It has been exposed for testing |
+// purposes. You should not need to use this class directly. |
+class BASE_EXPORT_PRIVATE DiscardableMemoryProvider { |
+ public: |
+ DiscardableMemoryProvider(); |
+ ~DiscardableMemoryProvider(); |
+ |
+ static DiscardableMemoryProvider* GetInstance(); |
+ |
+ // Sets the instance of DiscardableMemoryProvider to be returned by |
+ // GetInstance. This should only be used by tests and must be called |
+ // prior to GetInstance(). The ownership of the given provider is |
+ // retained by the caller. |
+ static void SetInstanceForTest(DiscardableMemoryProvider* provider); |
+ |
+ // The maximum number of bytes of discardable memory that may be allocated |
+ // before we assume moderate memory pressure. If this amount is zero, it is |
+ // interpreted as having no limit at all. |
+ void SetDiscardableMemoryLimit(size_t bytes); |
+ |
+ // Sets the amount of memory to reclaim when we're under moderate pressure. |
+ void SetBytesToReclaimUnderModeratePressure(size_t bytes); |
+ |
+ // Adds the given discardable memory to the provider's collection. |
+ void Register(const DiscardableMemory* discardable, size_t bytes); |
+ |
+ // Removes the given discardable memory from the provider's collection. |
+ void Unregister(const DiscardableMemory* discardable); |
+ |
+ // Returns NULL if an error occurred. Otherwise, returns the backing buffer |
+ // and sets |purged| to indicate whether or not the backing buffer has been |
+ // purged since last use. |
+ scoped_ptr<uint8, FreeDeleter> Acquire( |
+ const DiscardableMemory* discardable, bool* purged); |
+ |
+ // Release a previously acquired backing buffer. This gives the buffer back |
+ // to the provider where it can be purged if necessary. |
+ void Release(const DiscardableMemory* discardable, |
+ scoped_ptr<uint8, FreeDeleter> memory); |
+ |
+ // Purges all discardable memory. |
+ void PurgeAll(); |
+ |
+ // Returns true if discardable memory has been added to the provider's |
+ // collection. This should only be used by tests. |
+ bool IsRegisteredForTest(const DiscardableMemory* discardable) const; |
+ |
+ // Returns true if discardable memory can be purged. This should only |
+ // be used by tests. |
+ bool CanBePurgedForTest(const DiscardableMemory* discardable) const; |
+ |
+ // Returns total amount of allocated discardable memory. This should only |
+ // be used by tests. |
+ size_t GetBytesAllocatedForTest() const; |
+ |
+ private: |
+ struct Allocation { |
+ explicit Allocation(size_t bytes) |
+ : bytes(bytes), |
+ memory(NULL) { |
+ } |
+ |
+ size_t bytes; |
+ uint8* memory; |
+ }; |
+ typedef HashingMRUCache<const DiscardableMemory*, Allocation> AllocationMap; |
+ |
+ // This can be called as a hint that the system is under memory pressure. |
+ static void NotifyMemoryPressure( |
+ MemoryPressureListener::MemoryPressureLevel pressure_level); |
+ |
+ // Purges least recently used memory based on the value of |
+ // |bytes_to_reclaim_under_moderate_pressure_|. |
+ void Purge(); |
+ |
+ // Purges least recently used memory until usage is less or equal to |limit|. |
+ // Caller must acquire |lock_| prior to calling this function. |
+ void PurgeLRUWithLockAcquiredUntilUsageIsWithin(size_t limit); |
+ |
+ // Ensures that we don't allocate beyond our memory limit. |
+ // Caller must acquire |lock_| prior to calling this function. |
+ void EnforcePolicyWithLockAcquired(); |
+ |
+ // Needs to be held when accessing members. |
+ mutable Lock lock_; |
+ |
+ // A MRU cache of all allocated bits of discardable memory. Used for purging. |
+ AllocationMap allocations_; |
+ |
+ // The total amount of allocated discardable memory. |
+ size_t bytes_allocated_; |
+ |
+ // The maximum number of bytes of discardable memory that may be allocated |
+ // before we assume moderate memory pressure. |
+ size_t discardable_memory_limit_; |
+ |
+ // Under moderate memory pressure, we will purge this amount of memory. |
+ size_t bytes_to_reclaim_under_moderate_pressure_; |
+ |
+ // Allows us to be respond when the system reports that it is under memory |
+ // pressure. |
+ MemoryPressureListener memory_pressure_listener_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryProvider); |
+}; |
+ |
+} // namespace internal |
+} // namespace base |
+ |
+#endif // BASE_MEMORY_DISCARDABLE_MEMORY_PROVIDER_H_ |