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

Side by Side Diff: components/discardable_memory/service/discardable_shared_memory_manager.cc

Issue 2485623002: discardable_memory: Using mojo IPC to replace Chrome IPC (Closed)
Patch Set: Fix build bots. 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/service/discardable_shared_memory_manage r.h" 5 #include "components/discardable_memory/service/discardable_shared_memory_manage r.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/atomic_sequence_num.h" 10 #include "base/atomic_sequence_num.h"
(...skipping 11 matching lines...) Expand all
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/sys_info.h" 24 #include "base/sys_info.h"
25 #include "base/threading/thread_task_runner_handle.h" 25 #include "base/threading/thread_task_runner_handle.h"
26 #include "base/trace_event/memory_allocator_dump.h" 26 #include "base/trace_event/memory_allocator_dump.h"
27 #include "base/trace_event/memory_dump_manager.h" 27 #include "base/trace_event/memory_dump_manager.h"
28 #include "base/trace_event/process_memory_dump.h" 28 #include "base/trace_event/process_memory_dump.h"
29 #include "base/trace_event/trace_event.h" 29 #include "base/trace_event/trace_event.h"
30 #include "build/build_config.h" 30 #include "build/build_config.h"
31 #include "components/discardable_memory/common/discardable_shared_memory_heap.h" 31 #include "components/discardable_memory/common/discardable_shared_memory_heap.h"
32 #include "mojo/public/cpp/bindings/strong_binding.h"
33 #include "mojo/public/cpp/system/platform_handle.h"
32 34
33 #if defined(OS_LINUX) 35 #if defined(OS_LINUX)
34 #include "base/files/file_path.h" 36 #include "base/files/file_path.h"
35 #include "base/files/file_util.h" 37 #include "base/files/file_util.h"
36 #include "base/metrics/histogram_macros.h" 38 #include "base/metrics/histogram_macros.h"
37 #endif 39 #endif
38 40
39 namespace discardable_memory { 41 namespace discardable_memory {
40 namespace { 42 namespace {
41 43
42 const char kSingleProcess[] = "single-process"; 44 const char kSingleProcess[] = "single-process";
43 45
44 const int kInvalidUniqueClientID = -1; 46 const int kInvalidUniqueClientID = -1;
45 47
46 const uint64_t kBrowserTracingProcessId = std::numeric_limits<uint64_t>::max(); 48 const uint64_t kBrowserTracingProcessId = std::numeric_limits<uint64_t>::max();
47 49
48 uint64_t ClientProcessUniqueIdToTracingProcessId(int client_id) { 50 uint64_t ClientProcessUniqueIdToTracingProcessId(int client_id) {
49 // TODO(penghuang): Move this function to right place. 51 // TODO(penghuang): Move this function to right place.
50 // https://crbug.com/661257 52 // https://crbug.com/661257
51 if (base::CommandLine::ForCurrentProcess()->HasSwitch(kSingleProcess)) 53 if (base::CommandLine::ForCurrentProcess()->HasSwitch(kSingleProcess))
52 return kBrowserTracingProcessId; 54 return kBrowserTracingProcessId;
53 // The hash value is incremented so that the tracing id is never equal to 55 // The hash value is incremented so that the tracing id is never equal to
54 // MemoryDumpManager::kInvalidTracingProcessId. 56 // MemoryDumpManager::kInvalidTracingProcessId.
55 return static_cast<uint64_t>(base::Hash( 57 return static_cast<uint64_t>(base::Hash(
56 reinterpret_cast<const char*>(&client_id), sizeof(client_id))) + 58 reinterpret_cast<const char*>(&client_id), sizeof(client_id))) +
57 1; 59 1;
58 } 60 }
59 61
62 class DiscardableSharedMemoryManagerProxy
reveman 2016/11/23 17:07:44 Please add a comment above this class describing w
Peng 2016/11/24 15:04:37 How about MojoDiscardableSharedMemoryManagerImpl?
63 : public mojom::DiscardableSharedMemoryManager {
64 public:
65 DiscardableSharedMemoryManagerProxy(
66 int32_t client_id,
67 ::discardable_memory::DiscardableSharedMemoryManager* manager)
68 : client_id_(client_id), manager_(manager) {}
69
70 ~DiscardableSharedMemoryManagerProxy() override {
71 manager_->ClientRemoved(client_id_);
72 }
73
74 // mojom::DiscardableSharedMemoryManager overrides:
75 void AllocateLockedDiscardableSharedMemory(
76 uint32_t size,
77 int32_t id,
78 const AllocateLockedDiscardableSharedMemoryCallback& callback) override {
79 base::SharedMemoryHandle handle;
80 manager_->AllocateLockedDiscardableSharedMemoryForClient(client_id_, size,
81 id, &handle);
82 mojo::ScopedSharedBufferHandle memory;
83 if (handle != base::SharedMemory::NULLHandle()) {
dcheng 2016/11/25 00:07:08 Is it necessary to check this condition? I would e
Peng 2016/11/25 16:41:53 Done.
84 memory =
85 mojo::WrapSharedMemoryHandle(handle, size, false /* ready_only */);
86 }
87 return callback.Run(std::move(memory));
88 }
89
90 void DeletedDiscardableSharedMemory(int32_t id) override {
91 manager_->ClientDeletedDiscardableSharedMemory(id, client_id_);
92 }
93
94 private:
95 const int32_t client_id_;
96 ::discardable_memory::DiscardableSharedMemoryManager* const manager_;
97
98 DISALLOW_COPY_AND_ASSIGN(DiscardableSharedMemoryManagerProxy);
99 };
100
60 class DiscardableMemoryImpl : public base::DiscardableMemory { 101 class DiscardableMemoryImpl : public base::DiscardableMemory {
61 public: 102 public:
62 DiscardableMemoryImpl( 103 DiscardableMemoryImpl(
63 std::unique_ptr<base::DiscardableSharedMemory> shared_memory, 104 std::unique_ptr<base::DiscardableSharedMemory> shared_memory,
64 const base::Closure& deleted_callback) 105 const base::Closure& deleted_callback)
65 : shared_memory_(std::move(shared_memory)), 106 : shared_memory_(std::move(shared_memory)),
66 deleted_callback_(deleted_callback), 107 deleted_callback_(deleted_callback),
67 is_locked_(true) {} 108 is_locked_(true) {}
68 109
69 ~DiscardableMemoryImpl() override { 110 ~DiscardableMemoryImpl() override {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 214
174 } // namespace 215 } // namespace
175 216
176 DiscardableSharedMemoryManager::MemorySegment::MemorySegment( 217 DiscardableSharedMemoryManager::MemorySegment::MemorySegment(
177 std::unique_ptr<base::DiscardableSharedMemory> memory) 218 std::unique_ptr<base::DiscardableSharedMemory> memory)
178 : memory_(std::move(memory)) {} 219 : memory_(std::move(memory)) {}
179 220
180 DiscardableSharedMemoryManager::MemorySegment::~MemorySegment() {} 221 DiscardableSharedMemoryManager::MemorySegment::~MemorySegment() {}
181 222
182 DiscardableSharedMemoryManager::DiscardableSharedMemoryManager() 223 DiscardableSharedMemoryManager::DiscardableSharedMemoryManager()
183 : default_memory_limit_(GetDefaultMemoryLimit()), 224 : last_client_id_(0),
225 default_memory_limit_(GetDefaultMemoryLimit()),
184 memory_limit_(default_memory_limit_), 226 memory_limit_(default_memory_limit_),
185 bytes_allocated_(0), 227 bytes_allocated_(0),
186 memory_pressure_listener_(new base::MemoryPressureListener( 228 memory_pressure_listener_(new base::MemoryPressureListener(
187 base::Bind(&DiscardableSharedMemoryManager::OnMemoryPressure, 229 base::Bind(&DiscardableSharedMemoryManager::OnMemoryPressure,
188 base::Unretained(this)))), 230 base::Unretained(this)))),
189 // Current thread might not have a task runner in tests. 231 // Current thread might not have a task runner in tests.
190 enforce_memory_policy_task_runner_(base::ThreadTaskRunnerHandle::Get()), 232 enforce_memory_policy_task_runner_(base::ThreadTaskRunnerHandle::Get()),
191 enforce_memory_policy_pending_(false), 233 enforce_memory_policy_pending_(false),
192 weak_ptr_factory_(this) { 234 weak_ptr_factory_(this) {
193 DCHECK_NE(memory_limit_, 0u); 235 DCHECK_NE(memory_limit_, 0u);
194 enforce_memory_policy_callback_ = 236 enforce_memory_policy_callback_ =
195 base::Bind(&DiscardableSharedMemoryManager::EnforceMemoryPolicy, 237 base::Bind(&DiscardableSharedMemoryManager::EnforceMemoryPolicy,
196 weak_ptr_factory_.GetWeakPtr()); 238 weak_ptr_factory_.GetWeakPtr());
197 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( 239 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
198 this, "DiscardableSharedMemoryManager", 240 this, "DiscardableSharedMemoryManager",
199 base::ThreadTaskRunnerHandle::Get()); 241 base::ThreadTaskRunnerHandle::Get());
200 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); 242 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
201 } 243 }
202 244
203 DiscardableSharedMemoryManager::~DiscardableSharedMemoryManager() { 245 DiscardableSharedMemoryManager::~DiscardableSharedMemoryManager() {
204 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( 246 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
205 this); 247 this);
206 } 248 }
207 249
250 // static
251 DiscardableSharedMemoryManager*
252 DiscardableSharedMemoryManager::CreateInstance() {
253 DCHECK(g_discardable_shared_memory_manager == nullptr);
reveman 2016/11/23 17:07:44 nit: DCHECK(!g_discardable_shared_memory_manager)
Peng 2016/11/24 15:04:37 It doesn't work. Because base::LazyInstance only o
254 return g_discardable_shared_memory_manager.Pointer();
255 }
256
257 // static
208 DiscardableSharedMemoryManager* DiscardableSharedMemoryManager::current() { 258 DiscardableSharedMemoryManager* DiscardableSharedMemoryManager::current() {
259 DCHECK(!(g_discardable_shared_memory_manager == nullptr));
reveman 2016/11/23 17:07:44 nit: DCHECK(g_discardable_shared_memory_manager)
Peng 2016/11/24 15:04:37 It doesn't work. Because base::LazyInstance only o
209 return g_discardable_shared_memory_manager.Pointer(); 260 return g_discardable_shared_memory_manager.Pointer();
210 } 261 }
211 262
263 // static
264 void DiscardableSharedMemoryManager::Bind(
265 mojom::DiscardableSharedMemoryManagerRequest request) {
266 auto* manager = current();
267 mojo::MakeStrongBinding(base::MakeUnique<DiscardableSharedMemoryManagerProxy>(
268 ++manager->last_client_id_, manager),
269 std::move(request));
270 }
271
212 std::unique_ptr<base::DiscardableMemory> 272 std::unique_ptr<base::DiscardableMemory>
213 DiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(size_t size) { 273 DiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(size_t size) {
214 DCHECK_NE(size, 0u); 274 DCHECK_NE(size, 0u);
215 275
216 DiscardableSharedMemoryId new_id = 276 int32_t new_id = g_next_discardable_shared_memory_id.GetNext();
217 g_next_discardable_shared_memory_id.GetNext();
218 base::ProcessHandle current_process_handle = base::GetCurrentProcessHandle();
219 277
220 // Note: Use DiscardableSharedMemoryHeap for in-process allocation 278 // Note: Use DiscardableSharedMemoryHeap for in-process allocation
221 // of discardable memory if the cost of each allocation is too high. 279 // of discardable memory if the cost of each allocation is too high.
222 base::SharedMemoryHandle handle; 280 base::SharedMemoryHandle handle;
223 AllocateLockedDiscardableSharedMemory( 281 AllocateLockedDiscardableSharedMemory(kInvalidUniqueClientID, size, new_id,
224 current_process_handle, kInvalidUniqueClientID, size, new_id, &handle); 282 &handle);
225 std::unique_ptr<base::DiscardableSharedMemory> memory( 283 std::unique_ptr<base::DiscardableSharedMemory> memory(
226 new base::DiscardableSharedMemory(handle)); 284 new base::DiscardableSharedMemory(handle));
227 if (!memory->Map(size)) 285 if (!memory->Map(size))
228 base::TerminateBecauseOutOfMemory(size); 286 base::TerminateBecauseOutOfMemory(size);
229 // Close file descriptor to avoid running out. 287 // Close file descriptor to avoid running out.
230 memory->Close(); 288 memory->Close();
231 return base::MakeUnique<DiscardableMemoryImpl>( 289 return base::MakeUnique<DiscardableMemoryImpl>(
232 std::move(memory), 290 std::move(memory),
233 base::Bind( 291 base::Bind(
234 &DiscardableSharedMemoryManager::DeletedDiscardableSharedMemory, 292 &DiscardableSharedMemoryManager::DeletedDiscardableSharedMemory,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 static_cast<uint64_t>(resident_size)); 359 static_cast<uint64_t>(resident_size));
302 } 360 }
303 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) 361 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED)
304 } 362 }
305 } 363 }
306 return true; 364 return true;
307 } 365 }
308 366
309 void DiscardableSharedMemoryManager:: 367 void DiscardableSharedMemoryManager::
310 AllocateLockedDiscardableSharedMemoryForClient( 368 AllocateLockedDiscardableSharedMemoryForClient(
311 base::ProcessHandle process_handle,
312 int client_id, 369 int client_id,
313 size_t size, 370 size_t size,
314 DiscardableSharedMemoryId id, 371 int32_t id,
315 base::SharedMemoryHandle* shared_memory_handle) { 372 base::SharedMemoryHandle* shared_memory_handle) {
316 AllocateLockedDiscardableSharedMemory(process_handle, client_id, size, id, 373 AllocateLockedDiscardableSharedMemory(client_id, size, id,
317 shared_memory_handle); 374 shared_memory_handle);
318 } 375 }
319 376
320 void DiscardableSharedMemoryManager::ClientDeletedDiscardableSharedMemory( 377 void DiscardableSharedMemoryManager::ClientDeletedDiscardableSharedMemory(
321 DiscardableSharedMemoryId id, 378 int32_t id,
322 int client_id) { 379 int client_id) {
323 DeletedDiscardableSharedMemory(id, client_id); 380 DeletedDiscardableSharedMemory(id, client_id);
324 } 381 }
325 382
326 void DiscardableSharedMemoryManager::ClientRemoved(int client_id) { 383 void DiscardableSharedMemoryManager::ClientRemoved(int client_id) {
327 base::AutoLock lock(lock_); 384 base::AutoLock lock(lock_);
328 385
329 auto it = clients_.find(client_id); 386 auto it = clients_.find(client_id);
330 if (it == clients_.end()) 387 if (it == clients_.end())
331 return; 388 return;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 case base::MemoryState::SUSPENDED: 430 case base::MemoryState::SUSPENDED:
374 // Note that SUSPENDED never occurs in the main browser process so far. 431 // Note that SUSPENDED never occurs in the main browser process so far.
375 // Fall through. 432 // Fall through.
376 case base::MemoryState::UNKNOWN: 433 case base::MemoryState::UNKNOWN:
377 NOTREACHED(); 434 NOTREACHED();
378 break; 435 break;
379 } 436 }
380 } 437 }
381 438
382 void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( 439 void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
383 base::ProcessHandle process_handle,
384 int client_id, 440 int client_id,
385 size_t size, 441 size_t size,
386 DiscardableSharedMemoryId id, 442 int32_t id,
387 base::SharedMemoryHandle* shared_memory_handle) { 443 base::SharedMemoryHandle* shared_memory_handle) {
388 base::AutoLock lock(lock_); 444 base::AutoLock lock(lock_);
389 445
390 // Make sure |id| is not already in use. 446 // Make sure |id| is not already in use.
391 MemorySegmentMap& client_segments = clients_[client_id]; 447 MemorySegmentMap& client_segments = clients_[client_id];
392 if (client_segments.find(id) != client_segments.end()) { 448 if (client_segments.find(id) != client_segments.end()) {
393 LOG(ERROR) << "Invalid discardable shared memory ID"; 449 LOG(ERROR) << "Invalid discardable shared memory ID";
394 *shared_memory_handle = base::SharedMemory::NULLHandle(); 450 *shared_memory_handle = base::SharedMemory::NULLHandle();
395 return; 451 return;
396 } 452 }
(...skipping 12 matching lines...) Expand all
409 if (bytes_allocated_ > limit) 465 if (bytes_allocated_ > limit)
410 ReduceMemoryUsageUntilWithinLimit(limit); 466 ReduceMemoryUsageUntilWithinLimit(limit);
411 467
412 std::unique_ptr<base::DiscardableSharedMemory> memory( 468 std::unique_ptr<base::DiscardableSharedMemory> memory(
413 new base::DiscardableSharedMemory); 469 new base::DiscardableSharedMemory);
414 if (!memory->CreateAndMap(size)) { 470 if (!memory->CreateAndMap(size)) {
415 *shared_memory_handle = base::SharedMemory::NULLHandle(); 471 *shared_memory_handle = base::SharedMemory::NULLHandle();
416 return; 472 return;
417 } 473 }
418 474
419 if (!memory->ShareToProcess(process_handle, shared_memory_handle)) { 475 *shared_memory_handle = base::SharedMemory::DuplicateHandle(memory->handle());
dcheng 2016/11/25 00:07:08 Nit: I would just DuplicateHandle up in the Proxy
Peng 2016/11/25 16:41:53 Because the handle inside of memory will be closed
dcheng 2016/11/28 18:26:54 Hmm... I was hoping we could wrap this in sort of
Peng 2016/11/29 15:20:13 Done.
420 LOG(ERROR) << "Cannot share discardable memory segment";
421 *shared_memory_handle = base::SharedMemory::NULLHandle();
422 return;
423 }
424 476
425 // Close file descriptor to avoid running out. 477 // Close file descriptor to avoid running out.
426 memory->Close(); 478 memory->Close();
427 479
428 base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_; 480 base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_;
429 checked_bytes_allocated += memory->mapped_size(); 481 checked_bytes_allocated += memory->mapped_size();
430 if (!checked_bytes_allocated.IsValid()) { 482 if (!checked_bytes_allocated.IsValid()) {
483 base::SharedMemory::CloseHandle(*shared_memory_handle);
431 *shared_memory_handle = base::SharedMemory::NULLHandle(); 484 *shared_memory_handle = base::SharedMemory::NULLHandle();
432 return; 485 return;
433 } 486 }
434 487
435 bytes_allocated_ = checked_bytes_allocated.ValueOrDie(); 488 bytes_allocated_ = checked_bytes_allocated.ValueOrDie();
436 BytesAllocatedChanged(bytes_allocated_); 489 BytesAllocatedChanged(bytes_allocated_);
437 490
438 scoped_refptr<MemorySegment> segment(new MemorySegment(std::move(memory))); 491 scoped_refptr<MemorySegment> segment(new MemorySegment(std::move(memory)));
439 client_segments[id] = segment.get(); 492 client_segments[id] = segment.get();
440 segments_.push_back(segment.get()); 493 segments_.push_back(segment.get());
441 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); 494 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime);
442 495
443 if (bytes_allocated_ > memory_limit_) 496 if (bytes_allocated_ > memory_limit_)
444 ScheduleEnforceMemoryPolicy(); 497 ScheduleEnforceMemoryPolicy();
445 } 498 }
446 499
447 void DiscardableSharedMemoryManager::DeletedDiscardableSharedMemory( 500 void DiscardableSharedMemoryManager::DeletedDiscardableSharedMemory(
448 DiscardableSharedMemoryId id, 501 int32_t id,
449 int client_id) { 502 int client_id) {
450 base::AutoLock lock(lock_); 503 base::AutoLock lock(lock_);
451 504
452 MemorySegmentMap& client_segments = clients_[client_id]; 505 MemorySegmentMap& client_segments = clients_[client_id];
453 506
454 MemorySegmentMap::iterator segment_it = client_segments.find(id); 507 MemorySegmentMap::iterator segment_it = client_segments.find(id);
455 if (segment_it == client_segments.end()) { 508 if (segment_it == client_segments.end()) {
456 LOG(ERROR) << "Invalid discardable shared memory ID"; 509 LOG(ERROR) << "Invalid discardable shared memory ID";
457 return; 510 return;
458 } 511 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 return; 634 return;
582 635
583 enforce_memory_policy_pending_ = true; 636 enforce_memory_policy_pending_ = true;
584 DCHECK(enforce_memory_policy_task_runner_); 637 DCHECK(enforce_memory_policy_task_runner_);
585 enforce_memory_policy_task_runner_->PostDelayedTask( 638 enforce_memory_policy_task_runner_->PostDelayedTask(
586 FROM_HERE, enforce_memory_policy_callback_, 639 FROM_HERE, enforce_memory_policy_callback_,
587 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); 640 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs));
588 } 641 }
589 642
590 } // namespace discardable_memory 643 } // namespace discardable_memory
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698