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

Side by Side Diff: base/metrics/histogram_snapshot_manager.cc

Issue 1537743006: Persist setup metrics and have Chrome report them during UMA upload. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@shared-histograms
Patch Set: test needs to clear out statistics-recorder before releasing histogram memory Created 4 years, 10 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 "base/metrics/histogram_snapshot_manager.h" 5 #include "base/metrics/histogram_snapshot_manager.h"
6 6
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/metrics/histogram_flattener.h" 8 #include "base/metrics/histogram_flattener.h"
9 #include "base/metrics/histogram_samples.h" 9 #include "base/metrics/histogram_samples.h"
10 #include "base/metrics/statistics_recorder.h" 10 #include "base/metrics/statistics_recorder.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 12
13 namespace { 13 namespace {
14 // A flag to indicate that a new inconsistency has been added to the set.
15 // It is used to know if the value needs to be sent upstream and cleared after.
16 const int kNewInconsistency = (int)0x80000000; 14 const int kNewInconsistency = (int)0x80000000;
grt (UTC plus 2) 2016/02/15 15:42:39 nit: replace c-style cast with a C++ cast
bcwhite 2016/02/15 19:22:10 Done.
17 } // namespace 15 } // namespace
18 16
19 namespace base { 17 namespace base {
20 18
21 HistogramSnapshotManager::HistogramSnapshotManager( 19 HistogramSnapshotManager::HistogramSnapshotManager(
22 HistogramFlattener* histogram_flattener) 20 HistogramFlattener* histogram_flattener)
23 : preparing_deltas_(false), 21 : preparing_deltas_(false),
24 histogram_flattener_(histogram_flattener) { 22 histogram_flattener_(histogram_flattener) {
25 DCHECK(histogram_flattener_); 23 DCHECK(histogram_flattener_);
26 } 24 }
27 25
28 HistogramSnapshotManager::~HistogramSnapshotManager() { 26 HistogramSnapshotManager::~HistogramSnapshotManager() {
29 } 27 }
30 28
31 void HistogramSnapshotManager::StartDeltas() { 29 void HistogramSnapshotManager::StartDeltas() {
32 // Ensure that start/finish calls do not get nested. 30 // Ensure that start/finish calls do not get nested.
33 DCHECK(!preparing_deltas_); 31 DCHECK(!preparing_deltas_);
34 preparing_deltas_ = true; 32 preparing_deltas_ = true;
35 33
34 DCHECK(owned_histograms_.empty());
35
36 #ifdef DEBUG 36 #ifdef DEBUG
37 for (const auto& iter : known_histograms) {
38 CHECK(!iter->second.histogram); 37 CHECK(!iter->second.histogram);
39 CHECK(!iter->second.accumulated_samples); 38 CHECK(!iter->second.accumulated_samples);
40 CHECK(!(iter->second.inconsistencies & kNewInconsistency)); 39 CHECK(!(iter->second.inconsistencies & kNewInconsistency));
41 } 40 }
42 #endif 41 #endif
43 } 42 }
44 43
45 void HistogramSnapshotManager::PrepareDelta(HistogramBase* histogram) { 44 void HistogramSnapshotManager::PrepareDelta(HistogramBase* histogram) {
46 PrepareSamples(histogram, histogram->SnapshotDelta()); 45 PrepareSamples(histogram, histogram->SnapshotDelta(), false);
46 }
47
48 void HistogramSnapshotManager::PrepareDeltaTakingOwnership(
49 scoped_ptr<HistogramBase> histogram) {
50 // Snapshot must be done before releasing the pointer.
51 scoped_ptr<HistogramSamples> samples = histogram->SnapshotDelta();
52 PrepareSamples(histogram.release(), std::move(samples), true);
47 } 53 }
48 54
49 void HistogramSnapshotManager::PrepareOnce(const HistogramBase* histogram) { 55 void HistogramSnapshotManager::PrepareOnce(const HistogramBase* histogram) {
50 PrepareSamples(histogram, histogram->SnapshotSamples()); 56 PrepareSamples(histogram, histogram->SnapshotSamples(), false);
57 }
58
59 void HistogramSnapshotManager::PrepareOnceTakingOwnership(
60 scoped_ptr<const HistogramBase> histogram) {
61 // Snapshot must be done before releasing the pointer.
62 scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
63 PrepareSamples(histogram.release(), std::move(samples), true);
51 } 64 }
52 65
53 void HistogramSnapshotManager::FinishDeltas() { 66 void HistogramSnapshotManager::FinishDeltas() {
54 DCHECK(preparing_deltas_); 67 DCHECK(preparing_deltas_);
55 68
56 // Iterate over all known histograms to see what should be recorded. 69 // Iterate over all known histograms to see what should be recorded.
57 for (auto& iter : known_histograms_) { 70 for (auto& iter : known_histograms_) {
grt (UTC plus 2) 2016/02/15 15:42:39 |iter| isn't an iterator, but rather a pair of a h
bcwhite 2016/02/15 19:22:10 Done.
58 SampleInfo* sample_info = &iter.second; 71 SampleInfo* sample_info = &iter.second;
59 72
60 // First, record any histograms in which corruption was detected. 73 // First, record any histograms in which corruption was detected.
61 if (sample_info->inconsistencies & kNewInconsistency) { 74 if (sample_info->inconsistencies & kNewInconsistency) {
62 sample_info->inconsistencies &= ~kNewInconsistency; 75 sample_info->inconsistencies &= ~kNewInconsistency;
63 histogram_flattener_->UniqueInconsistencyDetected( 76 histogram_flattener_->UniqueInconsistencyDetected(
64 static_cast<HistogramBase::Inconsistency>( 77 static_cast<HistogramBase::Inconsistency>(
65 sample_info->inconsistencies)); 78 sample_info->inconsistencies));
66 } 79 }
67 80
68 // Second, record actual accumulated deltas. 81 // Second, record actual accumulated deltas.
69 if (sample_info->accumulated_samples) { 82 if (sample_info->accumulated_samples) {
70 // TODO(bcwhite): Investigate using redundant_count() below to avoid 83 // TODO(bcwhite): Investigate using redundant_count() below to avoid
71 // additional pass through all the samples to calculate real total. 84 // additional pass through all the samples to calculate real total.
72 if (sample_info->accumulated_samples->TotalCount() > 0) { 85 if (sample_info->accumulated_samples->TotalCount() > 0) {
73 histogram_flattener_->RecordDelta(*sample_info->histogram, 86 histogram_flattener_->RecordDelta(*sample_info->histogram,
74 *sample_info->accumulated_samples); 87 *sample_info->accumulated_samples);
75 } 88 }
76 delete sample_info->accumulated_samples; 89 delete sample_info->accumulated_samples;
77 sample_info->accumulated_samples = nullptr; 90 sample_info->accumulated_samples = nullptr;
78 } 91 }
79 92
80 // The Histogram pointer must be cleared at this point because the owner 93 // The Histogram pointer must be cleared at this point because the owner
81 // is only required to keep it alive until FinishDeltas() completes. 94 // is only required to keep it alive until FinishDeltas() completes.
82 sample_info->histogram = nullptr; 95 sample_info->histogram = nullptr;
grt (UTC plus 2) 2016/02/15 15:42:39 just curious: should |inconsistencies| also be cle
bcwhite 2016/02/15 19:22:10 It needs to remain to prevent multiple reports of
grt (UTC plus 2) 2016/02/15 19:53:55 groovy, thanks
83 } 96 }
84 97
98 owned_histograms_.clear();
85 preparing_deltas_ = false; 99 preparing_deltas_ = false;
86 } 100 }
87 101
88 void HistogramSnapshotManager::PrepareSamples( 102 void HistogramSnapshotManager::PrepareSamples(
89 const HistogramBase* histogram, 103 const HistogramBase* histogram,
90 scoped_ptr<HistogramSamples> samples) { 104 scoped_ptr<HistogramSamples> samples,
105 bool take_ownership) {
91 DCHECK(histogram_flattener_); 106 DCHECK(histogram_flattener_);
107 scoped_ptr<const HistogramBase> owned_histogram;
92 108
93 // Get information known about this histogram. 109 // Get information known about this histogram.
94 SampleInfo* sample_info = &known_histograms_[histogram->name_hash()]; 110 SampleInfo* sample_info = &known_histograms_[histogram->name_hash()];
95 if (sample_info->histogram) { 111 if (sample_info->histogram) {
96 DCHECK_EQ(sample_info->histogram->histogram_name(), 112 DCHECK_EQ(sample_info->histogram->histogram_name(),
97 histogram->histogram_name()) << "hash collision"; 113 histogram->histogram_name()) << "hash collision";
114 // Passed histogram won't be needed past end of this method so store
115 // it in a scoped_ptr that will release it when returning.
116 if (take_ownership)
117 owned_histogram.reset(histogram);
98 } else { 118 } else {
99 // First time this histogram has been seen; datafill. 119 // First time this histogram has been seen; datafill.
100 sample_info->histogram = histogram; 120 sample_info->histogram = histogram;
121 // The histogram data will be needed up until "finished" so store
122 // in member vector for releasing when that is done.
123 if (take_ownership)
124 owned_histograms_.push_back(make_scoped_ptr(histogram));
101 } 125 }
102 126
103 // Crash if we detect that our histograms have been overwritten. This may be 127 // Crash if we detect that our histograms have been overwritten. This may be
104 // a fair distance from the memory smasher, but we hope to correlate these 128 // a fair distance from the memory smasher, but we hope to correlate these
105 // crashes with other events, such as plugins, or usage patterns, etc. 129 // crashes with other events, such as plugins, or usage patterns, etc.
106 int corruption = histogram->FindCorruption(*samples); 130 int corruption = histogram->FindCorruption(*samples);
107 if (HistogramBase::BUCKET_ORDER_ERROR & corruption) { 131 if (HistogramBase::BUCKET_ORDER_ERROR & corruption) {
108 // The checksum should have caught this, so crash separately if it didn't. 132 // The checksum should have caught this, so crash separately if it didn't.
109 CHECK_NE(0, HistogramBase::RANGE_CHECKSUM_ERROR & corruption); 133 CHECK_NE(0, HistogramBase::RANGE_CHECKSUM_ERROR & corruption);
110 CHECK(false); // Crash for the bucket order corruption. 134 CHECK(false); // Crash for the bucket order corruption.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 172
149 histogram_flattener_->InconsistencyDetectedInLoggedCount(discrepancy); 173 histogram_flattener_->InconsistencyDetectedInLoggedCount(discrepancy);
150 if (discrepancy > Histogram::kCommonRaceBasedCountMismatch) { 174 if (discrepancy > Histogram::kCommonRaceBasedCountMismatch) {
151 // Fix logged_samples. 175 // Fix logged_samples.
152 logged_samples->Subtract(*logged_samples); 176 logged_samples->Subtract(*logged_samples);
153 logged_samples->Add(new_snapshot); 177 logged_samples->Add(new_snapshot);
154 } 178 }
155 } 179 }
156 180
157 } // namespace base 181 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698