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..12bd3db8021715171cf906be2a3914aa57cc0924 |
| --- /dev/null |
| +++ b/base/memory/discardable_memory_provider.h |
| @@ -0,0 +1,147 @@ |
| +// 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<base::DiscardableMemory*> { |
| + size_t operator()(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 unlocked |
| +// memory -- if the pressure is moderate -- or all unlocked 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 DiscardableMemoryProvider { |
|
willchan no longer on Chromium
2013/10/01 18:47:25
BASE_EXPORT_PRIVATE?
reveman
2013/10/09 22:40:24
Done.
|
| + public: |
| + // The bool here is just a placeholder. The MRU cache acts like a map, but we |
| + // only actually care about the keys. |
| + typedef HashingMRUCache<DiscardableMemory*, bool> AllocationMap; |
| + |
| + DiscardableMemoryProvider(); |
| + ~DiscardableMemoryProvider(); |
| + |
| + // 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); |
| + |
| + // Gets the maximum amount of discardable memory that may be allocated. |
| + size_t discardable_memory_limit() const; |
| + |
| + // Sets the amount of memory to reclaim when we're under moderate pressure. |
| + void SetBytesToReclaimUnderModeratePressure(size_t bytes); |
| + |
| + // Gets the amount of memory to reclaim when we're under moderate pressure. |
| + size_t bytes_to_reclaim_under_moderate_pressure() const; |
| + |
| + private: |
| + friend class base::DiscardableMemory; |
|
willchan no longer on Chromium
2013/10/01 18:47:25
Can you just move the necessary private member fun
reveman
2013/10/09 22:40:24
Done.
|
| + friend class base::DiscardableMemoryProviderTest; |
| + friend class Singleton<DiscardableMemoryProvider>; |
| + |
| + static DiscardableMemoryProvider* GetInstance(); |
| + |
| + // This can be called as a hint that the system is under memory pressure. |
| + static void NotifyMemoryPressure( |
| + MemoryPressureListener::MemoryPressureLevel pressure_level); |
| + |
| + // Sets the instance of DiscardableMemoryProvider to be returned by |
| + // GetInstance. This should only be used by tests. The ownership of the given |
| + // provider is retained by the caller. |
|
willchan no longer on Chromium
2013/10/01 18:47:25
You should note that this should be called prior t
reveman
2013/10/09 22:40:24
Done.
|
| + static void SetInstanceForTest(DiscardableMemoryProvider* provider); |
| + |
| + // Adds the given discardable memory to the provider's collection. If the |
| + // discardable has already been added, it is first unregistered and its |
| + // memory deallocated. |
| + void Register(DiscardableMemory* discardable); |
| + |
| + // Removes the given discardable memory from the provider's collection. |
| + void Unregister(DiscardableMemory* discardable); |
| + |
| + // Called by discardable memory instances to allow the provider to keep track |
| + // of the total amout of discardable memory allocated. |
| + void DidAllocate(size_t bytes); |
| + |
| + // Called by discardable memory instances to allow the provider to keep track |
| + // of the total amount of discardable memory allocated. |
| + void DidDeallocate(size_t bytes); |
| + |
| + // Called by discardable memory instances to allow the provider to maintain |
| + // its MRU cache. Returns false if the discardable has not been registered. |
| + bool DidAccess(DiscardableMemory* discardable); |
| + |
| + // Purges all discardable memory. |
| + void PurgeAll(); |
| + |
| + // Purges least recently used memory. |
| + void PurgeLRU(); |
| + |
| + // 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. |
| + // It's mutable because it must be accessed in a const function. |
| + mutable 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_ |