Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1633)

Unified Diff: base/memory/discardable_memory_emulated.cc

Issue 204733003: base: Refactor DiscardableMemoryManager for use with different type of allocations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add missing unlock call and remove unnecessary unlock call Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/memory/discardable_memory_emulated.cc
diff --git a/base/memory/discardable_memory_emulated.cc b/base/memory/discardable_memory_emulated.cc
index 82f887f55d33d967995dc0e68f8f8a69b383c9ab..89ca590015c3d89284d6e82e2d820c1fdc156b77 100644
--- a/base/memory/discardable_memory_emulated.cc
+++ b/base/memory/discardable_memory_emulated.cc
@@ -4,14 +4,92 @@
#include "base/memory/discardable_memory_emulated.h"
+#include "base/bind.h"
#include "base/lazy_instance.h"
-#include "base/memory/discardable_memory_manager.h"
+#include "base/memory/memory_pressure_listener.h"
+#include "base/message_loop/message_loop.h"
+#include "base/threading/thread_checker.h"
namespace base {
namespace {
-base::LazyInstance<internal::DiscardableMemoryManager>::Leaky g_manager =
+class DiscardableMemoryAllocationImpl
willchan no longer on Chromium 2014/04/01 01:11:08 Maybe we should name this DiscardableMemoryHeapAll
reveman 2014/04/03 17:02:12 I added a comment here to emphasize the use of hea
willchan no longer on Chromium 2014/04/15 20:51:31 I will defer to you here. Please take my comment a
+ : public internal::DiscardableMemoryAllocation {
+ public:
+ explicit DiscardableMemoryAllocationImpl(size_t bytes)
+ : memory_(new uint8[bytes]) {}
+
+ // Overridden from internal::DiscardableMemoryAllocation:
+ virtual bool Lock() OVERRIDE { return true; }
+ virtual void Unlock() OVERRIDE {}
+ virtual void* Memory() OVERRIDE { return memory_.get(); }
+
+ private:
+ scoped_ptr<uint8[]> memory_;
+};
+
+// This is admittedly pretty magical. It's approximately enough memory for four
+// 2560x1600 images.
+const size_t kDefaultDiscardableMemoryLimit = 64 * 1024 * 1024;
+
+// Under moderate memory pressure, we will purge until usage is within this
+// limit.
+const size_t kBytesToKeepUnderModeratePressure =
+ kDefaultDiscardableMemoryLimit / 4;
+
+class DiscardableMemoryManagerImpl
+ : public internal::DiscardableMemoryManager,
+ public internal::DiscardableMemoryAllocation::Factory {
+ public:
+ DiscardableMemoryManagerImpl()
+ : internal::DiscardableMemoryManager(this,
Philippe 2014/03/20 18:08:31 I think this part is slightly hairy :) Correct me
reveman 2014/03/20 19:08:22 Correct.
Philippe 2014/03/21 09:13:09 I think we will have to initialize the factory bef
Philippe 2014/03/21 09:49:19 I think this should be a reasonable compromise tha
reveman 2014/03/21 12:32:16 Why not?
reveman 2014/03/21 12:32:16 I don't like that either. Awkward for the manager
Philippe 2014/03/21 12:40:50 Because this would be a direct violation of the Li
reveman 2014/03/22 16:49:34 Correct, DiscardableMemoryManagerImpl is not a Fac
Philippe 2014/03/24 09:35:31 Just to be clear and so that the information is pr
willchan no longer on Chromium 2014/04/01 01:11:08 I am not fully up to date with Philippe's proposal
reveman 2014/04/03 17:02:12 Do we really need to avoid all kinds of concrete c
Philippe 2014/04/14 15:35:47 I agree, let's move this forward :) I think I have
willchan no longer on Chromium 2014/04/15 20:51:31 It's not strictly disallowed, but it's strongly di
+ kDefaultDiscardableMemoryLimit) {}
+
+ // Overridden from internal::DiscardableMemoryAllocation::Factory:
+ virtual scoped_ptr<internal::DiscardableMemoryAllocation>
+ CreateLockedAllocation(size_t bytes) OVERRIDE {
+ return make_scoped_ptr<internal::DiscardableMemoryAllocation>(
+ new DiscardableMemoryAllocationImpl(bytes));
+ }
+
+ void RegisterMemoryPressureListener() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(base::MessageLoop::current());
+ DCHECK(!memory_pressure_listener_);
+ memory_pressure_listener_.reset(new MemoryPressureListener(base::Bind(
+ &DiscardableMemoryManagerImpl::OnMemoryPressure, Unretained(this))));
+ }
+
+ void UnregisterMemoryPressureListener() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(memory_pressure_listener_);
+ memory_pressure_listener_.reset();
+ }
+
+ // This can be called as a hint that the system is under memory pressure.
+ void OnMemoryPressure(
+ MemoryPressureListener::MemoryPressureLevel pressure_level) {
+ switch (pressure_level) {
+ case MemoryPressureListener::MEMORY_PRESSURE_MODERATE:
+ PurgeUntilUsageIsWithin(kBytesToKeepUnderModeratePressure);
+ return;
+ case MemoryPressureListener::MEMORY_PRESSURE_CRITICAL:
+ PurgeUntilUsageIsWithin(0u);
+ return;
+ }
+
+ NOTREACHED();
+ }
+
+ private:
+ // Allows us to be respond when the system reports that it is under memory
+ // pressure.
+ scoped_ptr<MemoryPressureListener> memory_pressure_listener_;
+
+ base::ThreadChecker thread_checker_;
+};
+base::LazyInstance<DiscardableMemoryManagerImpl>::Leaky g_manager =
LAZY_INSTANCE_INITIALIZER;
} // namespace
@@ -19,14 +97,10 @@ base::LazyInstance<internal::DiscardableMemoryManager>::Leaky g_manager =
namespace internal {
DiscardableMemoryEmulated::DiscardableMemoryEmulated(size_t size)
- : is_locked_(false) {
- g_manager.Pointer()->Register(this, size);
-}
+ : allocation_id_(g_manager.Pointer()->Register(size)), memory_(NULL) {}
DiscardableMemoryEmulated::~DiscardableMemoryEmulated() {
- if (is_locked_)
- Unlock();
- g_manager.Pointer()->Unregister(this);
+ g_manager.Pointer()->Unregister(allocation_id_);
}
// static
@@ -41,7 +115,7 @@ void DiscardableMemoryEmulated::UnregisterMemoryPressureListeners() {
// static
void DiscardableMemoryEmulated::PurgeForTesting() {
- g_manager.Pointer()->PurgeAll();
+ g_manager.Pointer()->PurgeUntilUsageIsWithin(0u);
}
bool DiscardableMemoryEmulated::Initialize() {
@@ -49,27 +123,26 @@ bool DiscardableMemoryEmulated::Initialize() {
}
DiscardableMemoryLockStatus DiscardableMemoryEmulated::Lock() {
- DCHECK(!is_locked_);
+ DCHECK(!memory_);
bool purged = false;
- memory_ = g_manager.Pointer()->Acquire(this, &purged);
+ memory_ = g_manager.Pointer()->Lock(allocation_id_, &purged);
if (!memory_)
return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
- is_locked_ = true;
return purged ? DISCARDABLE_MEMORY_LOCK_STATUS_PURGED
: DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS;
}
void DiscardableMemoryEmulated::Unlock() {
- DCHECK(is_locked_);
- g_manager.Pointer()->Release(this, memory_.Pass());
- is_locked_ = false;
+ DCHECK(memory_);
+ g_manager.Pointer()->Unlock(allocation_id_);
+ memory_ = NULL;
}
void* DiscardableMemoryEmulated::Memory() const {
DCHECK(memory_);
- return memory_.get();
+ return memory_;
}
} // namespace internal

Powered by Google App Engine
This is Rietveld 408576698