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

Side by Side Diff: components/discardable_memory/client/client_discardable_shared_memory_manager.cc

Issue 2485623002: discardable_memory: Using mojo IPC to replace Chrome IPC (Closed)
Patch Set: Address review issues. Created 4 years, 1 month 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/discardable_memory/client/client_discardable_shared_memory_ manager.h" 5 #include "components/discardable_memory/client/client_discardable_shared_memory_ manager.h"
6 6
7 #include <inttypes.h> 7 #include <inttypes.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/atomic_sequence_num.h" 12 #include "base/atomic_sequence_num.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/debug/crash_logging.h" 14 #include "base/debug/crash_logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/discardable_memory.h" 16 #include "base/memory/discardable_memory.h"
17 #include "base/memory/discardable_shared_memory.h" 17 #include "base/memory/discardable_shared_memory.h"
18 #include "base/memory/ptr_util.h" 18 #include "base/memory/ptr_util.h"
19 #include "base/metrics/histogram_macros.h" 19 #include "base/metrics/histogram_macros.h"
20 #include "base/process/memory.h" 20 #include "base/process/memory.h"
21 #include "base/process/process_metrics.h" 21 #include "base/process/process_metrics.h"
22 #include "base/strings/string_number_conversions.h" 22 #include "base/strings/string_number_conversions.h"
23 #include "base/strings/stringprintf.h" 23 #include "base/strings/stringprintf.h"
24 #include "base/synchronization/waitable_event.h"
24 #include "base/threading/thread_task_runner_handle.h" 25 #include "base/threading/thread_task_runner_handle.h"
25 #include "base/trace_event/memory_dump_manager.h" 26 #include "base/trace_event/memory_dump_manager.h"
26 #include "base/trace_event/trace_event.h" 27 #include "base/trace_event/trace_event.h"
28 #include "mojo/public/cpp/system/platform_handle.h"
27 29
28 namespace discardable_memory { 30 namespace discardable_memory {
29 namespace { 31 namespace {
30 32
31 // Default allocation size. 33 // Default allocation size.
32 const size_t kAllocationSize = 4 * 1024 * 1024; 34 const size_t kAllocationSize = 4 * 1024 * 1024;
33 35
34 // Global atomic to generate unique discardable shared memory IDs. 36 // Global atomic to generate unique discardable shared memory IDs.
35 base::StaticAtomicSequenceNumber g_next_discardable_shared_memory_id; 37 base::StaticAtomicSequenceNumber g_next_discardable_shared_memory_id;
36 38
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 } 77 }
76 78
77 private: 79 private:
78 ClientDiscardableSharedMemoryManager* const manager_; 80 ClientDiscardableSharedMemoryManager* const manager_;
79 std::unique_ptr<DiscardableSharedMemoryHeap::Span> span_; 81 std::unique_ptr<DiscardableSharedMemoryHeap::Span> span_;
80 bool is_locked_; 82 bool is_locked_;
81 83
82 DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryImpl); 84 DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryImpl);
83 }; 85 };
84 86
85 void SendDeletedDiscardableSharedMemoryMessage( 87 } // namespace
86 ClientDiscardableSharedMemoryManager::Delegate* delegate, 88
87 DiscardableSharedMemoryId id) { 89 // A wrapper for mojo interface DiscardableSharedMemroyManager. It makes
88 delegate->DeletedDiscardableSharedMemory(id); 90 // the mojo interface thread safe.
91 class ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy
92 : public base::RefCountedThreadSafe<ThreadSafeManagerProxy> {
93 public:
94 ThreadSafeManagerProxy(mojom::DiscardableSharedMemoryManagerPtrInfo info,
95 base::SingleThreadTaskRunner* io_task_runner);
96 std::unique_ptr<base::DiscardableSharedMemory> Allocate(size_t size,
97 int32_t id);
98 void Deleted(int32_t id);
99
100 private:
101 friend class base::RefCountedThreadSafe<ThreadSafeManagerProxy>;
102
103 ~ThreadSafeManagerProxy() {}
104
105 void OnConnectionError();
106 void InitInIOThread(mojom::DiscardableSharedMemoryManagerPtrInfo info);
107 void AllocateInIOThread(
108 size_t size,
109 int32_t id,
110 std::unique_ptr<base::DiscardableSharedMemory>* memory,
111 base::WaitableEvent* event);
112 void OnAllocateCompletedInIOThread(
113 std::unique_ptr<base::DiscardableSharedMemory>* memory,
114 base::WaitableEvent* event,
115 mojo::ScopedSharedBufferHandle mojo_handle);
116 void DeletedInIOThread(int32_t id);
117
118 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
119 mojom::DiscardableSharedMemoryManagerPtr manager_;
120
121 DISALLOW_COPY_AND_ASSIGN(ThreadSafeManagerProxy);
122 };
123
124 ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
125 ThreadSafeManagerProxy(mojom::DiscardableSharedMemoryManagerPtrInfo info,
126 base::SingleThreadTaskRunner* io_task_runner)
127 : io_task_runner_(io_task_runner) {
128 io_task_runner_->PostTask(
129 FROM_HERE, base::Bind(&ClientDiscardableSharedMemoryManager::
130 ThreadSafeManagerProxy::InitInIOThread,
131 this, base::Passed(&info)));
89 } 132 }
90 133
91 } // namespace 134 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
135 OnConnectionError() {
136 manager_.reset();
137 }
138
139 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
140 InitInIOThread(mojom::DiscardableSharedMemoryManagerPtrInfo info) {
141 DCHECK(io_task_runner_->BelongsToCurrentThread());
142 manager_.Bind(std::move(info));
143 manager_.set_connection_error_handler(
144 base::Bind(&ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
145 OnConnectionError,
146 this));
147 }
148
149 std::unique_ptr<base::DiscardableSharedMemory>
150 ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::Allocate(
151 size_t size,
152 int32_t id) {
153 DCHECK(!io_task_runner_->BelongsToCurrentThread());
154 std::unique_ptr<base::DiscardableSharedMemory> memory;
155 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
156 base::WaitableEvent::InitialState::NOT_SIGNALED);
157 io_task_runner_->PostTask(
158 FROM_HERE, base::Bind(&ClientDiscardableSharedMemoryManager::
159 ThreadSafeManagerProxy::AllocateInIOThread,
160 this, size, id, &memory, &event));
161 // Waiting until IPC is finished in the IO thread.
162 event.Wait();
163 return memory;
164 }
165
166 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::Deleted(
167 int32_t id) {
168 DCHECK(!io_task_runner_->BelongsToCurrentThread());
169 io_task_runner_->PostTask(
170 FROM_HERE, base::Bind(&ClientDiscardableSharedMemoryManager::
171 ThreadSafeManagerProxy::DeletedInIOThread,
172 this, id));
173 }
174
175 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
176 AllocateInIOThread(size_t size,
177 int32_t id,
178 std::unique_ptr<base::DiscardableSharedMemory>* memory,
179 base::WaitableEvent* event) {
180 DCHECK(io_task_runner_->BelongsToCurrentThread());
181 if (!manager_)
182 return;
183 manager_->AllocateLockedDiscardableSharedMemory(
184 static_cast<uint32_t>(size), id,
185 base::Bind(&ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
186 OnAllocateCompletedInIOThread,
187 this, memory, event));
188 }
189
190 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
191 OnAllocateCompletedInIOThread(
192 std::unique_ptr<base::DiscardableSharedMemory>* memory,
193 base::WaitableEvent* event,
194 mojo::ScopedSharedBufferHandle mojo_handle) {
195 DCHECK(io_task_runner_->BelongsToCurrentThread());
196 do {
197 if (!mojo_handle.is_valid())
198 break;
199 auto handle = base::SharedMemory::NULLHandle();
200 size_t memory_size = 0;
201 bool read_only = false;
202 auto result = mojo::UnwrapSharedMemoryHandle(
203 std::move(mojo_handle), &handle, &memory_size, &read_only);
204 if (result != MOJO_RESULT_OK)
205 break;
206 auto discardable_shared_memory =
207 base::MakeUnique<base::DiscardableSharedMemory>(handle);
208 if (!discardable_shared_memory->Map(memory_size)) {
209 base::TerminateBecauseOutOfMemory(memory_size);
210 break;
211 }
212 *memory = std::move(discardable_shared_memory);
213 } while (false);
214 event->Signal();
215 }
216
217 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
218 DeletedInIOThread(int32_t id) {
219 if (!manager_)
220 return;
221 manager_->DeletedDiscardableSharedMemory(id);
222 }
92 223
93 ClientDiscardableSharedMemoryManager::ClientDiscardableSharedMemoryManager( 224 ClientDiscardableSharedMemoryManager::ClientDiscardableSharedMemoryManager(
94 Delegate* delegate) 225 mojom::DiscardableSharedMemoryManagerPtrInfo info,
95 : heap_(base::GetPageSize()), delegate_(delegate) { 226 base::SingleThreadTaskRunner* io_task_runner)
227 : heap_(base::GetPageSize()) {
96 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( 228 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
97 this, "ClientDiscardableSharedMemoryManager", 229 this, "ClientDiscardableSharedMemoryManager",
98 base::ThreadTaskRunnerHandle::Get()); 230 base::ThreadTaskRunnerHandle::Get());
231 manager_ = new ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy(
232 std::move(info), io_task_runner);
99 } 233 }
100 234
101 ClientDiscardableSharedMemoryManager::~ClientDiscardableSharedMemoryManager() { 235 ClientDiscardableSharedMemoryManager::~ClientDiscardableSharedMemoryManager() {
102 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( 236 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
103 this); 237 this);
104 // TODO(reveman): Determine if this DCHECK can be enabled. crbug.com/430533 238 // TODO(reveman): Determine if this DCHECK can be enabled. crbug.com/430533
105 // DCHECK_EQ(heap_.GetSize(), heap_.GetSizeOfFreeLists()); 239 // DCHECK_EQ(heap_.GetSize(), heap_.GetSizeOfFreeLists());
106 if (heap_.GetSize()) 240 if (heap_.GetSize())
107 MemoryUsageChanged(0, 0); 241 MemoryUsageChanged(0, 0);
108 } 242 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 heap_.ReleasePurgedMemory(); 308 heap_.ReleasePurgedMemory();
175 309
176 // Make sure crash keys are up to date in case allocation fails. 310 // Make sure crash keys are up to date in case allocation fails.
177 if (heap_.GetSize() != heap_size_prior_to_releasing_purged_memory) 311 if (heap_.GetSize() != heap_size_prior_to_releasing_purged_memory)
178 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); 312 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists());
179 313
180 size_t pages_to_allocate = 314 size_t pages_to_allocate =
181 std::max(kAllocationSize / base::GetPageSize(), pages); 315 std::max(kAllocationSize / base::GetPageSize(), pages);
182 size_t allocation_size_in_bytes = pages_to_allocate * base::GetPageSize(); 316 size_t allocation_size_in_bytes = pages_to_allocate * base::GetPageSize();
183 317
184 DiscardableSharedMemoryId new_id = 318 int32_t new_id = g_next_discardable_shared_memory_id.GetNext();
185 g_next_discardable_shared_memory_id.GetNext();
186 319
187 // Ask parent process to allocate a new discardable shared memory segment. 320 // Ask parent process to allocate a new discardable shared memory segment.
188 std::unique_ptr<base::DiscardableSharedMemory> shared_memory( 321 auto shared_memory =
189 AllocateLockedDiscardableSharedMemory(allocation_size_in_bytes, new_id)); 322 AllocateLockedDiscardableSharedMemory(allocation_size_in_bytes, new_id);
190 323
191 // Create span for allocated memory. 324 // Create span for allocated memory.
192 std::unique_ptr<DiscardableSharedMemoryHeap::Span> new_span( 325 std::unique_ptr<DiscardableSharedMemoryHeap::Span> new_span(heap_.Grow(
193 heap_.Grow(std::move(shared_memory), allocation_size_in_bytes, new_id, 326 std::move(shared_memory), allocation_size_in_bytes, new_id,
194 base::Bind(&SendDeletedDiscardableSharedMemoryMessage, 327 base::Bind(
195 delegate_, new_id))); 328 &ClientDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory,
329 base::Unretained(this), new_id)));
196 new_span->set_is_locked(true); 330 new_span->set_is_locked(true);
197 331
198 // Unlock and insert any left over memory into free lists. 332 // Unlock and insert any left over memory into free lists.
199 if (pages < pages_to_allocate) { 333 if (pages < pages_to_allocate) {
200 std::unique_ptr<DiscardableSharedMemoryHeap::Span> leftover = 334 std::unique_ptr<DiscardableSharedMemoryHeap::Span> leftover =
201 heap_.Split(new_span.get(), pages); 335 heap_.Split(new_span.get(), pages);
202 leftover->shared_memory()->Unlock( 336 leftover->shared_memory()->Unlock(
203 leftover->start() * base::GetPageSize() - 337 leftover->start() * base::GetPageSize() -
204 reinterpret_cast<size_t>(leftover->shared_memory()->memory()), 338 reinterpret_cast<size_t>(leftover->shared_memory()->memory()),
205 leftover->length() * base::GetPageSize()); 339 leftover->length() * base::GetPageSize());
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 DiscardableSharedMemoryHeap::Span* span, 451 DiscardableSharedMemoryHeap::Span* span,
318 const char* name, 452 const char* name,
319 base::trace_event::ProcessMemoryDump* pmd) const { 453 base::trace_event::ProcessMemoryDump* pmd) const {
320 base::AutoLock lock(lock_); 454 base::AutoLock lock(lock_);
321 return heap_.CreateMemoryAllocatorDump(span, name, pmd); 455 return heap_.CreateMemoryAllocatorDump(span, name, pmd);
322 } 456 }
323 457
324 std::unique_ptr<base::DiscardableSharedMemory> 458 std::unique_ptr<base::DiscardableSharedMemory>
325 ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( 459 ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
326 size_t size, 460 size_t size,
327 DiscardableSharedMemoryId id) { 461 int32_t id) {
328 TRACE_EVENT2("renderer", 462 TRACE_EVENT2("renderer",
329 "ClientDiscardableSharedMemoryManager::" 463 "ClientDiscardableSharedMemoryManager::"
330 "AllocateLockedDiscardableSharedMemory", 464 "AllocateLockedDiscardableSharedMemory",
331 "size", size, "id", id); 465 "size", size, "id", id);
466 return manager_->Allocate(size, id);
467 }
332 468
333 base::SharedMemoryHandle handle = base::SharedMemory::NULLHandle(); 469 void ClientDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory(
334 delegate_->AllocateLockedDiscardableSharedMemory(size, id, &handle); 470 int32_t id) {
335 std::unique_ptr<base::DiscardableSharedMemory> memory( 471 manager_->Deleted(id);
336 new base::DiscardableSharedMemory(handle));
337 if (!memory->Map(size))
338 base::TerminateBecauseOutOfMemory(size);
339 return memory;
340 } 472 }
341 473
342 void ClientDiscardableSharedMemoryManager::MemoryUsageChanged( 474 void ClientDiscardableSharedMemoryManager::MemoryUsageChanged(
343 size_t new_bytes_total, 475 size_t new_bytes_total,
344 size_t new_bytes_free) const { 476 size_t new_bytes_free) const {
345 static const char kDiscardableMemoryAllocatedKey[] = 477 static const char kDiscardableMemoryAllocatedKey[] =
346 "discardable-memory-allocated"; 478 "discardable-memory-allocated";
347 base::debug::SetCrashKeyValue(kDiscardableMemoryAllocatedKey, 479 base::debug::SetCrashKeyValue(kDiscardableMemoryAllocatedKey,
348 base::Uint64ToString(new_bytes_total)); 480 base::Uint64ToString(new_bytes_total));
349 481
350 static const char kDiscardableMemoryFreeKey[] = "discardable-memory-free"; 482 static const char kDiscardableMemoryFreeKey[] = "discardable-memory-free";
351 base::debug::SetCrashKeyValue(kDiscardableMemoryFreeKey, 483 base::debug::SetCrashKeyValue(kDiscardableMemoryFreeKey,
352 base::Uint64ToString(new_bytes_free)); 484 base::Uint64ToString(new_bytes_free));
353 } 485 }
354 486
355 } // namespace discardable_memory 487 } // namespace discardable_memory
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698