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

Unified Diff: base/metrics/histogram.cc

Issue 2867303004: [histogram] Make histograms more resistant to overflows. (Closed)
Patch Set: fix unittest compilation Created 3 years, 7 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
Index: base/metrics/histogram.cc
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc
index c35f76ce5548d8f0264f26fbeefab9c5d62aea82..dff5f36599fe21fa45efa6d03d54b5af292d984f 100644
--- a/base/metrics/histogram.cc
+++ b/base/metrics/histogram.cc
@@ -414,7 +414,7 @@ bool Histogram::InspectConstructionArguments(const std::string& name,
}
uint64_t Histogram::name_hash() const {
- return samples_->id();
+ return unlogged_samples_->id();
}
HistogramType Histogram::GetHistogramType() const {
@@ -445,29 +445,30 @@ void Histogram::AddCount(int value, int count) {
NOTREACHED();
return;
}
- samples_->Accumulate(value, count);
+ unlogged_samples_->Accumulate(value, count);
FindAndRunCallback(value);
}
std::unique_ptr<HistogramSamples> Histogram::SnapshotSamples() const {
- return SnapshotSampleVector();
+ return SnapshotAllSamples();
}
std::unique_ptr<HistogramSamples> Histogram::SnapshotDelta() {
DCHECK(!final_delta_created_);
- std::unique_ptr<HistogramSamples> snapshot = SnapshotSampleVector();
- if (!logged_samples_) {
- // If nothing has been previously logged, save this one as
- // |logged_samples_| and gather another snapshot to return.
- logged_samples_.swap(snapshot);
- return SnapshotSampleVector();
- }
+ // This code takes unlogged samples, adds them to logged samples,
+ // resets them and returns them.
+ // Correctness of this code relies on unlogged_samples being thread-safe
+ // due to atomic integer operations. Snapshot is taken by atomically copying
+ // all existing samples. Reset is implemented by subtracting copied snapshot,
+ // leaving samples added concurrently from another thread in unlogged_samples
+ // to be reported by the next call to SnapshotDelta.
Alexei Svitkine (slow) 2017/05/11 13:54:35 Maybe call out the function names where the atomic
bcwhite 2017/05/11 17:34:52 Basically, every individual operation is atomic bu
altimin 2017/05/11 17:55:43 I think that does not belong here. We should menti
- // Subtract what was previously logged and update that information.
- snapshot->Subtract(*logged_samples_);
+ std::unique_ptr<HistogramSamples> snapshot = SnapshotUnloggedSamples();
+ unlogged_samples_->Subtract(*snapshot);
logged_samples_->Add(*snapshot);
+
return snapshot;
}
@@ -475,20 +476,15 @@ std::unique_ptr<HistogramSamples> Histogram::SnapshotFinalDelta() const {
DCHECK(!final_delta_created_);
final_delta_created_ = true;
- std::unique_ptr<HistogramSamples> snapshot = SnapshotSampleVector();
-
- // Subtract what was previously logged and then return.
- if (logged_samples_)
- snapshot->Subtract(*logged_samples_);
- return snapshot;
+ return SnapshotUnloggedSamples();
}
void Histogram::AddSamples(const HistogramSamples& samples) {
- samples_->Add(samples);
+ unlogged_samples_->Add(samples);
}
bool Histogram::AddSamplesFromPickle(PickleIterator* iter) {
- return samples_->AddFromPickle(iter);
+ return unlogged_samples_->AddFromPickle(iter);
}
// The following methods provide a graphical histogram display.
@@ -521,8 +517,10 @@ Histogram::Histogram(const std::string& name,
bucket_ranges_(ranges),
declared_min_(minimum),
declared_max_(maximum) {
- if (ranges)
- samples_.reset(new SampleVector(HashMetricName(name), ranges));
+ if (ranges) {
+ unlogged_samples_.reset(new SampleVector(HashMetricName(name), ranges));
+ logged_samples_.reset(new SampleVector(unlogged_samples_->id(), ranges));
+ }
}
Histogram::Histogram(const std::string& name,
@@ -538,10 +536,10 @@ Histogram::Histogram(const std::string& name,
declared_min_(minimum),
declared_max_(maximum) {
if (ranges) {
- samples_.reset(
+ unlogged_samples_.reset(
new PersistentSampleVector(HashMetricName(name), ranges, meta, counts));
logged_samples_.reset(new PersistentSampleVector(
- samples_->id(), ranges, logged_meta, logged_counts));
+ unlogged_samples_->id(), ranges, logged_meta, logged_counts));
}
}
@@ -598,10 +596,16 @@ HistogramBase* Histogram::DeserializeInfoImpl(PickleIterator* iter) {
return histogram;
}
-std::unique_ptr<SampleVector> Histogram::SnapshotSampleVector() const {
+std::unique_ptr<SampleVector> Histogram::SnapshotAllSamples() const {
+ std::unique_ptr<SampleVector> samples = SnapshotUnloggedSamples();
+ samples->Add(*logged_samples_);
+ return samples;
+}
+
+std::unique_ptr<SampleVector> Histogram::SnapshotUnloggedSamples() const {
std::unique_ptr<SampleVector> samples(
- new SampleVector(samples_->id(), bucket_ranges()));
- samples->Add(*samples_);
+ new SampleVector(unlogged_samples_->id(), bucket_ranges()));
+ samples->Add(*unlogged_samples_);
return samples;
}
@@ -610,7 +614,7 @@ void Histogram::WriteAsciiImpl(bool graph_it,
std::string* output) const {
// Get local (stack) copies of all effectively volatile class data so that we
// are consistent across our output activities.
- std::unique_ptr<SampleVector> snapshot = SnapshotSampleVector();
+ std::unique_ptr<SampleVector> snapshot = SnapshotAllSamples();
Count sample_count = snapshot->TotalCount();
WriteAsciiHeader(*snapshot, sample_count, output);
@@ -722,7 +726,7 @@ void Histogram::GetParameters(DictionaryValue* params) const {
void Histogram::GetCountAndBucketData(Count* count,
int64_t* sum,
ListValue* buckets) const {
- std::unique_ptr<SampleVector> snapshot = SnapshotSampleVector();
+ std::unique_ptr<SampleVector> snapshot = SnapshotAllSamples();
*count = snapshot->TotalCount();
*sum = snapshot->sum();
uint32_t index = 0;

Powered by Google App Engine
This is Rietveld 408576698