| 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..f6036802fc499913476f6027a543bbb84324915a
|
| --- /dev/null
|
| +++ b/base/memory/discardable_memory_provider.h
|
| @@ -0,0 +1,139 @@
|
| +// 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;
|
| +} // 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 {
|
| +
|
| +// The DiscardableMemoryProvider 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).
|
| +//
|
| +// 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 {
|
| + public:
|
| + DiscardableMemoryProvider();
|
| + virtual ~DiscardableMemoryProvider();
|
| +
|
| + // 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;
|
| +
|
| + // 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 DiscardableMemory;
|
| + friend class 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.
|
| + 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 base
|
| +
|
| +#endif // BASE_MEMORY_DISCARDABLE_MEMORY_PROVIDER_H_
|
|
|