Chromium Code Reviews| 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..e7cf6d87c177d5ad674970ca6122ec31be703d69 |
| --- /dev/null |
| +++ b/base/memory/discardable_memory_provider.h |
| @@ -0,0 +1,162 @@ |
| +// 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/memory/singleton.h" |
| +#include "base/synchronization/lock.h" |
| + |
| +namespace base { |
| +class DiscardableMemory; |
| +class DiscardableMemoryProviderTest; |
| +} // 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); |
| + |
| + // Acquire the backing buffer for the given discardable memory. |purged| |
| + // is set to true if the backing has been purged since last use. Returns |
| + // NULL if an error occurred or discardable memory limit has been reached. |
| + 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 it 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); |
|
willchan no longer on Chromium
2013/10/17 02:06:13
Make these test functions const if they don't muta
reveman
2013/10/19 21:17:04
Done.
|
| + |
| + // Returns true if discardable memory can be purged. This should only |
| + // be used by tests. |
| + bool CanBePurgedForTest(const DiscardableMemory* discardable); |
| + |
| + // Returns total amount of allocated discardable memory. This should only |
| + // be used by tests. |
| + size_t GetBytesAllocatedForTest(); |
| + |
| + private: |
| + friend class Singleton<DiscardableMemoryProvider>; |
| + |
| + struct Allocation { |
| + Allocation(size_t bytes) |
|
willchan no longer on Chromium
2013/10/17 02:06:13
explicit
reveman
2013/10/19 21:17:04
Done.
|
| + : 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 until usage is below |limit|. |
| + // Caller must acquire |allocations_lock_| and |bytes_allocated_lock_| |
| + // prior to calling this function. |
| + void PurgeLRU(size_t limit); |
| + |
| + // Purges least recently used memory based on the value of |
| + // |bytes_to_reclaim_under_moderate_pressure_|. |
| + void Purge(); |
| + |
| + // Ensures that we don't allocate beyond our memory limit. |
| + void EnforcePolicy(); |
| + |
| + // 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_; |
| + |
| + // Used to avoid reentry into EnforcePolicy. |
| + bool enforcing_policy_; |
| + |
| + // Needs to be held when accessing |allocations_|. |
| + Lock allocations_lock_; |
| + |
| + // Needs to be held when accessing |bytes_allocated_| or the two limits |
| + // above. |
| + Lock bytes_allocated_lock_; |
| + |
| + // 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_ |