summaryrefslogtreecommitdiffstats
path: root/base/memory
diff options
context:
space:
mode:
authorreveman <reveman@chromium.org>2015-03-11 20:27:04 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-12 03:27:29 +0000
commit2092eaa97b727840b932824dd0f7582a4868a00b (patch)
treecf5f4e32cc269acf9c8ea6a68a0772f1d2e2e32f /base/memory
parent77f0e1aa1344e35343d6932415f2b3c0f381ef6f (diff)
downloadchromium_src-2092eaa97b727840b932824dd0f7582a4868a00b.zip
chromium_src-2092eaa97b727840b932824dd0f7582a4868a00b.tar.gz
chromium_src-2092eaa97b727840b932824dd0f7582a4868a00b.tar.bz2
base: Remove unused DiscardableMemoryManager class.
BUG=442945,422953 Review URL: https://codereview.chromium.org/999903002 Cr-Commit-Position: refs/heads/master@{#320224}
Diffstat (limited to 'base/memory')
-rw-r--r--base/memory/BUILD.gn4
-rw-r--r--base/memory/discardable_memory_manager.cc218
-rw-r--r--base/memory/discardable_memory_manager.h166
-rw-r--r--base/memory/discardable_memory_manager_unittest.cc490
4 files changed, 0 insertions, 878 deletions
diff --git a/base/memory/BUILD.gn b/base/memory/BUILD.gn
index 535202a..5d016ff 100644
--- a/base/memory/BUILD.gn
+++ b/base/memory/BUILD.gn
@@ -11,8 +11,6 @@ source_set("memory") {
"discardable_memory_android.cc",
"discardable_memory_linux.cc",
"discardable_memory_mac.cc",
- "discardable_memory_manager.cc",
- "discardable_memory_manager.h",
"discardable_memory_shmem.cc",
"discardable_memory_shmem.h",
"discardable_memory_shmem_allocator.cc",
@@ -48,8 +46,6 @@ source_set("memory") {
sources -= [
"discardable_memory.cc",
"discardable_memory.h",
- "discardable_memory_manager.cc",
- "discardable_memory_manager.h",
"discardable_memory_shmem.cc",
"discardable_memory_shmem.h",
"discardable_memory_shmem_allocator.cc",
diff --git a/base/memory/discardable_memory_manager.cc b/base/memory/discardable_memory_manager.cc
deleted file mode 100644
index cbbdb47..0000000
--- a/base/memory/discardable_memory_manager.cc
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2014 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.
-
-#include "base/memory/discardable_memory_manager.h"
-
-#include "base/bind.h"
-#include "base/containers/adapters.h"
-#include "base/containers/hash_tables.h"
-#include "base/containers/mru_cache.h"
-#include "base/debug/crash_logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/synchronization/lock.h"
-#include "base/trace_event/trace_event.h"
-
-namespace base {
-namespace internal {
-
-DiscardableMemoryManager::DiscardableMemoryManager(
- size_t memory_limit,
- size_t soft_memory_limit,
- TimeDelta hard_memory_limit_expiration_time)
- : allocations_(AllocationMap::NO_AUTO_EVICT),
- bytes_allocated_(0u),
- memory_limit_(memory_limit),
- soft_memory_limit_(soft_memory_limit),
- hard_memory_limit_expiration_time_(hard_memory_limit_expiration_time) {
- BytesAllocatedChanged(bytes_allocated_);
-}
-
-DiscardableMemoryManager::~DiscardableMemoryManager() {
- DCHECK(allocations_.empty());
- DCHECK_EQ(0u, bytes_allocated_);
-}
-
-void DiscardableMemoryManager::SetMemoryLimit(size_t bytes) {
- AutoLock lock(lock_);
- memory_limit_ = bytes;
- PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
- Now(), memory_limit_);
-}
-
-void DiscardableMemoryManager::SetSoftMemoryLimit(size_t bytes) {
- AutoLock lock(lock_);
- soft_memory_limit_ = bytes;
-}
-
-void DiscardableMemoryManager::SetHardMemoryLimitExpirationTime(
- TimeDelta hard_memory_limit_expiration_time) {
- AutoLock lock(lock_);
- hard_memory_limit_expiration_time_ = hard_memory_limit_expiration_time;
-}
-
-bool DiscardableMemoryManager::ReduceMemoryUsage() {
- return PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit();
-}
-
-void DiscardableMemoryManager::ReduceMemoryUsageUntilWithinLimit(size_t bytes) {
- AutoLock lock(lock_);
- PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(Now(),
- bytes);
-}
-
-void DiscardableMemoryManager::Register(Allocation* allocation, size_t bytes) {
- AutoLock lock(lock_);
- DCHECK(allocations_.Peek(allocation) == allocations_.end());
- allocations_.Put(allocation, AllocationInfo(bytes));
-}
-
-void DiscardableMemoryManager::Unregister(Allocation* allocation) {
- AutoLock lock(lock_);
- AllocationMap::iterator it = allocations_.Peek(allocation);
- DCHECK(it != allocations_.end());
- const AllocationInfo& info = it->second;
-
- if (info.purgable) {
- size_t bytes_purgable = info.bytes;
- DCHECK_LE(bytes_purgable, bytes_allocated_);
- bytes_allocated_ -= bytes_purgable;
- BytesAllocatedChanged(bytes_allocated_);
- }
- allocations_.Erase(it);
-}
-
-bool DiscardableMemoryManager::AcquireLock(Allocation* allocation,
- bool* purged) {
- AutoLock lock(lock_);
- // Note: |allocations_| is an MRU cache, and use of |Get| here updates that
- // cache.
- AllocationMap::iterator it = allocations_.Get(allocation);
- DCHECK(it != allocations_.end());
- AllocationInfo* info = &it->second;
-
- if (!info->bytes)
- return false;
-
- TimeTicks now = Now();
- size_t bytes_required = info->purgable ? 0u : info->bytes;
-
- if (memory_limit_) {
- size_t limit = 0;
- if (bytes_required < memory_limit_)
- limit = memory_limit_ - bytes_required;
-
- PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(now,
- limit);
- }
-
- // Check for overflow.
- if (std::numeric_limits<size_t>::max() - bytes_required < bytes_allocated_)
- return false;
-
- *purged = !allocation->AllocateAndAcquireLock();
- info->purgable = false;
- info->last_usage = now;
- if (bytes_required) {
- bytes_allocated_ += bytes_required;
- BytesAllocatedChanged(bytes_allocated_);
- }
- return true;
-}
-
-void DiscardableMemoryManager::ReleaseLock(Allocation* allocation) {
- AutoLock lock(lock_);
- // Note: |allocations_| is an MRU cache, and use of |Get| here updates that
- // cache.
- AllocationMap::iterator it = allocations_.Get(allocation);
- DCHECK(it != allocations_.end());
- AllocationInfo* info = &it->second;
-
- TimeTicks now = Now();
- allocation->ReleaseLock();
- info->purgable = true;
- info->last_usage = now;
-
- PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
- now, memory_limit_);
-}
-
-void DiscardableMemoryManager::PurgeAll() {
- AutoLock lock(lock_);
- PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(Now(), 0);
-}
-
-bool DiscardableMemoryManager::IsRegisteredForTest(
- Allocation* allocation) const {
- AutoLock lock(lock_);
- AllocationMap::const_iterator it = allocations_.Peek(allocation);
- return it != allocations_.end();
-}
-
-bool DiscardableMemoryManager::CanBePurgedForTest(
- Allocation* allocation) const {
- AutoLock lock(lock_);
- AllocationMap::const_iterator it = allocations_.Peek(allocation);
- return it != allocations_.end() && it->second.purgable;
-}
-
-size_t DiscardableMemoryManager::GetBytesAllocatedForTest() const {
- AutoLock lock(lock_);
- return bytes_allocated_;
-}
-
-bool DiscardableMemoryManager::
- PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit() {
- AutoLock lock(lock_);
-
- PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
- Now() - hard_memory_limit_expiration_time_, soft_memory_limit_);
-
- return bytes_allocated_ <= soft_memory_limit_;
-}
-
-void DiscardableMemoryManager::
- PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
- TimeTicks timestamp,
- size_t limit) {
- lock_.AssertAcquired();
-
- size_t bytes_allocated_before_purging = bytes_allocated_;
- for (auto& entry : base::Reversed(allocations_)) {
- Allocation* allocation = entry.first;
- AllocationInfo* info = &entry.second;
-
- if (bytes_allocated_ <= limit)
- break;
-
- bool purgable = info->purgable && info->last_usage <= timestamp;
- if (!purgable)
- continue;
-
- size_t bytes_purgable = info->bytes;
- DCHECK_LE(bytes_purgable, bytes_allocated_);
- bytes_allocated_ -= bytes_purgable;
- info->purgable = false;
- allocation->Purge();
- }
-
- if (bytes_allocated_ != bytes_allocated_before_purging)
- BytesAllocatedChanged(bytes_allocated_);
-}
-
-void DiscardableMemoryManager::BytesAllocatedChanged(
- size_t new_bytes_allocated) const {
- TRACE_COUNTER_ID1(
- "base", "DiscardableMemoryUsage", this, new_bytes_allocated);
-
- static const char kDiscardableMemoryUsageKey[] = "dm-usage";
- base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey,
- Uint64ToString(new_bytes_allocated));
-}
-
-TimeTicks DiscardableMemoryManager::Now() const {
- return TimeTicks::Now();
-}
-
-} // namespace internal
-} // namespace base
diff --git a/base/memory/discardable_memory_manager.h b/base/memory/discardable_memory_manager.h
deleted file mode 100644
index 43737f8..0000000
--- a/base/memory/discardable_memory_manager.h
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2014 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_MANAGER_H_
-#define BASE_MEMORY_DISCARDABLE_MEMORY_MANAGER_H_
-
-#include "base/base_export.h"
-#include "base/containers/hash_tables.h"
-#include "base/containers/mru_cache.h"
-#include "base/synchronization/lock.h"
-#include "base/time/time.h"
-
-namespace base {
-namespace internal {
-
-// This interface is used by the DiscardableMemoryManager class to provide some
-// level of userspace control over discardable memory allocations.
-class DiscardableMemoryManagerAllocation {
- public:
- // Allocate and acquire a lock that prevents the allocation from being purged
- // by the system. Returns true if memory was previously allocated and is still
- // resident.
- virtual bool AllocateAndAcquireLock() = 0;
-
- // Release a previously acquired lock on the allocation so that it can be
- // purged by the system.
- virtual void ReleaseLock() = 0;
-
- // Explicitly purge this allocation. It is illegal to call this while a lock
- // is acquired on the allocation.
- virtual void Purge() = 0;
-
- protected:
- virtual ~DiscardableMemoryManagerAllocation() {}
-};
-
-} // namespace internal
-} // namespace base
-
-namespace base {
-namespace internal {
-
-// The DiscardableMemoryManager manages a collection of
-// DiscardableMemoryManagerAllocation instances. It is used on platforms that
-// need some level of userspace control over discardable memory. It keeps track
-// of all allocation instances (in case they need to be purged), and the total
-// amount of allocated memory (in case this forces a purge). When memory usage
-// reaches the limit, the manager purges the LRU memory.
-class BASE_EXPORT_PRIVATE DiscardableMemoryManager {
- public:
- typedef DiscardableMemoryManagerAllocation Allocation;
-
- DiscardableMemoryManager(size_t memory_limit,
- size_t soft_memory_limit,
- TimeDelta hard_memory_limit_expiration_time);
- virtual ~DiscardableMemoryManager();
-
- // The maximum number of bytes of memory that may be allocated before we force
- // a purge.
- void SetMemoryLimit(size_t bytes);
-
- // The number of bytes of memory that may be allocated but unused for the hard
- // limit expiration time without getting purged.
- void SetSoftMemoryLimit(size_t bytes);
-
- // Sets the memory usage cutoff time for hard memory limit.
- void SetHardMemoryLimitExpirationTime(
- TimeDelta hard_memory_limit_expiration_time);
-
- // This will attempt to reduce memory footprint until within soft memory
- // limit. Returns true if there's no need to call this again until allocations
- // have been used.
- bool ReduceMemoryUsage();
-
- // This can be called to attempt to reduce memory footprint until within
- // limit for bytes to keep under moderate pressure.
- void ReduceMemoryUsageUntilWithinLimit(size_t bytes);
-
- // Adds the given allocation to the manager's collection.
- void Register(Allocation* allocation, size_t bytes);
-
- // Removes the given allocation from the manager's collection.
- void Unregister(Allocation* allocation);
-
- // Returns false if an error occurred. Otherwise, returns true and sets
- // |purged| to indicate whether or not allocation has been purged since last
- // use.
- bool AcquireLock(Allocation* allocation, bool* purged);
-
- // Release a previously acquired lock on allocation. This allows the manager
- // to purge it if necessary.
- void ReleaseLock(Allocation* allocation);
-
- // Purges all discardable memory.
- void PurgeAll();
-
- // Returns true if allocation has been added to the manager's collection. This
- // should only be used by tests.
- bool IsRegisteredForTest(Allocation* allocation) const;
-
- // Returns true if allocation can be purged. This should only be used by
- // tests.
- bool CanBePurgedForTest(Allocation* allocation) const;
-
- // Returns total amount of allocated discardable memory. This should only be
- // used by tests.
- size_t GetBytesAllocatedForTest() const;
-
- private:
- struct AllocationInfo {
- explicit AllocationInfo(size_t bytes) : bytes(bytes), purgable(false) {}
-
- const size_t bytes;
- bool purgable;
- TimeTicks last_usage;
- };
- typedef HashingMRUCache<Allocation*, AllocationInfo> AllocationMap;
-
- // Purges memory not used since |hard_memory_limit_expiration_time_| before
- // "right now" until usage is less or equal to |soft_memory_limit_|.
- // Returns true if total amount of memory is less or equal to soft memory
- // limit.
- bool PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit();
-
- // Purges memory that has not been used since |timestamp| until usage is less
- // or equal to |limit|.
- // Caller must acquire |lock_| prior to calling this function.
- void PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
- TimeTicks timestamp,
- size_t limit);
-
- // Called when a change to |bytes_allocated_| has been made.
- void BytesAllocatedChanged(size_t new_bytes_allocated) const;
-
- // Virtual for tests.
- virtual TimeTicks Now() const;
-
- // Needs to be held when accessing members.
- mutable Lock lock_;
-
- // A MRU cache of all allocated bits of memory. Used for purging.
- AllocationMap allocations_;
-
- // The total amount of allocated memory.
- size_t bytes_allocated_;
-
- // The maximum number of bytes of memory that may be allocated.
- size_t memory_limit_;
-
- // The number of bytes of memory that may be allocated but not used for
- // |hard_memory_limit_expiration_time_| amount of time when receiving an idle
- // notification.
- size_t soft_memory_limit_;
-
- // Amount of time it takes for an allocation to become affected by
- // |soft_memory_limit_|.
- TimeDelta hard_memory_limit_expiration_time_;
-
- DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryManager);
-};
-
-} // namespace internal
-} // namespace base
-
-#endif // BASE_MEMORY_DISCARDABLE_MEMORY_MANAGER_H_
diff --git a/base/memory/discardable_memory_manager_unittest.cc b/base/memory/discardable_memory_manager_unittest.cc
deleted file mode 100644
index 6717f09..0000000
--- a/base/memory/discardable_memory_manager_unittest.cc
+++ /dev/null
@@ -1,490 +0,0 @@
-// Copyright 2014 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.
-
-#include "base/memory/discardable_memory_manager.h"
-
-#include "base/bind.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace base {
-namespace {
-
-class TestAllocationImpl : public internal::DiscardableMemoryManagerAllocation {
- public:
- TestAllocationImpl() : is_allocated_(false), is_locked_(false) {}
- ~TestAllocationImpl() override { DCHECK(!is_locked_); }
-
- // Overridden from internal::DiscardableMemoryManagerAllocation:
- bool AllocateAndAcquireLock() override {
- bool was_allocated = is_allocated_;
- is_allocated_ = true;
- DCHECK(!is_locked_);
- is_locked_ = true;
- return was_allocated;
- }
- void ReleaseLock() override {
- DCHECK(is_locked_);
- is_locked_ = false;
- }
- void Purge() override {
- DCHECK(is_allocated_);
- is_allocated_ = false;
- }
-
- bool is_locked() const { return is_locked_; }
-
- private:
- bool is_allocated_;
- bool is_locked_;
-};
-
-// Tests can assume that the default limit is at least 1024. Tests that rely on
-// something else needs to explicit set the limit.
-const size_t kDefaultMemoryLimit = 1024;
-const size_t kDefaultSoftMemoryLimit = kDefaultMemoryLimit;
-
-class TestDiscardableMemoryManagerImpl
- : public internal::DiscardableMemoryManager {
- public:
- TestDiscardableMemoryManagerImpl()
- : DiscardableMemoryManager(kDefaultMemoryLimit,
- kDefaultSoftMemoryLimit,
- TimeDelta::Max()) {}
-
- void SetNow(TimeTicks now) { now_ = now; }
-
- private:
- // Overriden from internal::DiscardableMemoryManager:
- TimeTicks Now() const override { return now_; }
-
- TimeTicks now_;
-};
-
-class DiscardableMemoryManagerTestBase {
- public:
- DiscardableMemoryManagerTestBase() {}
-
- protected:
- enum LockStatus {
- LOCK_STATUS_FAILED,
- LOCK_STATUS_PURGED,
- LOCK_STATUS_SUCCESS
- };
-
- size_t BytesAllocated() const { return manager_.GetBytesAllocatedForTest(); }
-
- void SetMemoryLimit(size_t bytes) { manager_.SetMemoryLimit(bytes); }
-
- void SetSoftMemoryLimit(size_t bytes) { manager_.SetSoftMemoryLimit(bytes); }
-
- void SetHardMemoryLimitExpirationTime(TimeDelta time) {
- manager_.SetHardMemoryLimitExpirationTime(time);
- }
-
- void Register(TestAllocationImpl* allocation, size_t bytes) {
- manager_.Register(allocation, bytes);
- }
-
- void Unregister(TestAllocationImpl* allocation) {
- manager_.Unregister(allocation);
- }
-
- bool IsRegistered(TestAllocationImpl* allocation) const {
- return manager_.IsRegisteredForTest(allocation);
- }
-
- LockStatus Lock(TestAllocationImpl* allocation) {
- bool purged;
- if (!manager_.AcquireLock(allocation, &purged))
- return LOCK_STATUS_FAILED;
- return purged ? LOCK_STATUS_PURGED : LOCK_STATUS_SUCCESS;
- }
-
- void Unlock(TestAllocationImpl* allocation) {
- manager_.ReleaseLock(allocation);
- }
-
- LockStatus RegisterAndLock(TestAllocationImpl* allocation, size_t bytes) {
- manager_.Register(allocation, bytes);
- return Lock(allocation);
- }
-
- bool CanBePurged(TestAllocationImpl* allocation) const {
- return manager_.CanBePurgedForTest(allocation);
- }
-
- void SetNow(TimeTicks now) { manager_.SetNow(now); }
-
- void PurgeAll() { return manager_.PurgeAll(); }
-
- bool ReduceMemoryUsage() { return manager_.ReduceMemoryUsage(); }
-
- void ReduceMemoryUsageUntilWithinLimit(size_t bytes) {
- manager_.ReduceMemoryUsageUntilWithinLimit(bytes);
- }
-
- private:
- TestDiscardableMemoryManagerImpl manager_;
-};
-
-class DiscardableMemoryManagerTest : public DiscardableMemoryManagerTestBase,
- public testing::Test {
- public:
- DiscardableMemoryManagerTest() {}
-};
-
-TEST_F(DiscardableMemoryManagerTest, CreateAndLock) {
- size_t size = 1024;
- TestAllocationImpl allocation;
- Register(&allocation, size);
- EXPECT_TRUE(IsRegistered(&allocation));
- EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation));
- EXPECT_TRUE(allocation.is_locked());
- EXPECT_EQ(1024u, BytesAllocated());
- EXPECT_FALSE(CanBePurged(&allocation));
- Unlock(&allocation);
- Unregister(&allocation);
-}
-
-TEST_F(DiscardableMemoryManagerTest, CreateZeroSize) {
- size_t size = 0;
- TestAllocationImpl allocation;
- Register(&allocation, size);
- EXPECT_TRUE(IsRegistered(&allocation));
- EXPECT_EQ(LOCK_STATUS_FAILED, Lock(&allocation));
- EXPECT_EQ(0u, BytesAllocated());
- Unregister(&allocation);
-}
-
-TEST_F(DiscardableMemoryManagerTest, LockAfterUnlock) {
- size_t size = 1024;
- TestAllocationImpl allocation;
- RegisterAndLock(&allocation, size);
- EXPECT_EQ(1024u, BytesAllocated());
- EXPECT_FALSE(CanBePurged(&allocation));
-
- // Now unlock so we can lock later.
- Unlock(&allocation);
- EXPECT_TRUE(CanBePurged(&allocation));
-
- EXPECT_EQ(LOCK_STATUS_SUCCESS, Lock(&allocation));
- EXPECT_FALSE(CanBePurged(&allocation));
- Unlock(&allocation);
- Unregister(&allocation);
-}
-
-TEST_F(DiscardableMemoryManagerTest, LockAfterPurge) {
- size_t size = 1024;
- TestAllocationImpl allocation;
- RegisterAndLock(&allocation, size);
- EXPECT_EQ(1024u, BytesAllocated());
- EXPECT_FALSE(CanBePurged(&allocation));
-
- // Now unlock so we can lock later.
- Unlock(&allocation);
- EXPECT_TRUE(CanBePurged(&allocation));
-
- // Force the system to purge.
- PurgeAll();
-
- EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation));
- EXPECT_FALSE(CanBePurged(&allocation));
-
- Unlock(&allocation);
- Unregister(&allocation);
-}
-
-TEST_F(DiscardableMemoryManagerTest, LockAfterPurgeAndCannotReallocate) {
- size_t size = 1024;
- TestAllocationImpl allocation;
- RegisterAndLock(&allocation, size);
- EXPECT_EQ(1024u, BytesAllocated());
- EXPECT_FALSE(CanBePurged(&allocation));
-
- // Now unlock so we can lock later.
- Unlock(&allocation);
- EXPECT_TRUE(CanBePurged(&allocation));
-
- // Set max allowed allocation to 1 byte. This will cause the memory to be
- // purged.
- SetMemoryLimit(1);
-
- EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation));
- EXPECT_FALSE(CanBePurged(&allocation));
-
- Unlock(&allocation);
- Unregister(&allocation);
-}
-
-TEST_F(DiscardableMemoryManagerTest, Overflow) {
- size_t size = 1024;
- {
- TestAllocationImpl allocation;
- RegisterAndLock(&allocation, size);
- EXPECT_EQ(1024u, BytesAllocated());
-
- size_t massive_size = std::numeric_limits<size_t>::max();
- TestAllocationImpl massive_allocation;
- Register(&massive_allocation, massive_size);
- EXPECT_EQ(LOCK_STATUS_FAILED, Lock(&massive_allocation));
- EXPECT_EQ(1024u, BytesAllocated());
-
- Unlock(&allocation);
- EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&massive_allocation));
- Unlock(&massive_allocation);
- Unregister(&massive_allocation);
- Unregister(&allocation);
- }
- EXPECT_EQ(0u, BytesAllocated());
-}
-
-class PermutationTestData {
- public:
- PermutationTestData(unsigned d0, unsigned d1, unsigned d2) {
- ordering_[0] = d0;
- ordering_[1] = d1;
- ordering_[2] = d2;
- }
-
- const unsigned* ordering() const { return ordering_; }
-
- private:
- unsigned ordering_[3];
-};
-
-class DiscardableMemoryManagerPermutationTest
- : public DiscardableMemoryManagerTestBase,
- public testing::TestWithParam<PermutationTestData> {
- public:
- DiscardableMemoryManagerPermutationTest() {}
-
- protected:
- // Use memory in order specified by ordering parameter.
- void RegisterAndUseAllocations() {
- for (int i = 0; i < 3; ++i) {
- RegisterAndLock(&allocation_[i], 1024);
- Unlock(&allocation_[i]);
- }
- for (int i = 0; i < 3; ++i) {
- int index = GetParam().ordering()[i];
- EXPECT_NE(LOCK_STATUS_FAILED, Lock(&allocation_[index]));
- // Leave i == 0 locked.
- if (i > 0)
- Unlock(&allocation_[index]);
- }
- }
-
- TestAllocationImpl* allocation(unsigned position) {
- return &allocation_[GetParam().ordering()[position]];
- }
-
- void UnlockAndUnregisterAllocations() {
- for (int i = 0; i < 3; ++i) {
- if (allocation_[i].is_locked())
- Unlock(&allocation_[i]);
- Unregister(&allocation_[i]);
- }
- }
-
- private:
- TestAllocationImpl allocation_[3];
-};
-
-// Verify that memory was discarded in the correct order after reducing usage to
-// limit.
-TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscarded) {
- RegisterAndUseAllocations();
-
- SetMemoryLimit(2048);
-
- ReduceMemoryUsageUntilWithinLimit(1024);
-
- EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2)));
- EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
- // 0 should still be locked.
- EXPECT_TRUE(allocation(0)->is_locked());
-
- UnlockAndUnregisterAllocations();
-}
-
-// Verify that memory was discarded in the correct order after changing
-// memory limit.
-TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedExceedLimit) {
- RegisterAndUseAllocations();
-
- SetMemoryLimit(2048);
-
- EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2)));
- EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
- // 0 should still be locked.
- EXPECT_TRUE(allocation(0)->is_locked());
-
- UnlockAndUnregisterAllocations();
-}
-
-// Verify that no more memory than necessary was discarded after changing
-// memory limit.
-TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedAmount) {
- SetMemoryLimit(4096);
-
- RegisterAndUseAllocations();
-
- SetMemoryLimit(2048);
-
- EXPECT_EQ(LOCK_STATUS_SUCCESS, Lock(allocation(2)));
- EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
- // 0 should still be locked.
- EXPECT_TRUE(allocation(0)->is_locked());
-
- UnlockAndUnregisterAllocations();
-}
-
-TEST_P(DiscardableMemoryManagerPermutationTest, PurgeFreesAllUnlocked) {
- RegisterAndUseAllocations();
-
- PurgeAll();
-
- for (int i = 0; i < 3; ++i) {
- if (i == 0)
- EXPECT_TRUE(allocation(i)->is_locked());
- else
- EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(i)));
- }
-
- UnlockAndUnregisterAllocations();
-}
-
-INSTANTIATE_TEST_CASE_P(DiscardableMemoryManagerPermutationTests,
- DiscardableMemoryManagerPermutationTest,
- ::testing::Values(PermutationTestData(0, 1, 2),
- PermutationTestData(0, 2, 1),
- PermutationTestData(1, 0, 2),
- PermutationTestData(1, 2, 0),
- PermutationTestData(2, 0, 1),
- PermutationTestData(2, 1, 0)));
-
-TEST_F(DiscardableMemoryManagerTest, NormalDestruction) {
- {
- size_t size = 1024;
- TestAllocationImpl allocation;
- Register(&allocation, size);
- Unregister(&allocation);
- }
- EXPECT_EQ(0u, BytesAllocated());
-}
-
-TEST_F(DiscardableMemoryManagerTest, DestructionAfterLocked) {
- {
- size_t size = 1024;
- TestAllocationImpl allocation;
- RegisterAndLock(&allocation, size);
- EXPECT_EQ(1024u, BytesAllocated());
- EXPECT_FALSE(CanBePurged(&allocation));
- Unlock(&allocation);
- Unregister(&allocation);
- }
- EXPECT_EQ(0u, BytesAllocated());
-}
-
-TEST_F(DiscardableMemoryManagerTest, DestructionAfterPurged) {
- {
- size_t size = 1024;
- TestAllocationImpl allocation;
- RegisterAndLock(&allocation, size);
- EXPECT_EQ(1024u, BytesAllocated());
- Unlock(&allocation);
- EXPECT_TRUE(CanBePurged(&allocation));
- SetMemoryLimit(0);
- EXPECT_EQ(0u, BytesAllocated());
- Unregister(&allocation);
- }
- EXPECT_EQ(0u, BytesAllocated());
-}
-
-TEST_F(DiscardableMemoryManagerTest, ReduceMemoryUsage) {
- SetMemoryLimit(3072);
- SetSoftMemoryLimit(1024);
- SetHardMemoryLimitExpirationTime(TimeDelta::FromInternalValue(1));
-
- size_t size = 1024;
- TestAllocationImpl allocation[3];
- RegisterAndLock(&allocation[0], size);
- RegisterAndLock(&allocation[1], size);
- RegisterAndLock(&allocation[2], size);
- EXPECT_EQ(3072u, BytesAllocated());
-
- // Above soft limit but nothing that can be purged.
- EXPECT_FALSE(ReduceMemoryUsage());
-
- SetNow(TimeTicks::FromInternalValue(0));
- Unlock(&allocation[0]);
-
- // Above soft limit but still nothing that can be purged as all unlocked
- // allocations are within the hard limit cutoff time.
- EXPECT_FALSE(ReduceMemoryUsage());
-
- SetNow(TimeTicks::FromInternalValue(1));
- Unlock(&allocation[1]);
-
- // One unlocked allocation is no longer within the hard limit cutoff time. It
- // should be purged and ReduceMemoryUsage() should return false as we're not
- // yet within the soft memory limit.
- EXPECT_FALSE(ReduceMemoryUsage());
- EXPECT_EQ(2048u, BytesAllocated());
-
- // One more unlocked allocation is no longer within the hard limit cutoff
- // time. It should be purged and ReduceMemoryUsage() should return true as
- // we're now within the soft memory limit.
- SetNow(TimeTicks::FromInternalValue(2));
- EXPECT_TRUE(ReduceMemoryUsage());
- EXPECT_EQ(1024u, BytesAllocated());
-
- Unlock(&allocation[2]);
-
- Unregister(&allocation[0]);
- Unregister(&allocation[1]);
- Unregister(&allocation[2]);
-}
-
-class ThreadedDiscardableMemoryManagerTest
- : public DiscardableMemoryManagerTest {
- public:
- ThreadedDiscardableMemoryManagerTest()
- : memory_usage_thread_("memory_usage_thread"),
- thread_sync_(true, false) {}
-
- void SetUp() override { memory_usage_thread_.Start(); }
-
- void TearDown() override { memory_usage_thread_.Stop(); }
-
- void UseMemoryHelper() {
- size_t size = 1024;
- TestAllocationImpl allocation;
- RegisterAndLock(&allocation, size);
- Unlock(&allocation);
- Unregister(&allocation);
- }
-
- void SignalHelper() { thread_sync_.Signal(); }
-
- Thread memory_usage_thread_;
- WaitableEvent thread_sync_;
-};
-
-TEST_F(ThreadedDiscardableMemoryManagerTest, UseMemoryOnThread) {
- memory_usage_thread_.message_loop()->PostTask(
- FROM_HERE,
- Bind(&ThreadedDiscardableMemoryManagerTest::UseMemoryHelper,
- Unretained(this)));
- memory_usage_thread_.message_loop()->PostTask(
- FROM_HERE,
- Bind(&ThreadedDiscardableMemoryManagerTest::SignalHelper,
- Unretained(this)));
- thread_sync_.Wait();
-}
-
-} // namespace
-} // namespace base