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

Unified Diff: base/metrics/sparse_histogram.cc

Issue 1734033003: Add support for persistent sparse histograms. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressed more review comments by Alexei Created 4 years, 9 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/sparse_histogram.cc
diff --git a/base/metrics/sparse_histogram.cc b/base/metrics/sparse_histogram.cc
index 5653456a29fb552470871f8611cb6337ec65bc50..3530a2f011b27afd160e20c46531c4903215af03 100644
--- a/base/metrics/sparse_histogram.cc
+++ b/base/metrics/sparse_histogram.cc
@@ -6,7 +6,9 @@
#include <utility>
+#include "base/metrics/histogram_persistence.h"
#include "base/metrics/metrics_hashes.h"
+#include "base/metrics/persistent_sample_map.h"
#include "base/metrics/sample_map.h"
#include "base/metrics/statistics_recorder.h"
#include "base/pickle.h"
@@ -21,23 +23,73 @@ typedef HistogramBase::Sample Sample;
// static
HistogramBase* SparseHistogram::FactoryGet(const std::string& name,
int32_t flags) {
- HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
+ // Import histograms from known persistent storage. Histograms could have
+ // been added by other processes and they must be fetched and recognized
+ // locally in order to be found by FindHistograms() below. If the persistent
+ // memory segment is not shared between processes, this call does nothing.
+ ImportPersistentHistograms();
+ HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
if (!histogram) {
- // To avoid racy destruction at shutdown, the following will be leaked.
- HistogramBase* tentative_histogram = new SparseHistogram(name);
+ // Try to create the histogram using a "persistent" allocator. As of
+ // 2016-02-25, the availability of such is controlled by a base::Feature
+ // that is off by default. If the allocator doesn't exist or if
+ // allocating from it fails, code below will allocate the histogram from
+ // the process heap.
+ PersistentMemoryAllocator::Reference histogram_ref = 0;
+ HistogramBase* tentative_histogram = nullptr;
+ PersistentMemoryAllocator* allocator =
+ GetPersistentHistogramMemoryAllocator();
+ if (allocator) {
+ flags |= HistogramBase::kIsPersistent;
Alexei Svitkine (slow) 2016/03/09 20:35:19 Can we move this to inside AllocatePersistentHisto
bcwhite 2016/03/09 22:57:33 It would get overwritten below on line 65... but
+ tentative_histogram = AllocatePersistentHistogram(
+ allocator,
+ SPARSE_HISTOGRAM,
+ name,
+ 0,
+ 0,
+ nullptr,
+ flags,
+ &histogram_ref);
+ }
+
+ // Handle the case where no persistent allocator is present or the
+ // persistent allocation fails (perhaps because it is full).
+ if (!tentative_histogram) {
+ DCHECK(!histogram_ref); // Should never have been set.
+ DCHECK(!allocator); // Shouldn't have failed.
+ flags &= ~HistogramBase::kIsPersistent;
+ tentative_histogram = new SparseHistogram(name);
+ }
+
tentative_histogram->SetFlags(flags);
histogram =
StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
+
+ // Persistent histograms need some follow-up processing.
+ if (histogram_ref) {
+ FinalizePersistentHistogram(histogram_ref,
+ histogram == tentative_histogram);
+ }
}
+
DCHECK_EQ(SPARSE_HISTOGRAM, histogram->GetHistogramType());
return histogram;
}
+// static
+HistogramBase* SparseHistogram::PersistentGet(
+ PersistentMemoryAllocator* allocator,
+ const std::string& name,
+ HistogramSamples::Metadata* meta,
+ HistogramSamples::Metadata* logged_meta) {
+ return new SparseHistogram(allocator, name, meta, logged_meta);
+}
+
SparseHistogram::~SparseHistogram() {}
uint64_t SparseHistogram::name_hash() const {
- return samples_.id();
+ return samples_->id();
}
HistogramType SparseHistogram::GetHistogramType() const {
@@ -63,7 +115,7 @@ void SparseHistogram::AddCount(Sample value, int count) {
}
{
base::AutoLock auto_lock(lock_);
- samples_.Accumulate(value, count);
+ samples_->Accumulate(value, count);
}
FindAndRunCallback(value);
@@ -73,29 +125,29 @@ scoped_ptr<HistogramSamples> SparseHistogram::SnapshotSamples() const {
scoped_ptr<SampleMap> snapshot(new SampleMap(name_hash()));
base::AutoLock auto_lock(lock_);
- snapshot->Add(samples_);
+ snapshot->Add(*samples_);
return std::move(snapshot);
}
scoped_ptr<HistogramSamples> SparseHistogram::SnapshotDelta() {
scoped_ptr<SampleMap> snapshot(new SampleMap(name_hash()));
base::AutoLock auto_lock(lock_);
- snapshot->Add(samples_);
+ snapshot->Add(*samples_);
// Subtract what was previously logged and update that information.
- snapshot->Subtract(logged_samples_);
- logged_samples_.Add(*snapshot);
+ snapshot->Subtract(*logged_samples_);
+ logged_samples_->Add(*snapshot);
return std::move(snapshot);
}
void SparseHistogram::AddSamples(const HistogramSamples& samples) {
base::AutoLock auto_lock(lock_);
- samples_.Add(samples);
+ samples_->Add(samples);
}
bool SparseHistogram::AddSamplesFromPickle(PickleIterator* iter) {
base::AutoLock auto_lock(lock_);
- return samples_.AddFromPickle(iter);
+ return samples_->AddFromPickle(iter);
}
void SparseHistogram::WriteHTMLGraph(std::string* output) const {
@@ -114,7 +166,19 @@ bool SparseHistogram::SerializeInfoImpl(Pickle* pickle) const {
SparseHistogram::SparseHistogram(const std::string& name)
: HistogramBase(name),
- samples_(HashMetricName(name)) {}
+ samples_(new SampleMap(HashMetricName(name))),
+ logged_samples_(new SampleMap(samples_->id())) {}
+
+SparseHistogram::SparseHistogram(PersistentMemoryAllocator* allocator,
+ const std::string& name,
+ HistogramSamples::Metadata* meta,
+ HistogramSamples::Metadata* logged_meta)
+ : HistogramBase(name),
+ samples_(new PersistentSampleMap(HashMetricName(name), allocator, meta)),
+ // The ID must be different so as to not confuse sample records.
Alexei Svitkine (slow) 2016/03/09 20:35:19 Why is this the case here but not for other histog
bcwhite 2016/03/09 22:57:33 Done.
+ logged_samples_(
+ new PersistentSampleMap(samples_->id() + 1, allocator, logged_meta)) {
+}
HistogramBase* SparseHistogram::DeserializeInfoImpl(PickleIterator* iter) {
std::string histogram_name;

Powered by Google App Engine
This is Rietveld 408576698