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

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

Issue 2023253002: Merge subprocess metrics into global StatisticsRecorder. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: improved comment about when merges occur Created 4 years, 6 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 2016 The Chromium Authors. All rights reserved. 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 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 "chrome/browser/metrics/subprocess_metrics_provider.h" 5 #include "chrome/browser/metrics/subprocess_metrics_provider.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/metrics/histogram_base.h" 9 #include "base/metrics/histogram_base.h"
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
(...skipping 21 matching lines...) Expand all
32 // Map is "MapOwnPointer" so transfer ownership to it. 32 // Map is "MapOwnPointer" so transfer ownership to it.
33 allocators_by_id_.AddWithID(allocator.release(), id); 33 allocators_by_id_.AddWithID(allocator.release(), id);
34 } 34 }
35 35
36 void SubprocessMetricsProvider::DeregisterSubprocessAllocator(int id) { 36 void SubprocessMetricsProvider::DeregisterSubprocessAllocator(int id) {
37 DCHECK(thread_checker_.CalledOnValidThread()); 37 DCHECK(thread_checker_.CalledOnValidThread());
38 38
39 if (!allocators_by_id_.Lookup(id)) 39 if (!allocators_by_id_.Lookup(id))
40 return; 40 return;
41 41
42 // Extract the matching allocator from the list of active ones. 42 // Extract the matching allocator from the list of active ones. It will
43 // be automatically released when this method exits.
43 std::unique_ptr<base::PersistentHistogramAllocator> allocator( 44 std::unique_ptr<base::PersistentHistogramAllocator> allocator(
44 allocators_by_id_.Replace(id, nullptr)); 45 allocators_by_id_.Replace(id, nullptr));
45 allocators_by_id_.Remove(id); 46 allocators_by_id_.Remove(id);
46 DCHECK(allocator); 47 DCHECK(allocator);
47 48
48 // If metrics recording is enabled, transfer the allocator to the "release" 49 // Merge the last deltas from the allocator before it is released.
49 // list. The allocator will continue to live (and keep the associated shared 50 MergeHistogramDeltasFromAllocator(id, allocator.get());
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_for_exited_processes_.push_back(std::move(allocator));
55 } 51 }
56 52
57 void SubprocessMetricsProvider::OnDidCreateMetricsLog() { 53 void SubprocessMetricsProvider::MergeHistogramDeltasFromAllocator(
58 DCHECK(thread_checker_.CalledOnValidThread());
59
60 // The previous reporting cycle is complete and the data used to create it
61 // will never be needed again. Allocators for exited processes can finally
62 // be released.
63 allocators_to_release_.clear();
64 }
65
66 void SubprocessMetricsProvider::OnRecordingEnabled() {
67 DCHECK(thread_checker_.CalledOnValidThread());
68
69 metrics_recording_enabled_ = true;
70 }
71
72 void SubprocessMetricsProvider::OnRecordingDisabled() {
73 DCHECK(thread_checker_.CalledOnValidThread());
74
75 metrics_recording_enabled_ = false;
76 allocators_for_exited_processes_.clear();
77 allocators_to_release_.clear();
78 }
79
80 void SubprocessMetricsProvider::RecordHistogramSnapshotsFromAllocator(
81 base::HistogramSnapshotManager* snapshot_manager,
82 int id, 54 int id,
83 base::PersistentHistogramAllocator* allocator) { 55 base::PersistentHistogramAllocator* allocator) {
84 DCHECK(allocator); 56 DCHECK(allocator);
85 57
86 int histogram_count = 0; 58 int histogram_count = 0;
87 base::PersistentHistogramAllocator::Iterator hist_iter(allocator); 59 base::PersistentHistogramAllocator::Iterator hist_iter(allocator);
88 while (true) { 60 while (true) {
89 std::unique_ptr<base::HistogramBase> histogram = hist_iter.GetNext(); 61 std::unique_ptr<base::HistogramBase> histogram = hist_iter.GetNext();
90 if (!histogram) 62 if (!histogram)
91 break; 63 break;
92 snapshot_manager->PrepareDeltaTakingOwnership(std::move(histogram)); 64 allocator->MergeHistogramToStatisticsRecorder(histogram.get());
93 ++histogram_count; 65 ++histogram_count;
94 } 66 }
95 67
96 DVLOG(1) << "Reported " << histogram_count << " histograms from subprocess #" 68 DVLOG(1) << "Reported " << histogram_count << " histograms from subprocess #"
97 << id; 69 << id;
98 } 70 }
99 71
100 void SubprocessMetricsProvider::RecordHistogramSnapshots( 72 void SubprocessMetricsProvider::MergeHistogramDeltas() {
101 base::HistogramSnapshotManager* snapshot_manager) {
102 DCHECK(thread_checker_.CalledOnValidThread()); 73 DCHECK(thread_checker_.CalledOnValidThread());
103 74
104 for (AllocatorByIdMap::iterator iter(&allocators_by_id_); !iter.IsAtEnd(); 75 for (AllocatorByIdMap::iterator iter(&allocators_by_id_); !iter.IsAtEnd();
105 iter.Advance()) { 76 iter.Advance()) {
106 RecordHistogramSnapshotsFromAllocator( 77 MergeHistogramDeltasFromAllocator(iter.GetCurrentKey(),
107 snapshot_manager, iter.GetCurrentKey(), iter.GetCurrentValue()); 78 iter.GetCurrentValue());
108 } 79 }
109 80
110 for (auto& allocator : allocators_for_exited_processes_)
111 RecordHistogramSnapshotsFromAllocator(snapshot_manager, 0, allocator.get());
112
113 UMA_HISTOGRAM_COUNTS_100( 81 UMA_HISTOGRAM_COUNTS_100(
114 "UMA.SubprocessMetricsProvider.SubprocessCount", 82 "UMA.SubprocessMetricsProvider.SubprocessCount",
115 allocators_by_id_.size() + allocators_for_exited_processes_.size()); 83 allocators_by_id_.size());
116
117 // Move allocators for exited processes (which just had final reporting done
118 // for them) to the queue for being released. The actual release is delayed
119 // until after reporting is complete so as to not destruct objects that may
120 // still be needed.
121 DCHECK(allocators_to_release_.empty());
122 allocators_to_release_.swap(allocators_for_exited_processes_);
123 } 84 }
124 85
125 void SubprocessMetricsProvider::Observe( 86 void SubprocessMetricsProvider::Observe(
126 int type, 87 int type,
127 const content::NotificationSource& source, 88 const content::NotificationSource& source,
128 const content::NotificationDetails& details) { 89 const content::NotificationDetails& details) {
129 DCHECK(thread_checker_.CalledOnValidThread()); 90 DCHECK(thread_checker_.CalledOnValidThread());
130 DCHECK_EQ(content::NOTIFICATION_RENDERER_PROCESS_CREATED, type); 91 DCHECK_EQ(content::NOTIFICATION_RENDERER_PROCESS_CREATED, type);
131 92
132 content::RenderProcessHost* host = 93 content::RenderProcessHost* host =
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 content::RenderProcessHost* host) { 128 content::RenderProcessHost* host) {
168 DCHECK(thread_checker_.CalledOnValidThread()); 129 DCHECK(thread_checker_.CalledOnValidThread());
169 130
170 // It's possible for a Renderer to terminate without RenderProcessExited 131 // It's possible for a Renderer to terminate without RenderProcessExited
171 // (above) being called so it's necessary to de-register also upon the 132 // (above) being called so it's necessary to de-register also upon the
172 // destruction of the host. If both get called, no harm is done. 133 // destruction of the host. If both get called, no harm is done.
173 134
174 DeregisterSubprocessAllocator(host->GetID()); 135 DeregisterSubprocessAllocator(host->GetID());
175 scoped_observer_.Remove(host); 136 scoped_observer_.Remove(host);
176 } 137 }
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