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

Side by Side Diff: chrome/browser/metrics/subprocess_metrics_provider.cc

Issue 1671933002: Create and pass shared-histogram-allocator from browser to renderer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@hsm-merge
Patch Set: fixed test to not use SharedMemory which doesn't work on all builds (and rebased) Created 4 years, 8 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
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/metrics/subprocess_metrics_provider.h"
6
7 #include "base/logging.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/metrics/histogram_base.h"
10 #include "base/metrics/histogram_macros.h"
11 #include "base/metrics/persistent_histogram_allocator.h"
12 #include "base/metrics/persistent_memory_allocator.h"
13 #include "components/metrics/metrics_service.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/notification_types.h"
16 #include "content/public/browser/render_process_host.h"
17
18 SubprocessMetricsProvider::SubprocessMetricsProvider()
19 : scoped_observer_(this) {
20 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
21 content::NotificationService::AllBrowserContextsAndSources());
22 }
23
24 SubprocessMetricsProvider::~SubprocessMetricsProvider() {}
25
26 void SubprocessMetricsProvider::RegisterSubprocessAllocator(
27 int id,
28 std::unique_ptr<base::PersistentHistogramAllocator> allocator) {
29 DCHECK(thread_checker_.CalledOnValidThread());
30 DCHECK(!allocators_by_id_.Lookup(id));
31
32 // Map is "MapOwnPointer" so transfer ownership to it.
33 allocators_by_id_.AddWithID(allocator.release(), id);
34 }
35
36 void SubprocessMetricsProvider::DeregisterSubprocessAllocator(int id) {
37 DCHECK(thread_checker_.CalledOnValidThread());
38
39 if (!allocators_by_id_.Lookup(id))
40 return;
41
42 // Extract the matching allocator from the list of active ones.
43 std::unique_ptr<base::PersistentHistogramAllocator> allocator(
44 allocators_by_id_.Replace(id, nullptr));
45 allocators_by_id_.Remove(id);
46 DCHECK(allocator);
47
48 // If metrics recording is enabled, transfer the allocator to the "release"
49 // list. The allocator will continue to live (and keep the associated shared
50 // memory alive) until the next upload after which it will be released.
51 // Otherwise, the allocator and its memory will be released when the
52 // unique_ptr goes out of scope at the end of this method.
53 if (metrics_recording_enabled_)
54 allocators_to_release_.push_back(std::move(allocator));
55 }
56
57 void SubprocessMetricsProvider::OnRecordingEnabled() {
58 DCHECK(thread_checker_.CalledOnValidThread());
59
60 metrics_recording_enabled_ = true;
61 }
62
63 void SubprocessMetricsProvider::OnRecordingDisabled() {
64 DCHECK(thread_checker_.CalledOnValidThread());
65
66 metrics_recording_enabled_ = false;
67 allocators_to_release_.clear();
68 }
69
70 void SubprocessMetricsProvider::RecordHistogramSnapshotsFromAllocator(
71 base::HistogramSnapshotManager* snapshot_manager,
72 int id,
73 base::PersistentHistogramAllocator* allocator) {
74 DCHECK(allocator);
75
76 int histogram_count = 0;
77 base::PersistentHistogramAllocator::Iterator hist_iter(allocator);
78 while (true) {
79 std::unique_ptr<base::HistogramBase> histogram = hist_iter.GetNext();
80 if (!histogram)
81 break;
82 snapshot_manager->PrepareDeltaTakingOwnership(std::move(histogram));
83 ++histogram_count;
84 }
85
86 DVLOG(1) << "Reported " << histogram_count << " histograms from subprocess #"
87 << id;
88 }
89
90 void SubprocessMetricsProvider::RecordHistogramSnapshots(
91 base::HistogramSnapshotManager* snapshot_manager) {
92 DCHECK(thread_checker_.CalledOnValidThread());
93
94 for (AllocatorByIdMap::iterator iter(&allocators_by_id_); !iter.IsAtEnd();
95 iter.Advance()) {
96 RecordHistogramSnapshotsFromAllocator(
97 snapshot_manager, iter.GetCurrentKey(), iter.GetCurrentValue());
98 }
99
100 for (auto& allocator : allocators_to_release_)
101 RecordHistogramSnapshotsFromAllocator(snapshot_manager, 0, allocator.get());
102
103 UMA_HISTOGRAM_COUNTS_100(
104 "UMA.SubprocessMetricsProvider.SubprocessCount",
105 allocators_by_id_.size() + allocators_to_release_.size());
106
107 // The snapshot-manager has taken ownership of the histograms but needs
108 // access to only the histogram objects, not "sample" data it uses. Thus,
109 // it is safe to release shared-memory segments without waiting for the
110 // snapshot-manager to "finish".
111 allocators_to_release_.clear();
112 }
113
114 void SubprocessMetricsProvider::Observe(
115 int type,
116 const content::NotificationSource& source,
117 const content::NotificationDetails& details) {
118 DCHECK(thread_checker_.CalledOnValidThread());
119 DCHECK_EQ(content::NOTIFICATION_RENDERER_PROCESS_CREATED, type);
120
121 content::RenderProcessHost* host =
122 content::Source<content::RenderProcessHost>(source).ptr();
123
124 // Sometimes, the same host will cause multiple notifications in tests so
125 // could possibly do the same in a release build.
126 if (!scoped_observer_.IsObserving(host))
127 scoped_observer_.Add(host);
128 }
129
130 void SubprocessMetricsProvider::RenderProcessReady(
131 content::RenderProcessHost* host) {
132 DCHECK(thread_checker_.CalledOnValidThread());
133
134 // If the render-process-host passed a persistent-memory-allocator to the
135 // renderer process, extract it and register it here.
136 std::unique_ptr<base::SharedPersistentMemoryAllocator> allocator =
137 host->TakeMetricsAllocator();
138 if (allocator) {
139 RegisterSubprocessAllocator(
140 host->GetID(),
141 WrapUnique(new base::PersistentHistogramAllocator(
142 std::move(allocator))));
143 }
144 }
145
146 void SubprocessMetricsProvider::RenderProcessExited(
147 content::RenderProcessHost* host,
148 base::TerminationStatus status,
149 int exit_code) {
150 DCHECK(thread_checker_.CalledOnValidThread());
151
152 DeregisterSubprocessAllocator(host->GetID());
153 }
154
155 void SubprocessMetricsProvider::RenderProcessHostDestroyed(
156 content::RenderProcessHost* host) {
157 DCHECK(thread_checker_.CalledOnValidThread());
158
159 // It's possible for a Renderer to terminate without RenderProcessExited
160 // (above) being called so it's necessary to de-register also upon the
161 // destruction of the host. If both get called, no harm is done.
162
163 DeregisterSubprocessAllocator(host->GetID());
164 scoped_observer_.Remove(host);
165 }
OLDNEW
« no previous file with comments | « chrome/browser/metrics/subprocess_metrics_provider.h ('k') | chrome/browser/metrics/subprocess_metrics_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698