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

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

Issue 10829466: SampleSet -> HistogramSamples (will be reused by SparseHistogram) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 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 | Annotate | Revision Log
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/metrics/statistics_recorder.h" 7 #include "base/metrics/statistics_recorder.h"
8 #include "base/metrics/histogram_samples.h"
9 #include "base/stl_util.h"
8 10
9 using base::Histogram; 11 using std::map;
10 using base::StatisticsRecorder; 12 using std::string;
11 13
12 namespace base { 14 namespace base {
13 15
14 HistogramSnapshotManager::HistogramSnapshotManager( 16 HistogramSnapshotManager::HistogramSnapshotManager(
15 HistogramFlattener* histogram_flattener) 17 HistogramFlattener* histogram_flattener)
16 : histogram_flattener_(histogram_flattener) { 18 : histogram_flattener_(histogram_flattener) {
17 DCHECK(histogram_flattener_); 19 DCHECK(histogram_flattener_);
18 } 20 }
19 21
20 HistogramSnapshotManager::~HistogramSnapshotManager() {} 22 HistogramSnapshotManager::~HistogramSnapshotManager() {
23 STLDeleteValues(&logged_samples_);
24 }
21 25
22 void HistogramSnapshotManager::PrepareDeltas(Histogram::Flags flag_to_set, 26 void HistogramSnapshotManager::PrepareDeltas(Histogram::Flags flag_to_set,
23 bool record_only_uma) { 27 bool record_only_uma) {
24 StatisticsRecorder::Histograms histograms; 28 StatisticsRecorder::Histograms histograms;
25 StatisticsRecorder::GetHistograms(&histograms); 29 StatisticsRecorder::GetHistograms(&histograms);
26 for (StatisticsRecorder::Histograms::const_iterator it = histograms.begin(); 30 for (StatisticsRecorder::Histograms::const_iterator it = histograms.begin();
27 histograms.end() != it; 31 histograms.end() != it;
28 ++it) { 32 ++it) {
29 (*it)->SetFlags(flag_to_set); 33 (*it)->SetFlags(flag_to_set);
30 if (record_only_uma && 34 if (record_only_uma &&
31 0 == ((*it)->flags() & Histogram::kUmaTargetedHistogramFlag)) 35 0 == ((*it)->flags() & Histogram::kUmaTargetedHistogramFlag))
32 continue; 36 continue;
33 PrepareDelta(**it); 37 PrepareDelta(**it);
34 } 38 }
35 } 39 }
36 40
37 void HistogramSnapshotManager::PrepareDelta(const Histogram& histogram) { 41 void HistogramSnapshotManager::PrepareDelta(const Histogram& histogram) {
38 DCHECK(histogram_flattener_); 42 DCHECK(histogram_flattener_);
39 43
40 // Get up-to-date snapshot of sample stats. 44 // Get up-to-date snapshot of sample stats.
41 Histogram::SampleSet snapshot; 45 scoped_ptr<HistogramSamples> snapshot(histogram.SnapshotSamples());
42 histogram.SnapshotSample(&snapshot);
43 const std::string& histogram_name = histogram.histogram_name(); 46 const std::string& histogram_name = histogram.histogram_name();
44 47
45 int corruption = histogram.FindCorruption(snapshot); 48 int corruption = histogram.FindCorruption(*snapshot);
46 49
47 // Crash if we detect that our histograms have been overwritten. This may be 50 // Crash if we detect that our histograms have been overwritten. This may be
48 // a fair distance from the memory smasher, but we hope to correlate these 51 // a fair distance from the memory smasher, but we hope to correlate these
49 // crashes with other events, such as plugins, or usage patterns, etc. 52 // crashes with other events, such as plugins, or usage patterns, etc.
50 if (Histogram::BUCKET_ORDER_ERROR & corruption) { 53 if (Histogram::BUCKET_ORDER_ERROR & corruption) {
51 // The checksum should have caught this, so crash separately if it didn't. 54 // The checksum should have caught this, so crash separately if it didn't.
52 CHECK_NE(0, Histogram::RANGE_CHECKSUM_ERROR & corruption); 55 CHECK_NE(0, Histogram::RANGE_CHECKSUM_ERROR & corruption);
53 CHECK(false); // Crash for the bucket order corruption. 56 CHECK(false); // Crash for the bucket order corruption.
54 } 57 }
55 // Checksum corruption might not have caused order corruption. 58 // Checksum corruption might not have caused order corruption.
56 CHECK_EQ(0, Histogram::RANGE_CHECKSUM_ERROR & corruption); 59 CHECK_EQ(0, Histogram::RANGE_CHECKSUM_ERROR & corruption);
57 60
58 // Note, at this point corruption can only be COUNT_HIGH_ERROR or 61 // Note, at this point corruption can only be COUNT_HIGH_ERROR or
59 // COUNT_LOW_ERROR and they never arise together, so we don't need to extract 62 // COUNT_LOW_ERROR and they never arise together, so we don't need to extract
60 // bits from corruption. 63 // bits from corruption.
61 if (corruption) { 64 if (corruption) {
62 NOTREACHED(); 65 DLOG(ERROR) << "Histogram: " << histogram_name
66 << " has data corruption: " << corruption;
63 histogram_flattener_->InconsistencyDetected( 67 histogram_flattener_->InconsistencyDetected(
64 static_cast<Histogram::Inconsistencies>(corruption)); 68 static_cast<Histogram::Inconsistencies>(corruption));
65 // Don't record corrupt data to metrics survices. 69 // Don't record corrupt data to metrics services.
66 if (NULL == inconsistencies_.get()) 70 int old_corruption = inconsistencies_[histogram_name];
67 inconsistencies_.reset(new ProblemMap);
68 int old_corruption = (*inconsistencies_)[histogram_name];
69 if (old_corruption == (corruption | old_corruption)) 71 if (old_corruption == (corruption | old_corruption))
70 return; // We've already seen this corruption for this histogram. 72 return; // We've already seen this corruption for this histogram.
71 (*inconsistencies_)[histogram_name] |= corruption; 73 inconsistencies_[histogram_name] |= corruption;
72 histogram_flattener_->UniqueInconsistencyDetected( 74 histogram_flattener_->UniqueInconsistencyDetected(
73 static_cast<Histogram::Inconsistencies>(corruption)); 75 static_cast<Histogram::Inconsistencies>(corruption));
74 return; 76 return;
75 } 77 }
76 78
77 // Find the already recorded stats, or create an empty set. Remove from our 79 HistogramSamples* already_logged;
78 // snapshot anything that we've already recorded. 80 HistogramSamples* to_log;
79 LoggedSampleMap::iterator it = logged_samples_.find(histogram_name); 81
80 Histogram::SampleSet* already_logged; 82 map<string, HistogramSamples*>::iterator it =
81 if (logged_samples_.end() == it) { 83 logged_samples_.find(histogram_name);
82 // Add new entry 84 if (it == logged_samples_.end()) {
83 already_logged = &logged_samples_[histogram.histogram_name()]; 85 // This histogram has not been logged before, add a new entry.
84 // Complete initialization. 86 already_logged = snapshot.release();
Ilya Sherman 2012/08/29 08:48:16 nit: It seems clearer to just assign to |to_log| h
kaiwang 2012/08/29 22:42:16 Done.
85 already_logged->Resize(histogram.bucket_count()); 87 logged_samples_[histogram_name] = already_logged;
88 to_log = already_logged;
86 } else { 89 } else {
87 already_logged = &(it->second); 90 already_logged = it->second;
88 int64 discrepancy(already_logged->TotalCount() - 91 InspectLoggedSamplesInconsistency(*snapshot, already_logged);
89 already_logged->redundant_count()); 92 snapshot->Subtract(*already_logged);
90 if (discrepancy) { 93 already_logged->Add(*snapshot);
91 NOTREACHED(); // Already_logged has become corrupt. 94 to_log = snapshot.get();
Ilya Sherman 2012/08/29 08:48:16 Why did you remove this NOTREACHED()?
kaiwang 2012/08/29 22:42:16 It's trying to handle DCHECK error, which is not r
92 int problem = static_cast<int>(discrepancy);
93 if (problem != discrepancy)
94 problem = INT_MAX;
95 histogram_flattener_->InconsistencyDetectedInLoggedCount(problem);
96 // With no valid baseline, we'll act like we've recorded everything in our
97 // snapshot.
98 already_logged->Subtract(*already_logged);
99 already_logged->Add(snapshot);
100 }
101 // Deduct any stats we've already logged from our snapshot.
102 snapshot.Subtract(*already_logged);
103 } 95 }
104 96
105 // Snapshot now contains only a delta to what we've already_logged. 97 if (to_log->redundant_count() > 0) {
106 if (snapshot.redundant_count() > 0) { 98 histogram_flattener_->RecordDelta(histogram, *to_log);
107 histogram_flattener_->RecordDelta(histogram, snapshot);
108 // Add new data into our running total.
109 already_logged->Add(snapshot);
110 } 99 }
Ilya Sherman 2012/08/29 08:48:16 nit: No need for curly braces.
kaiwang 2012/08/29 22:42:16 Done.
111 } 100 }
101
102 void HistogramSnapshotManager::InspectLoggedSamplesInconsistency(
103 const HistogramSamples& new_snapshot,
104 HistogramSamples* logged_samples) {
105 HistogramBase::Count discrepancy =
106 logged_samples->TotalCount() - logged_samples->redundant_count();
107 if (discrepancy) {
Ilya Sherman 2012/08/29 08:48:16 Optional nit: You can reduce the level of indentat
kaiwang 2012/08/29 22:42:16 Done.
108 histogram_flattener_->InconsistencyDetectedInLoggedCount(discrepancy);
109 if (discrepancy > Histogram::kCommonRaceBasedCountMismatch) {
110 // Fix logged_samples.
111 logged_samples->Subtract(*logged_samples);
112 logged_samples->Add(new_snapshot);
113 }
114 }
115 }
116
112 } // namespace base 117 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698