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

Unified Diff: base/metrics/histogram_snapshot_manager.cc

Issue 1485763002: Merge multiple histogram snapshots into single one for reporting. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@shared-histograms
Patch Set: addressed remaining review comments by Alexei 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/metrics/histogram_snapshot_manager.h ('k') | base/metrics/histogram_snapshot_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/metrics/histogram_snapshot_manager.cc
diff --git a/base/metrics/histogram_snapshot_manager.cc b/base/metrics/histogram_snapshot_manager.cc
index 3d1c0d666a245050953d6899b9eb1423922f77ef..e03213fc72104774fc9568601e6f537952693847 100644
--- a/base/metrics/histogram_snapshot_manager.cc
+++ b/base/metrics/histogram_snapshot_manager.cc
@@ -14,68 +14,124 @@ namespace base {
HistogramSnapshotManager::HistogramSnapshotManager(
HistogramFlattener* histogram_flattener)
- : histogram_flattener_(histogram_flattener) {
+ : preparing_deltas_(false),
+ histogram_flattener_(histogram_flattener) {
DCHECK(histogram_flattener_);
}
HistogramSnapshotManager::~HistogramSnapshotManager() {
- STLDeleteValues(&logged_samples_);
}
-void HistogramSnapshotManager::PrepareDelta(const HistogramBase& histogram) {
+void HistogramSnapshotManager::StartDeltas() {
+ // Ensure that start/finish calls do not get nested.
+ DCHECK(!preparing_deltas_);
+ preparing_deltas_ = true;
+
+#ifdef DEBUG
+ for (const auto& iter : known_histograms) {
+ CHECK(!iter->second.histogram);
+ CHECK(!iter->second.accumulated_samples);
+ CHECK(!(iter->second.inconsistencies &
+ HistogramBase::NEW_INCONSISTENCY_FOUND));
+ }
+#endif
+}
+
+void HistogramSnapshotManager::PrepareDelta(HistogramBase* histogram) {
+ PrepareSamples(histogram, histogram->SnapshotDelta());
+}
+
+void HistogramSnapshotManager::PrepareAbsolute(const HistogramBase* histogram) {
+ PrepareSamples(histogram, histogram->SnapshotSamples());
+}
+
+void HistogramSnapshotManager::FinishDeltas() {
+ DCHECK(preparing_deltas_);
+
+ // Iterate over all known histograms to see what should be recorded.
+ for (auto& iter : known_histograms_) {
+ SampleInfo* sample_info = &iter.second;
+
+ // First, record any histograms in which corruption was detected.
+ if (sample_info->inconsistencies & HistogramBase::NEW_INCONSISTENCY_FOUND) {
+ sample_info->inconsistencies &= ~HistogramBase::NEW_INCONSISTENCY_FOUND;
+ histogram_flattener_->UniqueInconsistencyDetected(
+ static_cast<HistogramBase::Inconsistency>(
+ sample_info->inconsistencies));
+ }
+
+ // Second, record actual accumulated deltas.
+ if (sample_info->accumulated_samples) {
+ // TODO(bcwhite): Investigate using redundant_count() below to avoid
+ // additional pass through all the samples to calculate real total.
+ if (sample_info->accumulated_samples->TotalCount() > 0) {
+ histogram_flattener_->RecordDelta(*sample_info->histogram,
+ *sample_info->accumulated_samples);
+ }
+ delete sample_info->accumulated_samples;
+ sample_info->accumulated_samples = nullptr;
+ }
+
+ // The Histogram pointer must be cleared at this point because the owner
+ // is only required to keep it alive until FinishDeltas() completes.
+ sample_info->histogram = nullptr;
+ }
+
+ preparing_deltas_ = false;
+}
+
+void HistogramSnapshotManager::PrepareSamples(
+ const HistogramBase* histogram,
+ scoped_ptr<HistogramSamples> samples) {
DCHECK(histogram_flattener_);
- // Get up-to-date snapshot of sample stats.
- scoped_ptr<HistogramSamples> snapshot(histogram.SnapshotSamples());
+ // Get information known about this histogram.
+ SampleInfo* sample_info = &known_histograms_[histogram->name_hash()];
+ if (sample_info->histogram) {
+ DCHECK_EQ(sample_info->histogram->histogram_name(),
+ histogram->histogram_name()) << "hash collision";
+ } else {
+ // First time this histogram has been seen; datafill.
+ sample_info->histogram = histogram;
+ }
// Crash if we detect that our histograms have been overwritten. This may be
// a fair distance from the memory smasher, but we hope to correlate these
// crashes with other events, such as plugins, or usage patterns, etc.
- int corruption = histogram.FindCorruption(*snapshot);
+ uint32_t corruption = histogram->FindCorruption(*samples);
if (HistogramBase::BUCKET_ORDER_ERROR & corruption) {
// The checksum should have caught this, so crash separately if it didn't.
- CHECK_NE(0, HistogramBase::RANGE_CHECKSUM_ERROR & corruption);
+ CHECK_NE(0U, HistogramBase::RANGE_CHECKSUM_ERROR & corruption);
CHECK(false); // Crash for the bucket order corruption.
}
// Checksum corruption might not have caused order corruption.
- CHECK_EQ(0, HistogramBase::RANGE_CHECKSUM_ERROR & corruption);
+ CHECK_EQ(0U, HistogramBase::RANGE_CHECKSUM_ERROR & corruption);
// Note, at this point corruption can only be COUNT_HIGH_ERROR or
// COUNT_LOW_ERROR and they never arise together, so we don't need to extract
// bits from corruption.
- const uint64_t histogram_hash = histogram.name_hash();
if (corruption) {
- DLOG(ERROR) << "Histogram: " << histogram.histogram_name()
- << " has data corruption: " << corruption;
+ DLOG(ERROR) << "Histogram: \"" << histogram->histogram_name()
+ << "\" has data corruption: " << corruption;
histogram_flattener_->InconsistencyDetected(
static_cast<HistogramBase::Inconsistency>(corruption));
// Don't record corrupt data to metrics services.
- int old_corruption = inconsistencies_[histogram_hash];
+ const uint32_t old_corruption = sample_info->inconsistencies;
if (old_corruption == (corruption | old_corruption))
return; // We've already seen this corruption for this histogram.
- inconsistencies_[histogram_hash] |= corruption;
- histogram_flattener_->UniqueInconsistencyDetected(
- static_cast<HistogramBase::Inconsistency>(corruption));
+ sample_info->inconsistencies |=
+ corruption | HistogramBase::NEW_INCONSISTENCY_FOUND;
+ // TODO(bcwhite): Can we clear the inconsistency for future collection?
return;
}
- HistogramSamples* to_log;
- auto it = logged_samples_.find(histogram_hash);
- if (it == logged_samples_.end()) {
- to_log = snapshot.release();
-
- // This histogram has not been logged before, add a new entry.
- logged_samples_[histogram_hash] = to_log;
+ if (!sample_info->accumulated_samples) {
+ // This histogram has not been seen before; add it as a new entry.
+ sample_info->accumulated_samples = samples.release();
} else {
- HistogramSamples* already_logged = it->second;
- InspectLoggedSamplesInconsistency(*snapshot, already_logged);
- snapshot->Subtract(*already_logged);
- already_logged->Add(*snapshot);
- to_log = snapshot.get();
+ // There are previous values from this histogram; add them together.
+ sample_info->accumulated_samples->Add(*samples);
}
-
- if (to_log->TotalCount() > 0)
- histogram_flattener_->RecordDelta(histogram, *to_log);
}
void HistogramSnapshotManager::InspectLoggedSamplesInconsistency(
« no previous file with comments | « base/metrics/histogram_snapshot_manager.h ('k') | base/metrics/histogram_snapshot_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698