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

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: Update 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(
95 mojom::DiscardableSharedMemoryManagerPtrInfo info,
96 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
97 std::unique_ptr<base::DiscardableSharedMemory> Allocate(size_t size,
98 int32_t id);
99 void Deleted(int32_t id);
100
101 private:
102 friend class base::RefCountedThreadSafe<ThreadSafeManagerProxy>;
103
104 ~ThreadSafeManagerProxy() {}
105
106 void OnConnectionError();
107 void InitInIOThread(mojom::DiscardableSharedMemoryManagerPtrInfo info);
108 void AllocateInIOThread(
109 size_t size,
110 int32_t id,
111 std::unique_ptr<base::DiscardableSharedMemory>* memory,
112 base::WaitableEvent* event);
113 void OnAllocateCompletedInIOThread(
114 std::unique_ptr<base::DiscardableSharedMemory>* memory,
115 base::WaitableEvent* event,
116 mojo::ScopedSharedBufferHandle mojo_handle);
117 void DeletedInIOThread(int32_t id);
118
119 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
120 mojom::DiscardableSharedMemoryManagerPtr manager_;
121
122 DISALLOW_COPY_AND_ASSIGN(ThreadSafeManagerProxy);
123 };
124
125 ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
126 ThreadSafeManagerProxy(
127 mojom::DiscardableSharedMemoryManagerPtrInfo info,
128 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
129 : io_task_runner_(io_task_runner) {
130 io_task_runner_->PostTask(
131 FROM_HERE, base::Bind(&ClientDiscardableSharedMemoryManager::
132 ThreadSafeManagerProxy::InitInIOThread,
133 this, base::Passed(&info)));
89 } 134 }
90 135
91 } // namespace 136 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
137 OnConnectionError() {
138 manager_.reset();
139 }
140
141 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
142 InitInIOThread(mojom::DiscardableSharedMemoryManagerPtrInfo info) {
143 DCHECK(io_task_runner_->BelongsToCurrentThread());
144 manager_.Bind(std::move(info));
145 manager_.set_connection_error_handler(
146 base::Bind(&ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
147 OnConnectionError,
148 this));
149 }
150
151 std::unique_ptr<base::DiscardableSharedMemory>
152 ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::Allocate(
153 size_t size,
154 int32_t id) {
155 DCHECK(!io_task_runner_->BelongsToCurrentThread());
156 std::unique_ptr<base::DiscardableSharedMemory> memory;
157 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
158 base::WaitableEvent::InitialState::NOT_SIGNALED);
159 io_task_runner_->PostTask(
160 FROM_HERE, base::Bind(&ClientDiscardableSharedMemoryManager::
161 ThreadSafeManagerProxy::AllocateInIOThread,
162 this, size, id, &memory, &event));
163 // Waiting until IPC is finished in the IO thread.
164 event.Wait();
165 return memory;
166 }
167
168 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::Deleted(
169 int32_t id) {
170 DCHECK(!io_task_runner_->BelongsToCurrentThread());
171 io_task_runner_->PostTask(
172 FROM_HERE, base::Bind(&ClientDiscardableSharedMemoryManager::
173 ThreadSafeManagerProxy::DeletedInIOThread,
174 this, id));
175 }
176
177 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
178 AllocateInIOThread(size_t size,
179 int32_t id,
180 std::unique_ptr<base::DiscardableSharedMemory>* memory,
181 base::WaitableEvent* event) {
182 DCHECK(io_task_runner_->BelongsToCurrentThread());
183 if (!manager_)
184 return;
185 manager_->AllocateLockedDiscardableSharedMemory(
186 static_cast<uint32_t>(size), id,
187 base::Bind(&ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
188 OnAllocateCompletedInIOThread,
189 this, memory, event));
190 }
191
192 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
193 OnAllocateCompletedInIOThread(
194 std::unique_ptr<base::DiscardableSharedMemory>* memory,
195 base::WaitableEvent* event,
196 mojo::ScopedSharedBufferHandle mojo_handle) {
197 DCHECK(io_task_runner_->BelongsToCurrentThread());
198 do {
199 if (!mojo_handle.is_valid())
200 break;
201 auto handle = base::SharedMemory::NULLHandle();
202 size_t memory_size = 0;
203 bool read_only = false;
204 auto result = mojo::UnwrapSharedMemoryHandle(
205 std::move(mojo_handle), &handle, &memory_size, &read_only);
206 if (result != MOJO_RESULT_OK)
207 break;
208 auto discardable_shared_memory =
209 base::MakeUnique<base::DiscardableSharedMemory>(handle);
210 if (!discardable_shared_memory->Map(memory_size)) {
211 base::TerminateBecauseOutOfMemory(memory_size);
212 break;
213 }
214 *memory = std::move(discardable_shared_memory);
215 } while (false);
216 event->Signal();
217 }
218
219 void ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy::
220 DeletedInIOThread(int32_t id) {
221 if (!manager_)
222 return;
223 manager_->DeletedDiscardableSharedMemory(id);
224 }
92 225
93 ClientDiscardableSharedMemoryManager::ClientDiscardableSharedMemoryManager( 226 ClientDiscardableSharedMemoryManager::ClientDiscardableSharedMemoryManager(
94 Delegate* delegate) 227 mojom::DiscardableSharedMemoryManagerPtrInfo info,
95 : heap_(base::GetPageSize()), delegate_(delegate) { 228 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
229 : heap_(base::GetPageSize()) {
96 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( 230 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
97 this, "ClientDiscardableSharedMemoryManager", 231 this, "ClientDiscardableSharedMemoryManager",
98 base::ThreadTaskRunnerHandle::Get()); 232 base::ThreadTaskRunnerHandle::Get());
233 manager_ = new ClientDiscardableSharedMemoryManager::ThreadSafeManagerProxy(
234 std::move(info), io_task_runner);
99 } 235 }
100 236
101 ClientDiscardableSharedMemoryManager::~ClientDiscardableSharedMemoryManager() { 237 ClientDiscardableSharedMemoryManager::~ClientDiscardableSharedMemoryManager() {
102 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( 238 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
103 this); 239 this);
104 // TODO(reveman): Determine if this DCHECK can be enabled. crbug.com/430533 240 // TODO(reveman): Determine if this DCHECK can be enabled. crbug.com/430533
105 // DCHECK_EQ(heap_.GetSize(), heap_.GetSizeOfFreeLists()); 241 // DCHECK_EQ(heap_.GetSize(), heap_.GetSizeOfFreeLists());
106 if (heap_.GetSize()) 242 if (heap_.GetSize())
107 MemoryUsageChanged(0, 0); 243 MemoryUsageChanged(0, 0);
108 } 244 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 heap_.ReleasePurgedMemory(); 310 heap_.ReleasePurgedMemory();
175 311
176 // Make sure crash keys are up to date in case allocation fails. 312 // Make sure crash keys are up to date in case allocation fails.
177 if (heap_.GetSize() != heap_size_prior_to_releasing_purged_memory) 313 if (heap_.GetSize() != heap_size_prior_to_releasing_purged_memory)
178 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); 314 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists());
179 315
180 size_t pages_to_allocate = 316 size_t pages_to_allocate =
181 std::max(kAllocationSize / base::GetPageSize(), pages); 317 std::max(kAllocationSize / base::GetPageSize(), pages);
182 size_t allocation_size_in_bytes = pages_to_allocate * base::GetPageSize(); 318 size_t allocation_size_in_bytes = pages_to_allocate * base::GetPageSize();
183 319
184 DiscardableSharedMemoryId new_id = 320 int32_t new_id = g_next_discardable_shared_memory_id.GetNext();
185 g_next_discardable_shared_memory_id.GetNext();
186 321
187 // Ask parent process to allocate a new discardable shared memory segment. 322 // Ask parent process to allocate a new discardable shared memory segment.
188 std::unique_ptr<base::DiscardableSharedMemory> shared_memory( 323 auto shared_memory =
189 AllocateLockedDiscardableSharedMemory(allocation_size_in_bytes, new_id)); 324 AllocateLockedDiscardableSharedMemory(allocation_size_in_bytes, new_id);
190 325
191 // Create span for allocated memory. 326 // Create span for allocated memory.
192 std::unique_ptr<DiscardableSharedMemoryHeap::Span> new_span( 327 std::unique_ptr<DiscardableSharedMemoryHeap::Span> new_span(heap_.Grow(
193 heap_.Grow(std::move(shared_memory), allocation_size_in_bytes, new_id, 328 std::move(shared_memory), allocation_size_in_bytes, new_id,
194 base::Bind(&SendDeletedDiscardableSharedMemoryMessage, 329 base::Bind(
195 delegate_, new_id))); 330 &ClientDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory,
331 base::Unretained(this), new_id)));
196 new_span->set_is_locked(true); 332 new_span->set_is_locked(true);
197 333
198 // Unlock and insert any left over memory into free lists. 334 // Unlock and insert any left over memory into free lists.
199 if (pages < pages_to_allocate) { 335 if (pages < pages_to_allocate) {
200 std::unique_ptr<DiscardableSharedMemoryHeap::Span> leftover = 336 std::unique_ptr<DiscardableSharedMemoryHeap::Span> leftover =
201 heap_.Split(new_span.get(), pages); 337 heap_.Split(new_span.get(), pages);
202 leftover->shared_memory()->Unlock( 338 leftover->shared_memory()->Unlock(
203 leftover->start() * base::GetPageSize() - 339 leftover->start() * base::GetPageSize() -
204 reinterpret_cast<size_t>(leftover->shared_memory()->memory()), 340 reinterpret_cast<size_t>(leftover->shared_memory()->memory()),
205 leftover->length() * base::GetPageSize()); 341 leftover->length() * base::GetPageSize());
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 DiscardableSharedMemoryHeap::Span* span, 453 DiscardableSharedMemoryHeap::Span* span,
318 const char* name, 454 const char* name,
319 base::trace_event::ProcessMemoryDump* pmd) const { 455 base::trace_event::ProcessMemoryDump* pmd) const {
320 base::AutoLock lock(lock_); 456 base::AutoLock lock(lock_);
321 return heap_.CreateMemoryAllocatorDump(span, name, pmd); 457 return heap_.CreateMemoryAllocatorDump(span, name, pmd);
322 } 458 }
323 459
324 std::unique_ptr<base::DiscardableSharedMemory> 460 std::unique_ptr<base::DiscardableSharedMemory>
325 ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( 461 ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
326 size_t size, 462 size_t size,
327 DiscardableSharedMemoryId id) { 463 int32_t id) {
328 TRACE_EVENT2("renderer", 464 TRACE_EVENT2("renderer",
329 "ClientDiscardableSharedMemoryManager::" 465 "ClientDiscardableSharedMemoryManager::"
330 "AllocateLockedDiscardableSharedMemory", 466 "AllocateLockedDiscardableSharedMemory",
331 "size", size, "id", id); 467 "size", size, "id", id);
468 return manager_->Allocate(size, id);
469 }
332 470
333 base::SharedMemoryHandle handle = base::SharedMemory::NULLHandle(); 471 void ClientDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory(
334 delegate_->AllocateLockedDiscardableSharedMemory(size, id, &handle); 472 int32_t id) {
335 std::unique_ptr<base::DiscardableSharedMemory> memory( 473 manager_->Deleted(id);
336 new base::DiscardableSharedMemory(handle));
337 if (!memory->Map(size))
338 base::TerminateBecauseOutOfMemory(size);
339 return memory;
340 } 474 }
341 475
342 void ClientDiscardableSharedMemoryManager::MemoryUsageChanged( 476 void ClientDiscardableSharedMemoryManager::MemoryUsageChanged(
343 size_t new_bytes_total, 477 size_t new_bytes_total,
344 size_t new_bytes_free) const { 478 size_t new_bytes_free) const {
345 static const char kDiscardableMemoryAllocatedKey[] = 479 static const char kDiscardableMemoryAllocatedKey[] =
346 "discardable-memory-allocated"; 480 "discardable-memory-allocated";
347 base::debug::SetCrashKeyValue(kDiscardableMemoryAllocatedKey, 481 base::debug::SetCrashKeyValue(kDiscardableMemoryAllocatedKey,
348 base::Uint64ToString(new_bytes_total)); 482 base::Uint64ToString(new_bytes_total));
349 483
350 static const char kDiscardableMemoryFreeKey[] = "discardable-memory-free"; 484 static const char kDiscardableMemoryFreeKey[] = "discardable-memory-free";
351 base::debug::SetCrashKeyValue(kDiscardableMemoryFreeKey, 485 base::debug::SetCrashKeyValue(kDiscardableMemoryFreeKey,
352 base::Uint64ToString(new_bytes_free)); 486 base::Uint64ToString(new_bytes_free));
353 } 487 }
354 488
355 } // namespace discardable_memory 489 } // namespace discardable_memory
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698