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

Unified Diff: base/metrics/histogram.cc

Issue 6780035: Use lock-free lazy initialization for static histogram references (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 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
« no previous file with comments | « base/metrics/histogram.h ('k') | base/metrics/histogram_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/metrics/histogram.cc
===================================================================
--- base/metrics/histogram.cc (revision 80382)
+++ base/metrics/histogram.cc (working copy)
@@ -73,9 +73,12 @@
// static
const size_t Histogram::kBucketCount_MAX = 16384u;
-scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name,
- Sample minimum, Sample maximum, size_t bucket_count, Flags flags) {
- scoped_refptr<Histogram> histogram(NULL);
+Histogram* Histogram::FactoryGet(const std::string& name,
+ Sample minimum,
+ Sample maximum,
+ size_t bucket_count,
+ Flags flags) {
+ Histogram* histogram(NULL);
// Defensive code.
if (minimum < 1)
@@ -84,10 +87,16 @@
maximum = kSampleType_MAX - 1;
if (!StatisticsRecorder::FindHistogram(name, &histogram)) {
- histogram = new Histogram(name, minimum, maximum, bucket_count);
- histogram->InitializeBucketRange();
- histogram->SetFlags(flags);
- StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram);
+ // Extra variable is not needed... but this keeps this section basically
+ // identical to other derived classes in this file (and compiler will
+ // optimize away the extra variable.
+ // To avoid racy destruction at shutdown, the following will be leaked.
+ Histogram* tentative_histogram =
+ new Histogram(name, minimum, maximum, bucket_count);
+ tentative_histogram->InitializeBucketRange();
+ tentative_histogram->SetFlags(flags);
+ histogram =
+ StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
}
DCHECK_EQ(HISTOGRAM, histogram->histogram_type());
@@ -95,11 +104,11 @@
return histogram;
}
-scoped_refptr<Histogram> Histogram::FactoryTimeGet(const std::string& name,
- TimeDelta minimum,
- TimeDelta maximum,
- size_t bucket_count,
- Flags flags) {
+Histogram* Histogram::FactoryTimeGet(const std::string& name,
+ TimeDelta minimum,
+ TimeDelta maximum,
+ size_t bucket_count,
+ Flags flags) {
return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
bucket_count, flags);
}
@@ -259,7 +268,7 @@
DCHECK_NE(NOT_VALID_IN_RENDERER, histogram_type);
- scoped_refptr<Histogram> render_histogram(NULL);
+ Histogram* render_histogram(NULL);
if (histogram_type == HISTOGRAM) {
render_histogram = Histogram::FactoryGet(
@@ -761,12 +770,12 @@
LinearHistogram::~LinearHistogram() {
}
-scoped_refptr<Histogram> LinearHistogram::FactoryGet(const std::string& name,
- Sample minimum,
- Sample maximum,
- size_t bucket_count,
- Flags flags) {
- scoped_refptr<Histogram> histogram(NULL);
+Histogram* LinearHistogram::FactoryGet(const std::string& name,
+ Sample minimum,
+ Sample maximum,
+ size_t bucket_count,
+ Flags flags) {
+ Histogram* histogram(NULL);
if (minimum < 1)
minimum = 1;
@@ -774,12 +783,13 @@
maximum = kSampleType_MAX - 1;
if (!StatisticsRecorder::FindHistogram(name, &histogram)) {
- LinearHistogram* linear_histogram =
+ // To avoid racy destruction at shutdown, the following will be leaked.
+ LinearHistogram* tentative_histogram =
new LinearHistogram(name, minimum, maximum, bucket_count);
- linear_histogram->InitializeBucketRange();
- histogram = linear_histogram;
- histogram->SetFlags(flags);
- StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram);
+ tentative_histogram->InitializeBucketRange();
+ tentative_histogram->SetFlags(flags);
+ histogram =
+ StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
}
DCHECK_EQ(LINEAR_HISTOGRAM, histogram->histogram_type());
@@ -787,12 +797,11 @@
return histogram;
}
-scoped_refptr<Histogram> LinearHistogram::FactoryTimeGet(
- const std::string& name,
- TimeDelta minimum,
- TimeDelta maximum,
- size_t bucket_count,
- Flags flags) {
+Histogram* LinearHistogram::FactoryTimeGet(const std::string& name,
+ TimeDelta minimum,
+ TimeDelta maximum,
+ size_t bucket_count,
+ Flags flags) {
return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
bucket_count, flags);
}
@@ -862,16 +871,16 @@
// This section provides implementation for BooleanHistogram.
//------------------------------------------------------------------------------
-scoped_refptr<Histogram> BooleanHistogram::FactoryGet(const std::string& name,
- Flags flags) {
- scoped_refptr<Histogram> histogram(NULL);
+Histogram* BooleanHistogram::FactoryGet(const std::string& name, Flags flags) {
+ Histogram* histogram(NULL);
if (!StatisticsRecorder::FindHistogram(name, &histogram)) {
- BooleanHistogram* boolean_histogram = new BooleanHistogram(name);
- boolean_histogram->InitializeBucketRange();
- histogram = boolean_histogram;
- histogram->SetFlags(flags);
- StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram);
+ // To avoid racy destruction at shutdown, the following will be leaked.
+ BooleanHistogram* tentative_histogram = new BooleanHistogram(name);
+ tentative_histogram->InitializeBucketRange();
+ tentative_histogram->SetFlags(flags);
+ histogram =
+ StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
}
DCHECK_EQ(BOOLEAN_HISTOGRAM, histogram->histogram_type());
@@ -894,11 +903,10 @@
// CustomHistogram:
//------------------------------------------------------------------------------
-scoped_refptr<Histogram> CustomHistogram::FactoryGet(
- const std::string& name,
- const std::vector<Sample>& custom_ranges,
- Flags flags) {
- scoped_refptr<Histogram> histogram(NULL);
+Histogram* CustomHistogram::FactoryGet(const std::string& name,
+ const std::vector<Sample>& custom_ranges,
+ Flags flags) {
+ Histogram* histogram(NULL);
// Remove the duplicates in the custom ranges array.
std::vector<int> ranges = custom_ranges;
@@ -914,11 +922,12 @@
DCHECK_LT(ranges.back(), kSampleType_MAX);
if (!StatisticsRecorder::FindHistogram(name, &histogram)) {
- CustomHistogram* custom_histogram = new CustomHistogram(name, ranges);
- custom_histogram->InitializedCustomBucketRange(ranges);
- histogram = custom_histogram;
- histogram->SetFlags(flags);
- StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram);
+ // To avoid racy destruction at shutdown, the following will be leaked.
+ CustomHistogram* tentative_histogram = new CustomHistogram(name, ranges);
+ tentative_histogram->InitializedCustomBucketRange(ranges);
+ tentative_histogram->SetFlags(flags);
+ histogram =
+ StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
}
DCHECK_EQ(histogram->histogram_type(), CUSTOM_HISTOGRAM);
@@ -1004,27 +1013,23 @@
return NULL != histograms_;
}
-// Note: We can't accept a ref_ptr to |histogram| because we *might* not keep a
-// reference, and we are called while in the Histogram constructor. In that
-// scenario, a ref_ptr would have incremented the ref count when the histogram
-// was passed to us, decremented it when we returned, and the instance would be
-// destroyed before assignment (when value was returned by new).
-// static
-void StatisticsRecorder::RegisterOrDiscardDuplicate(
- scoped_refptr<Histogram>* histogram) {
- DCHECK((*histogram)->HasValidRangeChecksum());
+Histogram* StatisticsRecorder::RegisterOrDeleteDuplicate(Histogram* histogram) {
+ DCHECK(histogram->HasValidRangeChecksum());
if (lock_ == NULL)
- return;
+ return histogram;
base::AutoLock auto_lock(*lock_);
if (!histograms_)
- return;
- const std::string name = (*histogram)->histogram_name();
+ return histogram;
+ const std::string name = histogram->histogram_name();
HistogramMap::iterator it = histograms_->find(name);
// Avoid overwriting a previous registration.
- if (histograms_->end() == it)
- (*histograms_)[name] = *histogram;
- else
- *histogram = it->second;
+ if (histograms_->end() == it) {
+ (*histograms_)[name] = histogram;
+ } else {
+ delete histogram; // We already have one by this name.
+ histogram = it->second;
+ }
+ return histogram;
}
// static
@@ -1087,7 +1092,7 @@
}
bool StatisticsRecorder::FindHistogram(const std::string& name,
- scoped_refptr<Histogram>* histogram) {
+ Histogram** histogram) {
if (lock_ == NULL)
return false;
base::AutoLock auto_lock(*lock_);
« no previous file with comments | « base/metrics/histogram.h ('k') | base/metrics/histogram_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698