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

Side by Side Diff: mojo/services/html_viewer/discardable_memory_allocator.cc

Issue 1016493002: Add a DiscardableMemoryShmemeAllocator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add unit tests Created 5 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/services/html_viewer/discardable_memory_allocator.h"
6
7 #include "base/memory/weak_ptr.h"
8 #include "base/stl_util.h"
9
10 namespace html_viewer {
11
12 // Represents an actual memory chunk. This is an object owned by
13 // DiscardableMemoryAllocator. DiscardableMemoryChunkImpl are passed to the
14 // rest of the program, and access this memory through a weak ptr.
15 class DiscardableMemoryAllocator::OwnedMemoryChunk {
16 public:
17 OwnedMemoryChunk(size_t size)
jamesr 2015/03/17 23:26:19 explicit
18 : is_locked_(true),
19 size_(size),
20 memory_(new uint8_t[size]),
21 allocator_(nullptr),
22 weak_factory_(this) {}
23 ~OwnedMemoryChunk() {}
24
25 void Lock() {
26 DCHECK(!is_locked_);
27 is_locked_ = true;
28
29 // While locked, we also move ourselves to the back of the list.
30 allocator_->MoveToBack(it_);
31 }
32
33 void Unlock() {
34 DCHECK(is_locked_);
35 is_locked_ = false;
36 }
37
38 bool locked() const { return is_locked_; }
39 size_t size() const { return size_; }
40 void* Memory() const { return memory_.get(); }
jamesr 2015/03/17 23:26:19 DCHECK(is_locked_) here
41
42 base::WeakPtr<OwnedMemoryChunk> GetWeakPtr() {
43 return weak_factory_.GetWeakPtr();
44 }
45
46 void SetAllocatorAndPosition(std::list<OwnedMemoryChunk*>::iterator it,
47 DiscardableMemoryAllocator* allocator) {
48 it_ = it;
49 allocator_ = allocator;
50 }
51
52 private:
53 bool is_locked_;
54 size_t size_;
55 scoped_ptr<uint8_t[]> memory_;
56
57 std::list<OwnedMemoryChunk*>::iterator it_;
58 DiscardableMemoryAllocator* allocator_;
59
60 base::WeakPtrFactory<OwnedMemoryChunk> weak_factory_;
61
62 DISALLOW_IMPLICIT_CONSTRUCTORS(OwnedMemoryChunk);
63 };
64
65 namespace {
66
67 // Interface to the rest of the program. These objects are owned outside of the
68 // allocator and wrap a weak ptr.
69 class DiscardableMemoryChunkImpl : public base::DiscardableMemoryShmemChunk {
70 public:
71 explicit DiscardableMemoryChunkImpl(
72 base::WeakPtr<DiscardableMemoryAllocator::OwnedMemoryChunk> chunk)
73 : memory_chunk_(chunk) {}
74 ~DiscardableMemoryChunkImpl() override {}
75
76 // Overridden from DiscardableMemoryShmemChunk:
77 bool Lock() override {
78 if (!memory_chunk_)
79 return false;
80
81 memory_chunk_->Lock();
82 return true;
83 }
84
85 void Unlock() override {
86 if (memory_chunk_)
87 memory_chunk_->Unlock();
88 }
89
90 void* Memory() const override {
91 if (memory_chunk_)
92 return memory_chunk_->Memory();
93 return nullptr;
94 }
95
96 private:
97 base::WeakPtr<DiscardableMemoryAllocator::OwnedMemoryChunk> memory_chunk_;
98
99 DISALLOW_IMPLICIT_CONSTRUCTORS(DiscardableMemoryChunkImpl);
100 };
101
102 } // namespace
103
104 DiscardableMemoryAllocator::DiscardableMemoryAllocator(size_t max_memory)
105 : max_memory_(max_memory),
106 total_live_memory_(0) {
107 }
108
109 DiscardableMemoryAllocator::~DiscardableMemoryAllocator() {
110 STLDeleteElements(&live_chunks_);
111 }
112
113 scoped_ptr<base::DiscardableMemoryShmemChunk>
114 DiscardableMemoryAllocator::AllocateLockedDiscardableMemory(size_t size) {
115 OwnedMemoryChunk* chunk = new OwnedMemoryChunk(size);
116 auto it = live_chunks_.insert(live_chunks_.end(), chunk);
117 chunk->SetAllocatorAndPosition(it, this);
118 total_live_memory_ += size;
119
120 // Purge unlocked chunks from the cache until |total_live_memory_| is under
121 // the desired maximum size.
122 it = live_chunks_.begin();
123 while (total_live_memory_ > max_memory_ && it != live_chunks_.end()) {
124 if (!(*it)->locked()) {
125 total_live_memory_ -= (*it)->size();
126 delete *it;
127 it = live_chunks_.erase(it);
128 } else {
129 it++;
130 }
131 }
132
133 return make_scoped_ptr(new DiscardableMemoryChunkImpl(chunk->GetWeakPtr()));
134 }
135
136 void DiscardableMemoryAllocator::MoveToBack(
137 std::list<OwnedMemoryChunk*>::iterator it) {
138 OwnedMemoryChunk* chunk = *it;
139 live_chunks_.erase(it);
140 it = live_chunks_.insert(live_chunks_.end(), chunk);
141 chunk->SetAllocatorAndPosition(it, this);
142 }
143
144 } // namespace html_viewer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698