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

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

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

Powered by Google App Engine
This is Rietveld 408576698