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

Unified Diff: base/metrics/histogram.cc

Issue 1425533011: Support "shared" histograms between processes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@shmem-alloc
Patch Set: added a couple tests (and fixed related issues) Created 5 years, 1 month 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 5e24e005fabb23560870e6c8914859d263553ef4..d23472258e9073b480661842f9e31bcb0b351ec1 100644
--- a/base/metrics/histogram.cc
+++ b/base/metrics/histogram.cc
@@ -17,6 +17,7 @@
#include "base/compiler_specific.h"
#include "base/debug/alias.h"
#include "base/logging.h"
+#include "base/memory/persistent_memory_allocator.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/metrics_hashes.h"
#include "base/metrics/sample_vector.h"
@@ -91,6 +92,7 @@ HistogramBase* Histogram::FactoryGet(const std::string& name,
bool valid_arguments =
InspectConstructionArguments(name, &minimum, &maximum, &bucket_count);
DCHECK(valid_arguments);
+ ImportPersistentHistograms();
HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
if (!histogram) {
@@ -100,12 +102,42 @@ HistogramBase* Histogram::FactoryGet(const std::string& name,
const BucketRanges* registered_ranges =
StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
- Histogram* tentative_histogram =
- new Histogram(name, minimum, maximum, registered_ranges);
+ PersistentMemoryAllocator::Reference histogram_ref = 0;
+ HistogramBase* tentative_histogram = nullptr;
+ if (allocator_) {
+ flags |= kIsPersistent;
+ tentative_histogram = AllocatePersistentHistogram(
+ GetDefaultPersistentMemoryAllocator(),
+ HISTOGRAM,
+ name,
+ minimum,
+ maximum,
+ registered_ranges,
+ flags,
+ &histogram_ref);
+ }
+ if (!tentative_histogram) {
+ flags &= ~kIsPersistent;
+ tentative_histogram = new Histogram(
+ name, minimum, maximum, registered_ranges);
+ }
tentative_histogram->SetFlags(flags);
histogram =
StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
+
+ // Persistent histograms need some follow-up processing.
+ if (histogram_ref) {
+ // If the created persistent histogram is canonical then it needs to be
+ // marked as "iterable" in order to be found by other processes.
+ if (histogram == tentative_histogram)
+ GetDefaultPersistentMemoryAllocator()->MakeIterable(histogram_ref);
+ // If it's not the canonical one then a race condition must have caused
+ // two to be created. The allocator does not support releasing the
+ // acquired memory so just change the type to be empty.
+ else
+ GetDefaultPersistentMemoryAllocator()->SetType(histogram_ref, 0);
+ }
}
DCHECK_EQ(HISTOGRAM, histogram->GetHistogramType());
@@ -344,6 +376,22 @@ Histogram::Histogram(const std::string& name,
samples_.reset(new SampleVector(HashMetricName(name), ranges));
}
+Histogram::Histogram(const std::string& name,
+ Sample minimum,
+ Sample maximum,
+ const BucketRanges* ranges,
+ HistogramBase::AtomicCount* counts,
+ size_t counts_size,
+ HistogramSamples::Metadata* meta)
+ : HistogramBase(name),
+ bucket_ranges_(ranges),
+ declared_min_(minimum),
+ declared_max_(maximum) {
+ if (ranges)
+ samples_.reset(new SampleVector(HashMetricName(name),
+ counts, counts_size, meta, ranges));
+}
+
Histogram::~Histogram() {
}
@@ -399,7 +447,8 @@ HistogramBase* Histogram::DeserializeInfoImpl(PickleIterator* iter) {
scoped_ptr<SampleVector> Histogram::SnapshotSampleVector() const {
scoped_ptr<SampleVector> samples(
- new SampleVector(HashMetricName(histogram_name()), bucket_ranges()));
+ new SampleVector(HashMetricName(histogram_name()),
+ bucket_ranges()));
samples->Add(*samples_);
return samples;
}
@@ -593,6 +642,7 @@ HistogramBase* LinearHistogram::FactoryGetWithRangeDescription(
bool valid_arguments = Histogram::InspectConstructionArguments(
name, &minimum, &maximum, &bucket_count);
DCHECK(valid_arguments);
+ ImportPersistentHistograms();
HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
if (!histogram) {
@@ -602,8 +652,26 @@ HistogramBase* LinearHistogram::FactoryGetWithRangeDescription(
const BucketRanges* registered_ranges =
StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
- LinearHistogram* tentative_histogram =
- new LinearHistogram(name, minimum, maximum, registered_ranges);
+ PersistentMemoryAllocator::Reference histogram_ref = 0;
+ LinearHistogram* tentative_histogram = nullptr;
+ if (allocator_) {
+ flags |= kIsPersistent;
+ tentative_histogram = static_cast<LinearHistogram*>(
+ AllocatePersistentHistogram(
+ GetDefaultPersistentMemoryAllocator(),
+ LINEAR_HISTOGRAM,
+ name,
+ minimum,
+ maximum,
+ registered_ranges,
+ flags,
+ &histogram_ref));
+ }
+ if (!tentative_histogram) {
+ flags &= ~kIsPersistent;
+ tentative_histogram = new LinearHistogram(
+ name, minimum, maximum, registered_ranges);
+ }
// Set range descriptions.
if (descriptions) {
@@ -616,6 +684,19 @@ HistogramBase* LinearHistogram::FactoryGetWithRangeDescription(
tentative_histogram->SetFlags(flags);
histogram =
StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
+
+ // Persistent histograms need some follow-up processing.
+ if (histogram_ref) {
+ // If the created persistent histogram is canonical then it needs to be
+ // marked as "iterable" in order to be found by other processes.
+ if (histogram == tentative_histogram)
+ GetDefaultPersistentMemoryAllocator()->MakeIterable(histogram_ref);
+ // If it's not the canonical one then a race condition must have caused
+ // two to be created. The allocator does not support releasing the
+ // acquired memory so just change the type to be empty.
+ else
+ GetDefaultPersistentMemoryAllocator()->SetType(histogram_ref, 0);
+ }
}
DCHECK_EQ(LINEAR_HISTOGRAM, histogram->GetHistogramType());
@@ -643,6 +724,21 @@ LinearHistogram::LinearHistogram(const std::string& name,
: Histogram(name, minimum, maximum, ranges) {
}
+LinearHistogram::LinearHistogram(const std::string& name,
+ Sample minimum,
+ Sample maximum,
+ const BucketRanges* ranges,
+ HistogramBase::AtomicCount* counts,
+ size_t counts_size,
+ HistogramSamples::Metadata* meta)
+ : Histogram(name,
+ minimum,
+ maximum,
+ ranges,
+ counts,
+ counts_size,
+ meta) {}
+
double LinearHistogram::GetBucketSize(Count current, size_t i) const {
DCHECK_GT(ranges(i + 1), ranges(i));
// Adjacent buckets with different widths would have "surprisingly" many (few)
@@ -708,6 +804,8 @@ HistogramBase* LinearHistogram::DeserializeInfoImpl(PickleIterator* iter) {
HistogramBase* BooleanHistogram::FactoryGet(const std::string& name,
int32 flags) {
+ ImportPersistentHistograms();
+
HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
if (!histogram) {
// To avoid racy destruction at shutdown, the following will be leaked.
@@ -716,12 +814,40 @@ HistogramBase* BooleanHistogram::FactoryGet(const std::string& name,
const BucketRanges* registered_ranges =
StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
- BooleanHistogram* tentative_histogram =
- new BooleanHistogram(name, registered_ranges);
+ PersistentMemoryAllocator::Reference histogram_ref = 0;
+ HistogramBase* tentative_histogram = nullptr;
+ if (allocator_) {
+ flags |= kIsPersistent;
+ tentative_histogram = AllocatePersistentHistogram(
+ GetDefaultPersistentMemoryAllocator(),
+ BOOLEAN_HISTOGRAM,
+ name,
+ 1, 2,
+ registered_ranges,
+ flags,
+ &histogram_ref);
+ }
+ if (!tentative_histogram) {
+ flags &= ~kIsPersistent;
+ tentative_histogram = new BooleanHistogram(name, registered_ranges);
+ }
tentative_histogram->SetFlags(flags);
histogram =
StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
+
+ // Persistent histograms need some follow-up processing.
+ if (histogram_ref) {
+ // If the created persistent histogram is canonical then it needs to be
+ // marked as "iterable" in order to be found by other processes.
+ if (histogram == tentative_histogram)
+ GetDefaultPersistentMemoryAllocator()->MakeIterable(histogram_ref);
+ // If it's not the canonical one then a race condition must have caused
+ // two to be created. The allocator does not support releasing the
+ // acquired memory so just change the type to be empty.
+ else
+ GetDefaultPersistentMemoryAllocator()->SetType(histogram_ref, 0);
+ }
Alexei Svitkine (slow) 2015/12/04 18:27:36 The code from 817 to 850 is repeated in several pl
bcwhite 2015/12/07 23:27:19 Done.
}
DCHECK_EQ(BOOLEAN_HISTOGRAM, histogram->GetHistogramType());
@@ -740,6 +866,12 @@ BooleanHistogram::BooleanHistogram(const std::string& name,
const BucketRanges* ranges)
: LinearHistogram(name, 1, 2, ranges) {}
+BooleanHistogram::BooleanHistogram(const std::string& name,
+ const BucketRanges* ranges,
+ HistogramBase::AtomicCount* counts,
+ HistogramSamples::Metadata* meta)
+ : LinearHistogram(name, 1, 2, ranges, counts, 2, meta) {}
+
HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) {
std::string histogram_name;
int flags;
@@ -771,21 +903,50 @@ HistogramBase* CustomHistogram::FactoryGet(
const std::vector<Sample>& custom_ranges,
int32 flags) {
CHECK(ValidateCustomRanges(custom_ranges));
+ ImportPersistentHistograms();
HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
if (!histogram) {
+ // To avoid racy destruction at shutdown, the following will be leaked.
BucketRanges* ranges = CreateBucketRangesFromCustomRanges(custom_ranges);
const BucketRanges* registered_ranges =
StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
- // To avoid racy destruction at shutdown, the following will be leaked.
- CustomHistogram* tentative_histogram =
- new CustomHistogram(name, registered_ranges);
+ PersistentMemoryAllocator::Reference histogram_ref = 0;
+ HistogramBase* tentative_histogram = nullptr;
+ if (allocator_) {
+ flags |= kIsPersistent;
+ tentative_histogram = AllocatePersistentHistogram(
+ GetDefaultPersistentMemoryAllocator(),
+ CUSTOM_HISTOGRAM,
+ name,
+ registered_ranges->range(1),
+ registered_ranges->range(registered_ranges->bucket_count() - 1),
+ registered_ranges,
+ flags,
+ &histogram_ref);
+ }
+ if (!tentative_histogram) {
+ flags &= ~kIsPersistent;
+ tentative_histogram = new CustomHistogram(name, registered_ranges);
+ }
tentative_histogram->SetFlags(flags);
-
histogram =
StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
+
+ // Persistent histograms need some follow-up processing.
+ if (histogram_ref) {
+ // If the created persistent histogram is canonical then it needs to be
+ // marked as "iterable" in order to be found by other processes.
+ if (histogram == tentative_histogram)
+ GetDefaultPersistentMemoryAllocator()->MakeIterable(histogram_ref);
+ // If it's not the canonical one then a race condition must have caused
+ // two to be created. The allocator does not support releasing the
+ // acquired memory so just change the type to be empty.
+ else
+ GetDefaultPersistentMemoryAllocator()->SetType(histogram_ref, 0);
+ }
}
DCHECK_EQ(histogram->GetHistogramType(), CUSTOM_HISTOGRAM);
@@ -825,6 +986,19 @@ CustomHistogram::CustomHistogram(const std::string& name,
ranges->range(ranges->bucket_count() - 1),
ranges) {}
+CustomHistogram::CustomHistogram(const std::string& name,
+ const BucketRanges* ranges,
+ HistogramBase::AtomicCount* counts,
+ size_t counts_size,
+ HistogramSamples::Metadata* meta)
+ : Histogram(name,
+ ranges->range(1),
+ ranges->range(ranges->bucket_count() - 1),
+ ranges,
+ counts,
+ counts_size,
+ meta) {}
+
bool CustomHistogram::SerializeInfoImpl(Pickle* pickle) const {
if (!Histogram::SerializeInfoImpl(pickle))
return false;

Powered by Google App Engine
This is Rietveld 408576698