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

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 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/callback_helpers.h"
14 #include "base/debug/crash_logging.h" 15 #include "base/debug/crash_logging.h"
15 #include "base/macros.h" 16 #include "base/macros.h"
16 #include "base/memory/discardable_memory.h" 17 #include "base/memory/discardable_memory.h"
17 #include "base/memory/discardable_shared_memory.h" 18 #include "base/memory/discardable_shared_memory.h"
18 #include "base/memory/ptr_util.h" 19 #include "base/memory/ptr_util.h"
19 #include "base/metrics/histogram_macros.h" 20 #include "base/metrics/histogram_macros.h"
20 #include "base/process/memory.h" 21 #include "base/process/memory.h"
21 #include "base/process/process_metrics.h" 22 #include "base/process/process_metrics.h"
22 #include "base/strings/string_number_conversions.h" 23 #include "base/strings/string_number_conversions.h"
23 #include "base/strings/stringprintf.h" 24 #include "base/strings/stringprintf.h"
25 #include "base/synchronization/waitable_event.h"
24 #include "base/threading/thread_task_runner_handle.h" 26 #include "base/threading/thread_task_runner_handle.h"
25 #include "base/trace_event/memory_dump_manager.h" 27 #include "base/trace_event/memory_dump_manager.h"
26 #include "base/trace_event/trace_event.h" 28 #include "base/trace_event/trace_event.h"
29 #include "mojo/public/cpp/system/platform_handle.h"
27 30
28 namespace discardable_memory { 31 namespace discardable_memory {
29 namespace { 32 namespace {
30 33
31 // Default allocation size. 34 // Default allocation size.
32 const size_t kAllocationSize = 4 * 1024 * 1024; 35 const size_t kAllocationSize = 4 * 1024 * 1024;
33 36
34 // Global atomic to generate unique discardable shared memory IDs. 37 // Global atomic to generate unique discardable shared memory IDs.
35 base::StaticAtomicSequenceNumber g_next_discardable_shared_memory_id; 38 base::StaticAtomicSequenceNumber g_next_discardable_shared_memory_id;
36 39
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 } 78 }
76 79
77 private: 80 private:
78 ClientDiscardableSharedMemoryManager* const manager_; 81 ClientDiscardableSharedMemoryManager* const manager_;
79 std::unique_ptr<DiscardableSharedMemoryHeap::Span> span_; 82 std::unique_ptr<DiscardableSharedMemoryHeap::Span> span_;
80 bool is_locked_; 83 bool is_locked_;
81 84
82 DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryImpl); 85 DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryImpl);
83 }; 86 };
84 87
85 void SendDeletedDiscardableSharedMemoryMessage( 88 void OnManagerMojoConnectionError(
86 ClientDiscardableSharedMemoryManager::Delegate* delegate, 89 mojom::DiscardableSharedMemoryManagerPtr* manager_mojo) {
87 DiscardableSharedMemoryId id) { 90 manager_mojo->reset();
88 delegate->DeletedDiscardableSharedMemory(id); 91 }
92
93 void InitManagerMojoOnIO(mojom::DiscardableSharedMemoryManagerPtr* manager_mojo,
94 mojom::DiscardableSharedMemoryManagerPtrInfo info) {
95 manager_mojo->Bind(std::move(info));
96 manager_mojo->set_connection_error_handler(
97 base::Bind(&OnManagerMojoConnectionError, manager_mojo));
98 }
99
100 void DeletedDiscardableSharedMemoryOnIO(
101 mojom::DiscardableSharedMemoryManagerPtr* manager_mojo,
102 int32_t id) {
103 if (!manager_mojo->is_bound())
104 return;
105 (*manager_mojo)->DeletedDiscardableSharedMemory(id);
89 } 106 }
90 107
91 } // namespace 108 } // namespace
92 109
93 ClientDiscardableSharedMemoryManager::ClientDiscardableSharedMemoryManager( 110 ClientDiscardableSharedMemoryManager::ClientDiscardableSharedMemoryManager(
94 Delegate* delegate) 111 mojom::DiscardableSharedMemoryManagerPtr manager,
95 : heap_(base::GetPageSize()), delegate_(delegate) { 112 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
113 : io_task_runner_(std::move(io_task_runner)),
114 manager_mojo_(new mojom::DiscardableSharedMemoryManagerPtr),
115 heap_(new DiscardableSharedMemoryHeap(base::GetPageSize())) {
96 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( 116 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
97 this, "ClientDiscardableSharedMemoryManager", 117 this, "ClientDiscardableSharedMemoryManager",
98 base::ThreadTaskRunnerHandle::Get()); 118 base::ThreadTaskRunnerHandle::Get());
119 mojom::DiscardableSharedMemoryManagerPtrInfo info = manager.PassInterface();
120 io_task_runner_->PostTask(
121 FROM_HERE, base::Bind(&InitManagerMojoOnIO, manager_mojo_.get(),
122 base::Passed(&info)));
99 } 123 }
100 124
101 ClientDiscardableSharedMemoryManager::~ClientDiscardableSharedMemoryManager() { 125 ClientDiscardableSharedMemoryManager::~ClientDiscardableSharedMemoryManager() {
102 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( 126 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
103 this); 127 this);
104 // TODO(reveman): Determine if this DCHECK can be enabled. crbug.com/430533 128 // TODO(reveman): Determine if this DCHECK can be enabled. crbug.com/430533
105 // DCHECK_EQ(heap_.GetSize(), heap_.GetSizeOfFreeLists()); 129 // DCHECK_EQ(heap_->GetSize(), heap_->GetSizeOfFreeLists());
106 if (heap_.GetSize()) 130 if (heap_->GetSize())
107 MemoryUsageChanged(0, 0); 131 MemoryUsageChanged(0, 0);
132
133 // Releasing the |heap_| before posting a task for deleting |manager_mojo_|.
134 // It is because releasing |heap_| will invoke DeletedDiscardableSharedMemory
135 // which needs |manager_mojo_|.
136 heap_.reset();
137
138 // Delete the |manager_mojo_| on IO thread, so any pending tasks on IO thread
139 // will be executed before the |manager_mojo_| is deleted.
140 bool posted = io_task_runner_->DeleteSoon(FROM_HERE, manager_mojo_.release());
141 DCHECK(posted);
108 } 142 }
109 143
110 std::unique_ptr<base::DiscardableMemory> 144 std::unique_ptr<base::DiscardableMemory>
111 ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( 145 ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
112 size_t size) { 146 size_t size) {
113 base::AutoLock lock(lock_); 147 base::AutoLock lock(lock_);
114 148
115 DCHECK_NE(size, 0u); 149 DCHECK_NE(size, 0u);
116 150
117 auto size_in_kb = static_cast<base::HistogramBase::Sample>(size / 1024); 151 auto size_in_kb = static_cast<base::HistogramBase::Sample>(size / 1024);
(...skipping 13 matching lines...) Expand all
131 165
132 size_t slack = 0; 166 size_t slack = 0;
133 // When searching the free lists, allow a slack between required size and 167 // When searching the free lists, allow a slack between required size and
134 // free span size that is less or equal to kAllocationSize. This is to 168 // free span size that is less or equal to kAllocationSize. This is to
135 // avoid segments larger then kAllocationSize unless they are a perfect 169 // avoid segments larger then kAllocationSize unless they are a perfect
136 // fit. The result is that large allocations can be reused without reducing 170 // fit. The result is that large allocations can be reused without reducing
137 // the ability to discard memory. 171 // the ability to discard memory.
138 if (pages < allocation_pages) 172 if (pages < allocation_pages)
139 slack = allocation_pages - pages; 173 slack = allocation_pages - pages;
140 174
141 size_t heap_size_prior_to_releasing_purged_memory = heap_.GetSize(); 175 size_t heap_size_prior_to_releasing_purged_memory = heap_->GetSize();
142 for (;;) { 176 for (;;) {
143 // Search free lists for suitable span. 177 // Search free lists for suitable span.
144 std::unique_ptr<DiscardableSharedMemoryHeap::Span> free_span = 178 std::unique_ptr<DiscardableSharedMemoryHeap::Span> free_span =
145 heap_.SearchFreeLists(pages, slack); 179 heap_->SearchFreeLists(pages, slack);
146 if (!free_span.get()) 180 if (!free_span.get())
147 break; 181 break;
148 182
149 // Attempt to lock |free_span|. Delete span and search free lists again 183 // Attempt to lock |free_span|. Delete span and search free lists again
150 // if locking failed. 184 // if locking failed.
151 if (free_span->shared_memory()->Lock( 185 if (free_span->shared_memory()->Lock(
152 free_span->start() * base::GetPageSize() - 186 free_span->start() * base::GetPageSize() -
153 reinterpret_cast<size_t>(free_span->shared_memory()->memory()), 187 reinterpret_cast<size_t>(free_span->shared_memory()->memory()),
154 free_span->length() * base::GetPageSize()) == 188 free_span->length() * base::GetPageSize()) ==
155 base::DiscardableSharedMemory::FAILED) { 189 base::DiscardableSharedMemory::FAILED) {
156 DCHECK(!free_span->shared_memory()->IsMemoryResident()); 190 DCHECK(!free_span->shared_memory()->IsMemoryResident());
157 // We have to release purged memory before |free_span| can be destroyed. 191 // We have to release purged memory before |free_span| can be destroyed.
158 heap_.ReleasePurgedMemory(); 192 heap_->ReleasePurgedMemory();
159 DCHECK(!free_span->shared_memory()); 193 DCHECK(!free_span->shared_memory());
160 continue; 194 continue;
161 } 195 }
162 196
163 free_span->set_is_locked(true); 197 free_span->set_is_locked(true);
164 198
165 // Memory usage is guaranteed to have changed after having removed 199 // Memory usage is guaranteed to have changed after having removed
166 // at least one span from the free lists. 200 // at least one span from the free lists.
167 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); 201 MemoryUsageChanged(heap_->GetSize(), heap_->GetSizeOfFreeLists());
168 202
169 return base::MakeUnique<DiscardableMemoryImpl>(this, std::move(free_span)); 203 return base::MakeUnique<DiscardableMemoryImpl>(this, std::move(free_span));
170 } 204 }
171 205
172 // Release purged memory to free up the address space before we attempt to 206 // Release purged memory to free up the address space before we attempt to
173 // allocate more memory. 207 // allocate more memory.
174 heap_.ReleasePurgedMemory(); 208 heap_->ReleasePurgedMemory();
175 209
176 // Make sure crash keys are up to date in case allocation fails. 210 // Make sure crash keys are up to date in case allocation fails.
177 if (heap_.GetSize() != heap_size_prior_to_releasing_purged_memory) 211 if (heap_->GetSize() != heap_size_prior_to_releasing_purged_memory)
178 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); 212 MemoryUsageChanged(heap_->GetSize(), heap_->GetSizeOfFreeLists());
179 213
180 size_t pages_to_allocate = 214 size_t pages_to_allocate =
181 std::max(kAllocationSize / base::GetPageSize(), pages); 215 std::max(kAllocationSize / base::GetPageSize(), pages);
182 size_t allocation_size_in_bytes = pages_to_allocate * base::GetPageSize(); 216 size_t allocation_size_in_bytes = pages_to_allocate * base::GetPageSize();
183 217
184 DiscardableSharedMemoryId new_id = 218 int32_t new_id = g_next_discardable_shared_memory_id.GetNext();
185 g_next_discardable_shared_memory_id.GetNext();
186 219
187 // Ask parent process to allocate a new discardable shared memory segment. 220 // Ask parent process to allocate a new discardable shared memory segment.
188 std::unique_ptr<base::DiscardableSharedMemory> shared_memory( 221 std::unique_ptr<base::DiscardableSharedMemory> shared_memory =
189 AllocateLockedDiscardableSharedMemory(allocation_size_in_bytes, new_id)); 222 AllocateLockedDiscardableSharedMemory(allocation_size_in_bytes, new_id);
190 223
191 // Create span for allocated memory. 224 // Create span for allocated memory.
192 std::unique_ptr<DiscardableSharedMemoryHeap::Span> new_span( 225 std::unique_ptr<DiscardableSharedMemoryHeap::Span> new_span(heap_->Grow(
193 heap_.Grow(std::move(shared_memory), allocation_size_in_bytes, new_id, 226 std::move(shared_memory), allocation_size_in_bytes, new_id,
194 base::Bind(&SendDeletedDiscardableSharedMemoryMessage, 227 base::Bind(
195 delegate_, new_id))); 228 &ClientDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory,
229 base::Unretained(this), new_id)));
196 new_span->set_is_locked(true); 230 new_span->set_is_locked(true);
197 231
198 // Unlock and insert any left over memory into free lists. 232 // Unlock and insert any left over memory into free lists.
199 if (pages < pages_to_allocate) { 233 if (pages < pages_to_allocate) {
200 std::unique_ptr<DiscardableSharedMemoryHeap::Span> leftover = 234 std::unique_ptr<DiscardableSharedMemoryHeap::Span> leftover =
201 heap_.Split(new_span.get(), pages); 235 heap_->Split(new_span.get(), pages);
202 leftover->shared_memory()->Unlock( 236 leftover->shared_memory()->Unlock(
203 leftover->start() * base::GetPageSize() - 237 leftover->start() * base::GetPageSize() -
204 reinterpret_cast<size_t>(leftover->shared_memory()->memory()), 238 reinterpret_cast<size_t>(leftover->shared_memory()->memory()),
205 leftover->length() * base::GetPageSize()); 239 leftover->length() * base::GetPageSize());
206 leftover->set_is_locked(false); 240 leftover->set_is_locked(false);
207 heap_.MergeIntoFreeLists(std::move(leftover)); 241 heap_->MergeIntoFreeLists(std::move(leftover));
208 } 242 }
209 243
210 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); 244 MemoryUsageChanged(heap_->GetSize(), heap_->GetSizeOfFreeLists());
211 245
212 return base::MakeUnique<DiscardableMemoryImpl>(this, std::move(new_span)); 246 return base::MakeUnique<DiscardableMemoryImpl>(this, std::move(new_span));
213 } 247 }
214 248
215 bool ClientDiscardableSharedMemoryManager::OnMemoryDump( 249 bool ClientDiscardableSharedMemoryManager::OnMemoryDump(
216 const base::trace_event::MemoryDumpArgs& args, 250 const base::trace_event::MemoryDumpArgs& args,
217 base::trace_event::ProcessMemoryDump* pmd) { 251 base::trace_event::ProcessMemoryDump* pmd) {
218 base::AutoLock lock(lock_); 252 base::AutoLock lock(lock_);
219 if (args.level_of_detail == 253 if (args.level_of_detail ==
220 base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND) { 254 base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND) {
221 base::trace_event::MemoryAllocatorDump* total_dump = 255 base::trace_event::MemoryAllocatorDump* total_dump =
222 pmd->CreateAllocatorDump( 256 pmd->CreateAllocatorDump(
223 base::StringPrintf("discardable/child_0x%" PRIXPTR, 257 base::StringPrintf("discardable/child_0x%" PRIXPTR,
224 reinterpret_cast<uintptr_t>(this))); 258 reinterpret_cast<uintptr_t>(this)));
225 const size_t total_size = heap_.GetSize(); 259 const size_t total_size = heap_->GetSize();
226 const size_t freelist_size = heap_.GetSizeOfFreeLists(); 260 const size_t freelist_size = heap_->GetSizeOfFreeLists();
227 total_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, 261 total_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
228 base::trace_event::MemoryAllocatorDump::kUnitsBytes, 262 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
229 total_size - freelist_size); 263 total_size - freelist_size);
230 total_dump->AddScalar("freelist_size", 264 total_dump->AddScalar("freelist_size",
231 base::trace_event::MemoryAllocatorDump::kUnitsBytes, 265 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
232 freelist_size); 266 freelist_size);
233 return true; 267 return true;
234 } 268 }
235 269
236 return heap_.OnMemoryDump(pmd); 270 return heap_->OnMemoryDump(pmd);
237 } 271 }
238 272
239 ClientDiscardableSharedMemoryManager::Statistics 273 ClientDiscardableSharedMemoryManager::Statistics
240 ClientDiscardableSharedMemoryManager::GetStatistics() const { 274 ClientDiscardableSharedMemoryManager::GetStatistics() const {
241 base::AutoLock lock(lock_); 275 base::AutoLock lock(lock_);
242 Statistics stats; 276 Statistics stats;
243 stats.total_size = heap_.GetSize(); 277 stats.total_size = heap_->GetSize();
244 stats.freelist_size = heap_.GetSizeOfFreeLists(); 278 stats.freelist_size = heap_->GetSizeOfFreeLists();
245 return stats; 279 return stats;
246 } 280 }
247 281
248 void ClientDiscardableSharedMemoryManager::ReleaseFreeMemory() { 282 void ClientDiscardableSharedMemoryManager::ReleaseFreeMemory() {
249 base::AutoLock lock(lock_); 283 base::AutoLock lock(lock_);
250 284
251 size_t heap_size_prior_to_releasing_memory = heap_.GetSize(); 285 size_t heap_size_prior_to_releasing_memory = heap_->GetSize();
252 286
253 // Release both purged and free memory. 287 // Release both purged and free memory.
254 heap_.ReleasePurgedMemory(); 288 heap_->ReleasePurgedMemory();
255 heap_.ReleaseFreeMemory(); 289 heap_->ReleaseFreeMemory();
256 290
257 if (heap_.GetSize() != heap_size_prior_to_releasing_memory) 291 if (heap_->GetSize() != heap_size_prior_to_releasing_memory)
258 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); 292 MemoryUsageChanged(heap_->GetSize(), heap_->GetSizeOfFreeLists());
259 } 293 }
260 294
261 bool ClientDiscardableSharedMemoryManager::LockSpan( 295 bool ClientDiscardableSharedMemoryManager::LockSpan(
262 DiscardableSharedMemoryHeap::Span* span) { 296 DiscardableSharedMemoryHeap::Span* span) {
263 base::AutoLock lock(lock_); 297 base::AutoLock lock(lock_);
264 298
265 if (!span->shared_memory()) 299 if (!span->shared_memory())
266 return false; 300 return false;
267 301
268 size_t offset = span->start() * base::GetPageSize() - 302 size_t offset = span->start() * base::GetPageSize() -
(...skipping 30 matching lines...) Expand all
299 } 333 }
300 334
301 void ClientDiscardableSharedMemoryManager::ReleaseSpan( 335 void ClientDiscardableSharedMemoryManager::ReleaseSpan(
302 std::unique_ptr<DiscardableSharedMemoryHeap::Span> span) { 336 std::unique_ptr<DiscardableSharedMemoryHeap::Span> span) {
303 base::AutoLock lock(lock_); 337 base::AutoLock lock(lock_);
304 338
305 // Delete span instead of merging it into free lists if memory is gone. 339 // Delete span instead of merging it into free lists if memory is gone.
306 if (!span->shared_memory()) 340 if (!span->shared_memory())
307 return; 341 return;
308 342
309 heap_.MergeIntoFreeLists(std::move(span)); 343 heap_->MergeIntoFreeLists(std::move(span));
310 344
311 // Bytes of free memory changed. 345 // Bytes of free memory changed.
312 MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists()); 346 MemoryUsageChanged(heap_->GetSize(), heap_->GetSizeOfFreeLists());
313 } 347 }
314 348
315 base::trace_event::MemoryAllocatorDump* 349 base::trace_event::MemoryAllocatorDump*
316 ClientDiscardableSharedMemoryManager::CreateMemoryAllocatorDump( 350 ClientDiscardableSharedMemoryManager::CreateMemoryAllocatorDump(
317 DiscardableSharedMemoryHeap::Span* span, 351 DiscardableSharedMemoryHeap::Span* span,
318 const char* name, 352 const char* name,
319 base::trace_event::ProcessMemoryDump* pmd) const { 353 base::trace_event::ProcessMemoryDump* pmd) const {
320 base::AutoLock lock(lock_); 354 base::AutoLock lock(lock_);
321 return heap_.CreateMemoryAllocatorDump(span, name, pmd); 355 return heap_->CreateMemoryAllocatorDump(span, name, pmd);
322 } 356 }
323 357
324 std::unique_ptr<base::DiscardableSharedMemory> 358 std::unique_ptr<base::DiscardableSharedMemory>
325 ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( 359 ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
326 size_t size, 360 size_t size,
327 DiscardableSharedMemoryId id) { 361 int32_t id) {
328 TRACE_EVENT2("renderer", 362 TRACE_EVENT2("renderer",
329 "ClientDiscardableSharedMemoryManager::" 363 "ClientDiscardableSharedMemoryManager::"
330 "AllocateLockedDiscardableSharedMemory", 364 "AllocateLockedDiscardableSharedMemory",
331 "size", size, "id", id); 365 "size", size, "id", id);
332 366 std::unique_ptr<base::DiscardableSharedMemory> memory;
333 base::SharedMemoryHandle handle = base::SharedMemory::NULLHandle(); 367 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
334 delegate_->AllocateLockedDiscardableSharedMemory(size, id, &handle); 368 base::WaitableEvent::InitialState::NOT_SIGNALED);
335 std::unique_ptr<base::DiscardableSharedMemory> memory( 369 io_task_runner_->PostTask(
336 new base::DiscardableSharedMemory(handle)); 370 FROM_HERE, base::Bind(&ClientDiscardableSharedMemoryManager::AllocateOnIO,
337 if (!memory->Map(size)) 371 base::Unretained(this), size, id, &memory, &event));
338 base::TerminateBecauseOutOfMemory(size); 372 // Waiting until IPC has finished on the IO thread.
373 event.Wait();
339 return memory; 374 return memory;
340 } 375 }
341 376
377 void ClientDiscardableSharedMemoryManager::AllocateOnIO(
378 size_t size,
379 int32_t id,
380 std::unique_ptr<base::DiscardableSharedMemory>* memory,
381 base::WaitableEvent* event) {
382 if (!manager_mojo_->is_bound())
383 return;
384 (*manager_mojo_)
385 ->AllocateLockedDiscardableSharedMemory(
386 static_cast<uint32_t>(size), id,
387 base::Bind(
388 &ClientDiscardableSharedMemoryManager::AllocateCompletedOnIO,
389 base::Unretained(this), memory, event));
390 }
391
392 void ClientDiscardableSharedMemoryManager::AllocateCompletedOnIO(
393 std::unique_ptr<base::DiscardableSharedMemory>* memory,
394 base::WaitableEvent* event,
395 mojo::ScopedSharedBufferHandle mojo_handle) {
396 base::ScopedClosureRunner event_signal_runner(
397 base::Bind(&base::WaitableEvent::Signal, base::Unretained(event)));
398
399 if (!mojo_handle.is_valid())
400 return;
401 base::SharedMemoryHandle handle = base::SharedMemory::NULLHandle();
402 size_t memory_size = 0;
403 bool read_only = false;
404 auto result = mojo::UnwrapSharedMemoryHandle(std::move(mojo_handle), &handle,
405 &memory_size, &read_only);
406 if (result != MOJO_RESULT_OK)
407 return;
408 auto discardable_shared_memory =
409 base::MakeUnique<base::DiscardableSharedMemory>(handle);
410 if (!discardable_shared_memory->Map(memory_size))
411 base::TerminateBecauseOutOfMemory(memory_size);
412 *memory = std::move(discardable_shared_memory);
413 }
414
415 void ClientDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory(
416 int32_t id) {
417 io_task_runner_->PostTask(
418 FROM_HERE,
419 base::Bind(&DeletedDiscardableSharedMemoryOnIO, manager_mojo_.get(), id));
420 }
421
342 void ClientDiscardableSharedMemoryManager::MemoryUsageChanged( 422 void ClientDiscardableSharedMemoryManager::MemoryUsageChanged(
343 size_t new_bytes_total, 423 size_t new_bytes_total,
344 size_t new_bytes_free) const { 424 size_t new_bytes_free) const {
345 static const char kDiscardableMemoryAllocatedKey[] = 425 static const char kDiscardableMemoryAllocatedKey[] =
346 "discardable-memory-allocated"; 426 "discardable-memory-allocated";
347 base::debug::SetCrashKeyValue(kDiscardableMemoryAllocatedKey, 427 base::debug::SetCrashKeyValue(kDiscardableMemoryAllocatedKey,
348 base::Uint64ToString(new_bytes_total)); 428 base::Uint64ToString(new_bytes_total));
349 429
350 static const char kDiscardableMemoryFreeKey[] = "discardable-memory-free"; 430 static const char kDiscardableMemoryFreeKey[] = "discardable-memory-free";
351 base::debug::SetCrashKeyValue(kDiscardableMemoryFreeKey, 431 base::debug::SetCrashKeyValue(kDiscardableMemoryFreeKey,
352 base::Uint64ToString(new_bytes_free)); 432 base::Uint64ToString(new_bytes_free));
353 } 433 }
354 434
355 } // namespace discardable_memory 435 } // namespace discardable_memory
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698