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

Side by Side Diff: content/browser/browser_child_process_host_impl.cc

Issue 2224063002: Use persistent memory for receiving metrics from sub-processes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: create helper method; make test appear to be on UI thread Created 4 years, 4 months 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/browser_child_process_host_impl.h" 5 #include "content/browser/browser_child_process_host_impl.h"
6 6
7 #include "base/base_switches.h" 7 #include "base/base_switches.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/dump_without_crashing.h" 10 #include "base/debug/dump_without_crashing.h"
11 #include "base/feature_list.h" 11 #include "base/feature_list.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/metrics/field_trial.h" 16 #include "base/metrics/field_trial.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/metrics/persistent_histogram_allocator.h"
19 #include "base/metrics/persistent_memory_allocator.h"
18 #include "base/stl_util.h" 20 #include "base/stl_util.h"
19 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
20 #include "base/synchronization/waitable_event.h" 22 #include "base/synchronization/waitable_event.h"
21 #include "base/threading/thread_task_runner_handle.h" 23 #include "base/threading/thread_task_runner_handle.h"
22 #include "build/build_config.h" 24 #include "build/build_config.h"
23 #include "components/tracing/common/tracing_switches.h" 25 #include "components/tracing/common/tracing_switches.h"
24 #include "content/browser/histogram_message_filter.h" 26 #include "content/browser/histogram_message_filter.h"
25 #include "content/browser/loader/resource_message_filter.h" 27 #include "content/browser/loader/resource_message_filter.h"
26 #include "content/browser/memory/memory_message_filter.h" 28 #include "content/browser/memory/memory_message_filter.h"
27 #include "content/browser/profiler_message_filter.h" 29 #include "content/browser/profiler_message_filter.h"
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 child_process_host_.reset(ChildProcessHost::Create(this)); 163 child_process_host_.reset(ChildProcessHost::Create(this));
162 AddFilter(new TraceMessageFilter(data_.id)); 164 AddFilter(new TraceMessageFilter(data_.id));
163 AddFilter(new ProfilerMessageFilter(process_type)); 165 AddFilter(new ProfilerMessageFilter(process_type));
164 AddFilter(new HistogramMessageFilter); 166 AddFilter(new HistogramMessageFilter);
165 AddFilter(new MemoryMessageFilter(this, process_type)); 167 AddFilter(new MemoryMessageFilter(this, process_type));
166 168
167 g_child_process_list.Get().push_back(this); 169 g_child_process_list.Get().push_back(this);
168 GetContentClient()->browser()->BrowserChildProcessHostCreated(this); 170 GetContentClient()->browser()->BrowserChildProcessHostCreated(this);
169 171
170 power_monitor_message_broadcaster_.Init(); 172 power_monitor_message_broadcaster_.Init();
173
174 // Create a persistent memory segment for subprocess histograms.
175 CreateMetricsAllocator();
171 } 176 }
172 177
173 BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() { 178 BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() {
174 g_child_process_list.Get().remove(this); 179 g_child_process_list.Get().remove(this);
175 180
176 if (notify_child_disconnected_) { 181 if (notify_child_disconnected_) {
177 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 182 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
178 base::Bind(&NotifyProcessHostDisconnected, data_)); 183 base::Bind(&NotifyProcessHostDisconnected, data_));
179 } 184 }
180 } 185 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 266
262 const base::Process& BrowserChildProcessHostImpl::GetProcess() const { 267 const base::Process& BrowserChildProcessHostImpl::GetProcess() const {
263 DCHECK_CURRENTLY_ON(BrowserThread::IO); 268 DCHECK_CURRENTLY_ON(BrowserThread::IO);
264 DCHECK(child_process_.get()) 269 DCHECK(child_process_.get())
265 << "Requesting a child process handle before launching."; 270 << "Requesting a child process handle before launching.";
266 DCHECK(child_process_->GetProcess().IsValid()) 271 DCHECK(child_process_->GetProcess().IsValid())
267 << "Requesting a child process handle before launch has completed OK."; 272 << "Requesting a child process handle before launch has completed OK.";
268 return child_process_->GetProcess(); 273 return child_process_->GetProcess();
269 } 274 }
270 275
276 std::unique_ptr<base::SharedPersistentMemoryAllocator>
277 BrowserChildProcessHostImpl::TakeMetricsAllocator() {
278 return std::move(metrics_allocator_);
279 }
280
271 void BrowserChildProcessHostImpl::SetName(const base::string16& name) { 281 void BrowserChildProcessHostImpl::SetName(const base::string16& name) {
272 DCHECK_CURRENTLY_ON(BrowserThread::IO); 282 DCHECK_CURRENTLY_ON(BrowserThread::IO);
273 data_.name = name; 283 data_.name = name;
274 } 284 }
275 285
276 void BrowserChildProcessHostImpl::SetHandle(base::ProcessHandle handle) { 286 void BrowserChildProcessHostImpl::SetHandle(base::ProcessHandle handle) {
277 DCHECK_CURRENTLY_ON(BrowserThread::IO); 287 DCHECK_CURRENTLY_ON(BrowserThread::IO);
278 data_.handle = handle; 288 data_.handle = handle;
279 } 289 }
280 290
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 // error on the IPC channel. 338 // error on the IPC channel.
329 early_exit_watcher_.StopWatching(); 339 early_exit_watcher_.StopWatching();
330 #endif 340 #endif
331 341
332 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 342 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
333 base::Bind(&NotifyProcessHostConnected, data_)); 343 base::Bind(&NotifyProcessHostConnected, data_));
334 344
335 delegate_->OnChannelConnected(peer_pid); 345 delegate_->OnChannelConnected(peer_pid);
336 346
337 if (IsProcessLaunched()) { 347 if (IsProcessLaunched()) {
348 ShareMetricsAllocatorToProcess();
338 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 349 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
339 base::Bind(&NotifyProcessLaunchedAndConnected, 350 base::Bind(&NotifyProcessLaunchedAndConnected,
340 data_)); 351 data_));
341 } 352 }
342 } 353 }
343 354
344 void BrowserChildProcessHostImpl::OnChannelError() { 355 void BrowserChildProcessHostImpl::OnChannelError() {
345 delegate_->OnChannelError(); 356 delegate_->OnChannelError();
346 } 357 }
347 358
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 } 440 }
430 #endif 441 #endif
431 } 442 }
432 delete delegate_; // Will delete us 443 delete delegate_; // Will delete us
433 } 444 }
434 445
435 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) { 446 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) {
436 return child_process_host_->Send(message); 447 return child_process_host_->Send(message);
437 } 448 }
438 449
450 void BrowserChildProcessHostImpl::CreateMetricsAllocator() {
451 // Create a persistent memory segment for subprocess histograms only if
452 // they're active in the browser.
453 // TODO(bcwhite): Remove this once persistence is always enabled.
454 if (!base::GlobalHistogramAllocator::Get())
455 return;
456
457 // Determine the correct parameters based on the process type.
458 size_t memory_size;
459 base::StringPiece metrics_name;
460 switch (data_.process_type) {
461 case PROCESS_TYPE_GPU:
462 memory_size = 100 << 10; // 100 KiB
463 metrics_name = "GpuMetrics";
464 break;
465
466 default:
467 return;
468 }
469
470 // Create the shared memory segment and attach an allocator to it.
471 // Mapping the memory shouldn't fail but be safe if it does; everything
472 // will continue to work but just as if persistence weren't available.
473 std::unique_ptr<base::SharedMemory> shm(new base::SharedMemory());
474 if (!shm->CreateAndMapAnonymous(memory_size))
475 return;
476 metrics_allocator_.reset(new base::SharedPersistentMemoryAllocator(
477 std::move(shm), static_cast<uint64_t>(data_.id), metrics_name,
478 /*readonly=*/false));
479 }
480
481 void BrowserChildProcessHostImpl::ShareMetricsAllocatorToProcess() {
482 if (metrics_allocator_) {
483 base::SharedMemoryHandle shm_handle;
484 metrics_allocator_->shared_memory()->ShareToProcess(data_.handle,
485 &shm_handle);
486 Send(new ChildProcessMsg_SetHistogramMemory(
487 shm_handle, metrics_allocator_->shared_memory()->mapped_size()));
488 }
489 }
490
439 void BrowserChildProcessHostImpl::OnProcessLaunchFailed(int error_code) { 491 void BrowserChildProcessHostImpl::OnProcessLaunchFailed(int error_code) {
440 delegate_->OnProcessLaunchFailed(error_code); 492 delegate_->OnProcessLaunchFailed(error_code);
441 notify_child_disconnected_ = false; 493 notify_child_disconnected_ = false;
442 delete delegate_; // Will delete us 494 delete delegate_; // Will delete us
443 } 495 }
444 496
445 void BrowserChildProcessHostImpl::OnProcessLaunched() { 497 void BrowserChildProcessHostImpl::OnProcessLaunched() {
446 DCHECK_CURRENTLY_ON(BrowserThread::IO); 498 DCHECK_CURRENTLY_ON(BrowserThread::IO);
447 499
448 const base::Process& process = child_process_->GetProcess(); 500 const base::Process& process = child_process_->GetProcess();
449 DCHECK(process.IsValid()); 501 DCHECK(process.IsValid());
450 502
451 #if defined(OS_WIN) 503 #if defined(OS_WIN)
452 // Start a WaitableEventWatcher that will invoke OnProcessExitedEarly if the 504 // Start a WaitableEventWatcher that will invoke OnProcessExitedEarly if the
453 // child process exits. This watcher is stopped once the IPC channel is 505 // child process exits. This watcher is stopped once the IPC channel is
454 // connected and the exit of the child process is detecter by an error on the 506 // connected and the exit of the child process is detecter by an error on the
455 // IPC channel thereafter. 507 // IPC channel thereafter.
456 DCHECK(!early_exit_watcher_.GetWatchedObject()); 508 DCHECK(!early_exit_watcher_.GetWatchedObject());
457 early_exit_watcher_.StartWatchingOnce(process.Handle(), this); 509 early_exit_watcher_.StartWatchingOnce(process.Handle(), this);
458 #endif 510 #endif
459 511
460 // TODO(rvargas) crbug.com/417532: Don't store a handle. 512 // TODO(rvargas) crbug.com/417532: Don't store a handle.
461 data_.handle = process.Handle(); 513 data_.handle = process.Handle();
462 delegate_->OnProcessLaunched(); 514 delegate_->OnProcessLaunched();
463 515
464 if (is_channel_connected_) { 516 if (is_channel_connected_) {
517 ShareMetricsAllocatorToProcess();
465 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 518 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
466 base::Bind(&NotifyProcessLaunchedAndConnected, 519 base::Bind(&NotifyProcessLaunchedAndConnected,
467 data_)); 520 data_));
468 } 521 }
469 } 522 }
470 523
471 bool BrowserChildProcessHostImpl::IsProcessLaunched() const { 524 bool BrowserChildProcessHostImpl::IsProcessLaunched() const {
472 DCHECK_CURRENTLY_ON(BrowserThread::IO); 525 DCHECK_CURRENTLY_ON(BrowserThread::IO);
473 526
474 return child_process_.get() && child_process_->GetProcess().IsValid(); 527 return child_process_.get() && child_process_->GetProcess().IsValid();
(...skipping 28 matching lines...) Expand all
503 556
504 #if defined(OS_WIN) 557 #if defined(OS_WIN)
505 558
506 void BrowserChildProcessHostImpl::OnObjectSignaled(HANDLE object) { 559 void BrowserChildProcessHostImpl::OnObjectSignaled(HANDLE object) {
507 OnChildDisconnected(); 560 OnChildDisconnected();
508 } 561 }
509 562
510 #endif 563 #endif
511 564
512 } // namespace content 565 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698