diff options
author | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-05 04:48:53 +0000 |
---|---|---|
committer | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-05 04:48:53 +0000 |
commit | 81ce9f3b1eb34dc7f6954f0f6657a76b0f01fc12 (patch) | |
tree | 41b3caf1a55ba3cfa2f6cf13b0a5ce3d773d631f | |
parent | 4f7f4854821e8e4933ad2c662bfd9417eb604a68 (diff) | |
download | chromium_src-81ce9f3b1eb34dc7f6954f0f6657a76b0f01fc12.zip chromium_src-81ce9f3b1eb34dc7f6954f0f6657a76b0f01fc12.tar.gz chromium_src-81ce9f3b1eb34dc7f6954f0f6657a76b0f01fc12.tar.bz2 |
Use lock-free lazy initialization for static histogram references
Make all histogram macros thread safe, and fast by again
using statics to achieve performance.
...at the cost of:
Leak all histograms to avoid races at shutdown.
Also included leak suppression for valgrind.
r=rtenneti
BUG=78207
Review URL: http://codereview.chromium.org/6780035
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80412 0039d316-1c4b-4281-b951-d872f2087c98
34 files changed, 380 insertions, 330 deletions
diff --git a/base/message_loop.cc b/base/message_loop.cc index 39881d1..1154c3e 100644 --- a/base/message_loop.cc +++ b/base/message_loop.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -122,6 +122,7 @@ MessageLoop::MessageLoop(Type type) : type_(type), nestable_tasks_allowed_(true), exception_restoration_(false), + message_histogram_(NULL), state_(NULL), #ifdef OS_WIN os_modal_loop_(false), @@ -531,7 +532,7 @@ void MessageLoop::PostTask_Helper( // on each thread. void MessageLoop::StartHistogrammer() { - if (enable_histogrammer_ && !message_histogram_.get() + if (enable_histogrammer_ && !message_histogram_ && base::StatisticsRecorder::IsActive()) { DCHECK(!thread_name_.empty()); message_histogram_ = base::LinearHistogram::FactoryGet( @@ -544,7 +545,7 @@ void MessageLoop::StartHistogrammer() { } void MessageLoop::HistogramEvent(int event) { - if (message_histogram_.get()) + if (message_histogram_) message_histogram_->Add(event); } diff --git a/base/message_loop.h b/base/message_loop.h index 7da04d3..519e4a3 100644 --- a/base/message_loop.h +++ b/base/message_loop.h @@ -473,7 +473,7 @@ class BASE_API MessageLoop : public base::MessagePump::Delegate { std::string thread_name_; // A profiling histogram showing the counts of various messages and events. - scoped_refptr<base::Histogram> message_histogram_; + base::Histogram* message_histogram_; // A null terminated list which creates an incoming_queue of tasks that are // acquired under a mutex for processing on this instance's thread. These diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc index bf765c2..4262853 100644 --- a/base/metrics/histogram.cc +++ b/base/metrics/histogram.cc @@ -73,9 +73,12 @@ typedef Histogram::Count Count; // 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 @@ scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name, 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 @@ scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name, 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 @@ bool Histogram::DeserializeHistogramInfo(const std::string& histogram_info) { 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 @@ bool Histogram::SampleSet::Deserialize(void** iter, const Pickle& pickle) { 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 @@ scoped_refptr<Histogram> LinearHistogram::FactoryGet(const std::string& name, 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 @@ scoped_refptr<Histogram> LinearHistogram::FactoryGet(const std::string& name, 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 @@ bool LinearHistogram::PrintEmptyBucket(size_t index) const { // 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 @@ BooleanHistogram::BooleanHistogram(const std::string& name) // 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 @@ scoped_refptr<Histogram> CustomHistogram::FactoryGet( 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 @@ bool StatisticsRecorder::IsActive() { 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 @@ void StatisticsRecorder::GetHistograms(Histograms* output) { } bool StatisticsRecorder::FindHistogram(const std::string& name, - scoped_refptr<Histogram>* histogram) { + Histogram** histogram) { if (lock_ == NULL) return false; base::AutoLock auto_lock(*lock_); diff --git a/base/metrics/histogram.h b/base/metrics/histogram.h index be375dff..b7ae10a 100644 --- a/base/metrics/histogram.h +++ b/base/metrics/histogram.h @@ -28,6 +28,15 @@ // at the low end of the histogram scale, but allows the histogram to cover a // gigantic range with the addition of very few buckets. +// Histograms use a pattern involving a function static variable, that is a +// pointer to a histogram. This static is explicitly initialized on any thread +// that detects a uninitialized (NULL) pointer. The potentially racy +// initialization is not a problem as it is always set to point to the same +// value (i.e., the FactoryGet always returns the same value). FactoryGet +// is also completely thread safe, which results in a completely thread safe, +// and relatively fast, set of counters. To avoid races at shutdown, the static +// pointer is NOT deleted, and we leak the histograms at process termination. + #ifndef BASE_METRICS_HISTOGRAM_H_ #define BASE_METRICS_HISTOGRAM_H_ #pragma once @@ -39,7 +48,6 @@ #include "base/base_api.h" #include "base/gtest_prod_util.h" #include "base/logging.h" -#include "base/memory/ref_counted.h" #include "base/time.h" class Pickle; @@ -66,11 +74,12 @@ class Lock; name, sample, 1, 10000, 50) #define HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \ - scoped_refptr<base::Histogram> counter = \ - base::Histogram::FactoryGet(name, min, max, bucket_count, \ - base::Histogram::kNoFlags); \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryGet(name, min, max, bucket_count, \ + base::Histogram::kNoFlags); \ DCHECK_EQ(name, counter->histogram_name()); \ - if (counter.get()) counter->Add(sample); \ + counter->Add(sample); \ } while (0) #define HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ @@ -79,40 +88,43 @@ class Lock; // For folks that need real specific times, use this to select a precise range // of times you want plotted, and the number of buckets you want used. #define HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \ - scoped_refptr<base::Histogram> counter = \ - base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ - base::Histogram::kNoFlags); \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ + base::Histogram::kNoFlags); \ DCHECK_EQ(name, counter->histogram_name()); \ - if (counter.get()) counter->AddTime(sample); \ + counter->AddTime(sample); \ } while (0) // DO NOT USE THIS. It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES. #define HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \ - scoped_refptr<base::Histogram> counter = \ - base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ - base::Histogram::kNoFlags); \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ + base::Histogram::kNoFlags); \ DCHECK_EQ(name, counter->histogram_name()); \ - if ((sample) < (max) && counter.get()) counter->AddTime(sample); \ + if ((sample) < (max)) counter->AddTime(sample); \ } while (0) // Support histograming of an enumerated value. The samples should always be // less than boundary_value. #define HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \ - scoped_refptr<base::Histogram> counter = \ - base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ - boundary_value + 1, \ - base::Histogram::kNoFlags); \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ + boundary_value + 1, base::Histogram::kNoFlags); \ DCHECK_EQ(name, counter->histogram_name()); \ - if (counter.get()) counter->Add(sample); \ + counter->Add(sample); \ } while (0) #define HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) do { \ - scoped_refptr<base::Histogram> counter = \ - base::CustomHistogram::FactoryGet(name, custom_ranges, \ - base::Histogram::kNoFlags); \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::CustomHistogram::FactoryGet(name, custom_ranges, \ + base::Histogram::kNoFlags); \ DCHECK_EQ(name, counter->histogram_name()); \ - if (counter.get()) counter->Add(sample); \ + counter->Add(sample); \ } while (0) @@ -172,20 +184,22 @@ class Lock; base::TimeDelta::FromHours(1), 50) #define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \ - scoped_refptr<base::Histogram> counter = \ - base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ base::Histogram::kUmaTargetedHistogramFlag); \ DCHECK_EQ(name, counter->histogram_name()); \ - if (counter.get()) counter->AddTime(sample); \ + counter->AddTime(sample); \ } while (0) // DO NOT USE THIS. It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES. #define UMA_HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \ - scoped_refptr<base::Histogram> counter = \ - base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ - base::Histogram::kUmaTargetedHistogramFlag); \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ + base::Histogram::kUmaTargetedHistogramFlag); \ DCHECK_EQ(name, counter->histogram_name()); \ - if ((sample) < (max) && counter.get()) counter->AddTime(sample); \ + if ((sample) < (max)) counter->AddTime(sample); \ } while (0) #define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ @@ -198,11 +212,12 @@ class Lock; name, sample, 1, 10000, 50) #define UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \ - scoped_refptr<base::Histogram> counter = \ - base::Histogram::FactoryGet(name, min, max, bucket_count, \ - base::Histogram::kUmaTargetedHistogramFlag); \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::Histogram::FactoryGet(name, min, max, bucket_count, \ + base::Histogram::kUmaTargetedHistogramFlag); \ DCHECK_EQ(name, counter->histogram_name()); \ - if (counter.get()) counter->Add(sample); \ + counter->Add(sample); \ } while (0) #define UMA_HISTOGRAM_MEMORY_KB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ @@ -215,19 +230,21 @@ class Lock; UMA_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) #define UMA_HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \ - scoped_refptr<base::Histogram> counter = \ - base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ - boundary_value + 1, base::Histogram::kUmaTargetedHistogramFlag); \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ + boundary_value + 1, base::Histogram::kUmaTargetedHistogramFlag); \ DCHECK_EQ(name, counter->histogram_name()); \ - if (counter.get()) counter->Add(sample); \ + counter->Add(sample); \ } while (0) #define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) do { \ - scoped_refptr<base::Histogram> counter = \ - base::CustomHistogram::FactoryGet(name, custom_ranges, \ - base::Histogram::kUmaTargetedHistogramFlag); \ + static base::Histogram* counter(NULL); \ + if (!counter) \ + counter = base::CustomHistogram::FactoryGet(name, custom_ranges, \ + base::Histogram::kUmaTargetedHistogramFlag); \ DCHECK_EQ(name, counter->histogram_name()); \ - if (counter.get()) counter->Add(sample); \ + counter->Add(sample); \ } while (0) //------------------------------------------------------------------------------ @@ -237,7 +254,7 @@ class CustomHistogram; class Histogram; class LinearHistogram; -class BASE_API Histogram : public base::RefCountedThreadSafe<Histogram> { +class BASE_API Histogram { public: typedef int Sample; // Used for samples (and ranges of samples). typedef int Count; // Used to count samples in a bucket. @@ -347,11 +364,16 @@ class BASE_API Histogram : public base::RefCountedThreadSafe<Histogram> { //---------------------------------------------------------------------------- // minimum should start from 1. 0 is invalid as a minimum. 0 is an implicit // default underflow bucket. - static scoped_refptr<Histogram> FactoryGet(const std::string& name, - Sample minimum, Sample maximum, size_t bucket_count, Flags flags); - static scoped_refptr<Histogram> FactoryTimeGet(const std::string& name, - base::TimeDelta minimum, base::TimeDelta maximum, size_t bucket_count, - Flags flags); + static Histogram* FactoryGet(const std::string& name, + Sample minimum, + Sample maximum, + size_t bucket_count, + Flags flags); + static Histogram* FactoryTimeGet(const std::string& name, + base::TimeDelta minimum, + base::TimeDelta maximum, + size_t bucket_count, + Flags flags); void Add(int value); @@ -426,7 +448,6 @@ class BASE_API Histogram : public base::RefCountedThreadSafe<Histogram> { bool HasValidRangeChecksum() const; protected: - friend class base::RefCountedThreadSafe<Histogram>; Histogram(const std::string& name, Sample minimum, Sample maximum, size_t bucket_count); Histogram(const std::string& name, TimeDelta minimum, @@ -480,6 +501,8 @@ class BASE_API Histogram : public base::RefCountedThreadSafe<Histogram> { FRIEND_TEST(HistogramTest, Crc32SampleHash); FRIEND_TEST(HistogramTest, Crc32TableTest); + friend class StatisticsRecorder; // To allow it to delete duplicates. + // Post constructor initialization. void Initialize(); @@ -555,11 +578,16 @@ class BASE_API LinearHistogram : public Histogram { /* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit default underflow bucket. */ - static scoped_refptr<Histogram> FactoryGet(const std::string& name, - Sample minimum, Sample maximum, size_t bucket_count, Flags flags); - static scoped_refptr<Histogram> FactoryTimeGet(const std::string& name, - TimeDelta minimum, TimeDelta maximum, size_t bucket_count, - Flags flags); + static Histogram* FactoryGet(const std::string& name, + Sample minimum, + Sample maximum, + size_t bucket_count, + Flags flags); + static Histogram* FactoryTimeGet(const std::string& name, + TimeDelta minimum, + TimeDelta maximum, + size_t bucket_count, + Flags flags); // Overridden from Histogram: virtual ClassType histogram_type() const; @@ -602,8 +630,7 @@ class BASE_API LinearHistogram : public Histogram { // BooleanHistogram is a histogram for booleans. class BASE_API BooleanHistogram : public LinearHistogram { public: - static scoped_refptr<Histogram> FactoryGet(const std::string& name, - Flags flags); + static Histogram* FactoryGet(const std::string& name, Flags flags); virtual ClassType histogram_type() const; @@ -621,8 +648,9 @@ class BASE_API BooleanHistogram : public LinearHistogram { class BASE_API CustomHistogram : public Histogram { public: - static scoped_refptr<Histogram> FactoryGet(const std::string& name, - const std::vector<Sample>& custom_ranges, Flags flags); + static Histogram* FactoryGet(const std::string& name, + const std::vector<Sample>& custom_ranges, + Flags flags); // Overridden from Histogram: virtual ClassType histogram_type() const; @@ -645,7 +673,7 @@ class BASE_API CustomHistogram : public Histogram { class BASE_API StatisticsRecorder { public: - typedef std::vector<scoped_refptr<Histogram> > Histograms; + typedef std::vector<Histogram*> Histograms; StatisticsRecorder(); @@ -656,9 +684,9 @@ class BASE_API StatisticsRecorder { // Register, or add a new histogram to the collection of statistics. If an // identically named histogram is already registered, then the argument - // |histogram| will be replaced by the previously registered value, discarding - // the referenced argument. - static void RegisterOrDiscardDuplicate(scoped_refptr<Histogram>* histogram); + // |histogram| will deleted. The returned value is always the registered + // histogram (either the argument, or the pre-existing registered histogram). + static Histogram* RegisterOrDeleteDuplicate(Histogram* histogram); // Methods for printing histograms. Only histograms which have query as // a substring are written to output (an empty string will process all @@ -672,8 +700,7 @@ class BASE_API StatisticsRecorder { // Find a histogram by name. It matches the exact name. This method is thread // safe. If a matching histogram is not found, then the |histogram| is // not changed. - static bool FindHistogram(const std::string& query, - scoped_refptr<Histogram>* histogram); + static bool FindHistogram(const std::string& query, Histogram** histogram); static bool dump_on_exit() { return dump_on_exit_; } @@ -688,7 +715,7 @@ class BASE_API StatisticsRecorder { private: // We keep all registered histograms in a map, from name to histogram. - typedef std::map<std::string, scoped_refptr<Histogram> > HistogramMap; + typedef std::map<std::string, Histogram*> HistogramMap; static HistogramMap* histograms_; diff --git a/base/metrics/histogram_unittest.cc b/base/metrics/histogram_unittest.cc index afa69a6..496ff63 100644 --- a/base/metrics/histogram_unittest.cc +++ b/base/metrics/histogram_unittest.cc @@ -1,10 +1,11 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Test of Histogram class #include "base/metrics/histogram.h" +#include "base/scoped_ptr.h" #include "base/time.h" #include "testing/gtest/include/gtest/gtest.h" @@ -17,15 +18,22 @@ class HistogramTest : public testing::Test { // Check for basic syntax and use. TEST(HistogramTest, StartupShutdownTest) { // Try basic construction - scoped_refptr<Histogram> histogram = Histogram::FactoryGet( - "TestHistogram", 1, 1000, 10, Histogram::kNoFlags); - scoped_refptr<Histogram> histogram1 = Histogram::FactoryGet( - "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags); - - scoped_refptr<Histogram> linear_histogram = LinearHistogram::FactoryGet( - "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags); - scoped_refptr<Histogram> linear_histogram1 = LinearHistogram::FactoryGet( - "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags); + Histogram* histogram(Histogram::FactoryGet( + "TestHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram); + Histogram* histogram1(Histogram::FactoryGet( + "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram1); + EXPECT_NE(histogram, histogram1); + + + Histogram* linear_histogram(LinearHistogram::FactoryGet( + "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram); + Histogram* linear_histogram1(LinearHistogram::FactoryGet( + "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram1); + EXPECT_NE(linear_histogram, linear_histogram1); std::vector<int> custom_ranges; custom_ranges.push_back(1); @@ -33,10 +41,12 @@ TEST(HistogramTest, StartupShutdownTest) { custom_ranges.push_back(10); custom_ranges.push_back(20); custom_ranges.push_back(30); - scoped_refptr<Histogram> custom_histogram = CustomHistogram::FactoryGet( - "TestCustomHistogram", custom_ranges, Histogram::kNoFlags); - scoped_refptr<Histogram> custom_histogram1 = CustomHistogram::FactoryGet( - "Test1CustomHistogram", custom_ranges, Histogram::kNoFlags); + Histogram* custom_histogram(CustomHistogram::FactoryGet( + "TestCustomHistogram", custom_ranges, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram); + Histogram* custom_histogram1(CustomHistogram::FactoryGet( + "Test1CustomHistogram", custom_ranges, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram1); // Use standard macros (but with fixed samples) HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1)); @@ -70,25 +80,29 @@ TEST(HistogramTest, RecordedStartupTest) { EXPECT_EQ(0U, histograms.size()); // Try basic construction - scoped_refptr<Histogram> histogram = Histogram::FactoryGet( - "TestHistogram", 1, 1000, 10, Histogram::kNoFlags); + Histogram* histogram(Histogram::FactoryGet( + "TestHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists EXPECT_EQ(1U, histograms.size()); - scoped_refptr<Histogram> histogram1 = Histogram::FactoryGet( - "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags); + Histogram* histogram1(Histogram::FactoryGet( + "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram1); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists EXPECT_EQ(2U, histograms.size()); - scoped_refptr<Histogram> linear_histogram = LinearHistogram::FactoryGet( - "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags); + Histogram* linear_histogram(LinearHistogram::FactoryGet( + "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists EXPECT_EQ(3U, histograms.size()); - scoped_refptr<Histogram> linear_histogram1 = LinearHistogram::FactoryGet( - "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags); + Histogram* linear_histogram1(LinearHistogram::FactoryGet( + "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram1); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists EXPECT_EQ(4U, histograms.size()); @@ -99,10 +113,12 @@ TEST(HistogramTest, RecordedStartupTest) { custom_ranges.push_back(10); custom_ranges.push_back(20); custom_ranges.push_back(30); - scoped_refptr<Histogram> custom_histogram = CustomHistogram::FactoryGet( - "TestCustomHistogram", custom_ranges, Histogram::kNoFlags); - scoped_refptr<Histogram> custom_histogram1 = CustomHistogram::FactoryGet( - "TestCustomHistogram", custom_ranges, Histogram::kNoFlags); + Histogram* custom_histogram(CustomHistogram::FactoryGet( + "TestCustomHistogram", custom_ranges, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram); + Histogram* custom_histogram1(CustomHistogram::FactoryGet( + "TestCustomHistogram", custom_ranges, Histogram::kNoFlags)); + EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram1); histograms.clear(); StatisticsRecorder::GetHistograms(&histograms); // Load up lists @@ -138,8 +154,8 @@ TEST(HistogramTest, RangeTest) { recorder.GetHistograms(&histograms); EXPECT_EQ(0U, histograms.size()); - scoped_refptr<Histogram> histogram = Histogram::FactoryGet( - "Histogram", 1, 64, 8, Histogram::kNoFlags); // As per header file. + Histogram* histogram(Histogram::FactoryGet( + "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. // Check that we got a nice exponential when there was enough rooom. EXPECT_EQ(0, histogram->ranges(0)); int power_of_2 = 1; @@ -149,31 +165,30 @@ TEST(HistogramTest, RangeTest) { } EXPECT_EQ(INT_MAX, histogram->ranges(8)); - scoped_refptr<Histogram> short_histogram = Histogram::FactoryGet( - "Histogram Shortened", 1, 7, 8, Histogram::kNoFlags); + Histogram* short_histogram(Histogram::FactoryGet( + "Histogram Shortened", 1, 7, 8, Histogram::kNoFlags)); // Check that when the number of buckets is short, we get a linear histogram // for lack of space to do otherwise. for (int i = 0; i < 8; i++) EXPECT_EQ(i, short_histogram->ranges(i)); EXPECT_EQ(INT_MAX, short_histogram->ranges(8)); - scoped_refptr<Histogram> linear_histogram = LinearHistogram::FactoryGet( - "Linear", 1, 7, 8, Histogram::kNoFlags); + Histogram* linear_histogram(LinearHistogram::FactoryGet( + "Linear", 1, 7, 8, Histogram::kNoFlags)); // We also get a nice linear set of bucket ranges when we ask for it for (int i = 0; i < 8; i++) EXPECT_EQ(i, linear_histogram->ranges(i)); EXPECT_EQ(INT_MAX, linear_histogram->ranges(8)); - scoped_refptr<Histogram> linear_broad_histogram = LinearHistogram::FactoryGet( - "Linear widened", 2, 14, 8, Histogram::kNoFlags); + Histogram* linear_broad_histogram(LinearHistogram::FactoryGet( + "Linear widened", 2, 14, 8, Histogram::kNoFlags)); // ...but when the list has more space, then the ranges naturally spread out. for (int i = 0; i < 8; i++) EXPECT_EQ(2 * i, linear_broad_histogram->ranges(i)); EXPECT_EQ(INT_MAX, linear_broad_histogram->ranges(8)); - scoped_refptr<Histogram> transitioning_histogram = - Histogram::FactoryGet("LinearAndExponential", 1, 32, 15, - Histogram::kNoFlags); + Histogram* transitioning_histogram(Histogram::FactoryGet( + "LinearAndExponential", 1, 32, 15, Histogram::kNoFlags)); // When space is a little tight, we transition from linear to exponential. EXPECT_EQ(0, transitioning_histogram->ranges(0)); EXPECT_EQ(1, transitioning_histogram->ranges(1)); @@ -198,8 +213,8 @@ TEST(HistogramTest, RangeTest) { custom_ranges.push_back(10); custom_ranges.push_back(11); custom_ranges.push_back(300); - scoped_refptr<Histogram> test_custom_histogram = CustomHistogram::FactoryGet( - "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags); + Histogram* test_custom_histogram(CustomHistogram::FactoryGet( + "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags)); EXPECT_EQ(custom_ranges[0], test_custom_histogram->ranges(0)); EXPECT_EQ(custom_ranges[1], test_custom_histogram->ranges(1)); @@ -221,8 +236,8 @@ TEST(HistogramTest, CustomRangeTest) { custom_ranges.push_back(9); custom_ranges.push_back(10); custom_ranges.push_back(11); - scoped_refptr<Histogram> test_custom_histogram = CustomHistogram::FactoryGet( - "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags); + Histogram* test_custom_histogram(CustomHistogram::FactoryGet( + "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags)); EXPECT_EQ(0, test_custom_histogram->ranges(0)); // Auto added EXPECT_EQ(custom_ranges[0], test_custom_histogram->ranges(1)); @@ -242,8 +257,8 @@ TEST(HistogramTest, CustomRangeTest) { custom_ranges.push_back(0); // Push an explicit zero. custom_ranges.push_back(kBig); - scoped_refptr<Histogram> unsorted_histogram = CustomHistogram::FactoryGet( - "TestCustomUnsortedDupedHistogram", custom_ranges, Histogram::kNoFlags); + Histogram* unsorted_histogram(CustomHistogram::FactoryGet( + "TestCustomUnsortedDupedHistogram", custom_ranges, Histogram::kNoFlags)); EXPECT_EQ(0, unsorted_histogram->ranges(0)); EXPECT_EQ(kSmall, unsorted_histogram->ranges(1)); EXPECT_EQ(kMid, unsorted_histogram->ranges(2)); @@ -254,8 +269,8 @@ TEST(HistogramTest, CustomRangeTest) { // Make sure histogram handles out-of-bounds data gracefully. TEST(HistogramTest, BoundsTest) { const size_t kBucketCount = 50; - scoped_refptr<Histogram> histogram = Histogram::FactoryGet( - "Bounded", 10, 100, kBucketCount, Histogram::kNoFlags); + Histogram* histogram(Histogram::FactoryGet( + "Bounded", 10, 100, kBucketCount, Histogram::kNoFlags)); // Put two samples "out of bounds" above and below. histogram->Add(5); @@ -277,8 +292,8 @@ TEST(HistogramTest, BoundsTest) { // Check to be sure samples land as expected is "correct" buckets. TEST(HistogramTest, BucketPlacementTest) { - scoped_refptr<Histogram> histogram = Histogram::FactoryGet( - "Histogram", 1, 64, 8, Histogram::kNoFlags); // As per header file. + Histogram* histogram(Histogram::FactoryGet( + "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. // Check that we got a nice exponential since there was enough rooom. EXPECT_EQ(0, histogram->ranges(0)); @@ -314,8 +329,8 @@ TEST(HistogramTest, BucketPlacementTest) { // out to the base namespace here. We need to be friends to corrupt the // internals of the histogram and/or sampleset. TEST(HistogramTest, CorruptSampleCounts) { - scoped_refptr<Histogram> histogram = Histogram::FactoryGet( - "Histogram", 1, 64, 8, Histogram::kNoFlags); // As per header file. + Histogram* histogram(Histogram::FactoryGet( + "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. EXPECT_EQ(0, histogram->sample_.redundant_count()); histogram->Add(20); // Add some samples. @@ -339,8 +354,8 @@ TEST(HistogramTest, CorruptSampleCounts) { } TEST(HistogramTest, CorruptBucketBounds) { - scoped_refptr<Histogram> histogram = Histogram::FactoryGet( - "Histogram", 1, 64, 8, Histogram::kNoFlags); // As per header file. + Histogram* histogram(Histogram::FactoryGet( + "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file. Histogram::SampleSet snapshot; histogram->SnapshotSample(&snapshot); diff --git a/chrome/browser/autocomplete/autocomplete.cc b/chrome/browser/autocomplete/autocomplete.cc index 6d2c6c9..b076dc0 100644 --- a/chrome/browser/autocomplete/autocomplete.cc +++ b/chrome/browser/autocomplete/autocomplete.cc @@ -863,7 +863,7 @@ void AutocompleteController::Start( if (matches_requested == AutocompleteInput::ALL_MATCHES && text.size() < 6) { base::TimeTicks end_time = base::TimeTicks::Now(); std::string name = "Omnibox.QueryTime." + base::IntToString(text.size()); - scoped_refptr<base::Histogram> counter = base::Histogram::FactoryGet( + base::Histogram* counter = base::Histogram::FactoryGet( name, 1, 1000, 50, base::Histogram::kUmaTargetedHistogramFlag); counter->Add(static_cast<int>((end_time - start_time).InMilliseconds())); } diff --git a/chrome/browser/autocomplete/history_quick_provider.cc b/chrome/browser/autocomplete/history_quick_provider.cc index 778d345..8a7046a 100644 --- a/chrome/browser/autocomplete/history_quick_provider.cc +++ b/chrome/browser/autocomplete/history_quick_provider.cc @@ -71,7 +71,7 @@ void HistoryQuickProvider::Start(const AutocompleteInput& input, base::TimeTicks end_time = base::TimeTicks::Now(); std::string name = "HistoryQuickProvider.QueryIndexTime." + base::IntToString(input.text().size()); - scoped_refptr<base::Histogram> counter = base::Histogram::FactoryGet( + base::Histogram* counter = base::Histogram::FactoryGet( name, 1, 1000, 50, base::Histogram::kUmaTargetedHistogramFlag); counter->Add(static_cast<int>((end_time - start_time).InMilliseconds())); } diff --git a/chrome/browser/chromeos/boot_times_loader.cc b/chrome/browser/chromeos/boot_times_loader.cc index 4e08290..03359cf 100644 --- a/chrome/browser/chromeos/boot_times_loader.cc +++ b/chrome/browser/chromeos/boot_times_loader.cc @@ -259,7 +259,7 @@ void BootTimesLoader::WriteTimes( base::Time first = login_times.front().time(); base::Time last = login_times.back().time(); base::TimeDelta total = last - first; - scoped_refptr<base::Histogram>total_hist = base::Histogram::FactoryTimeGet( + base::Histogram* total_hist = base::Histogram::FactoryTimeGet( uma_name, base::TimeDelta::FromMilliseconds(kMinTimeMillis), base::TimeDelta::FromMilliseconds(kMaxTimeMillis), @@ -277,7 +277,7 @@ void BootTimesLoader::WriteTimes( if (tm.send_to_uma()) { name = uma_prefix + tm.name(); - scoped_refptr<base::Histogram>prev_hist = base::Histogram::FactoryTimeGet( + base::Histogram* prev_hist = base::Histogram::FactoryTimeGet( name, base::TimeDelta::FromMilliseconds(kMinTimeMillis), base::TimeDelta::FromMilliseconds(kMaxTimeMillis), diff --git a/chrome/browser/chromeos/cros/cros_library_loader.cc b/chrome/browser/chromeos/cros/cros_library_loader.cc index d631a6c..660bc2c 100644 --- a/chrome/browser/chromeos/cros/cros_library_loader.cc +++ b/chrome/browser/chromeos/cros/cros_library_loader.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -22,16 +22,14 @@ void addLibcrosTimeHistogram(const char* name, const base::TimeDelta& delta) { static const base::TimeDelta max_time = base::TimeDelta::FromSeconds(1); const size_t bucket_count(10); DCHECK(name); - scoped_refptr<base::Histogram> counter = base::Histogram::FactoryTimeGet( + base::Histogram* counter = base::Histogram::FactoryTimeGet( std::string(name), min_time, max_time, bucket_count, base::Histogram::kNoFlags); - if (counter.get()) { - counter->AddTime(delta); - VLOG(1) << "Cros Time: " << name << ": " << delta.InMilliseconds() << "ms."; - } + counter->AddTime(delta); + VLOG(1) << "Cros Time: " << name << ": " << delta.InMilliseconds() << "ms."; } } // namespace diff --git a/chrome/browser/chromeos/external_metrics.cc b/chrome/browser/chromeos/external_metrics.cc index edd48c0..830de18 100644 --- a/chrome/browser/chromeos/external_metrics.cc +++ b/chrome/browser/chromeos/external_metrics.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -86,7 +86,7 @@ void ExternalMetrics::RecordHistogram(const char* histogram_data) { } // Do not use the UMA_HISTOGRAM_... macros here. They cache the Histogram // instance and thus only work if |name| is constant. - scoped_refptr<base::Histogram> counter = base::Histogram::FactoryGet( + base::Histogram* counter = base::Histogram::FactoryGet( name, min, max, nbuckets, base::Histogram::kUmaTargetedHistogramFlag); counter->Add(sample); } @@ -101,7 +101,7 @@ void ExternalMetrics::RecordLinearHistogram(const char* histogram_data) { } // Do not use the UMA_HISTOGRAM_... macros here. They cache the Histogram // instance and thus only work if |name| is constant. - scoped_refptr<base::Histogram> counter = base::LinearHistogram::FactoryGet( + base::Histogram* counter = base::LinearHistogram::FactoryGet( name, 1, max, max + 1, base::Histogram::kUmaTargetedHistogramFlag); counter->Add(sample); } diff --git a/chrome/browser/extensions/extension_metrics_apitest.cc b/chrome/browser/extensions/extension_metrics_apitest.cc index ea5f9c6..522ea40 100644 --- a/chrome/browser/extensions/extension_metrics_apitest.cc +++ b/chrome/browser/extensions/extension_metrics_apitest.cc @@ -123,7 +123,7 @@ void ValidateHistograms(const Extension* extension, size_t j = 0; for (j = 0; j < histograms.size(); ++j) { - scoped_refptr<base::Histogram> histogram(histograms[j]); + base::Histogram* histogram(histograms[j]); if (name == histogram->histogram_name()) { EXPECT_EQ(r.type, histogram->histogram_type()); diff --git a/chrome/browser/extensions/extension_metrics_module.cc b/chrome/browser/extensions/extension_metrics_module.cc index a06d6fd..9681d84 100644 --- a/chrome/browser/extensions/extension_metrics_module.cc +++ b/chrome/browser/extensions/extension_metrics_module.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -75,7 +75,7 @@ bool MetricsHistogramHelperFunction::RecordValue(const std::string& name, size_t buckets, int sample) { std::string full_name = BuildMetricName(name, GetExtension()); - scoped_refptr<Histogram> counter; + Histogram* counter; if (type == Histogram::LINEAR_HISTOGRAM) { counter = LinearHistogram::FactoryGet(full_name, min, diff --git a/chrome/browser/jankometer.cc b/chrome/browser/jankometer.cc index 294860c..14be3be 100644 --- a/chrome/browser/jankometer.cc +++ b/chrome/browser/jankometer.cc @@ -119,8 +119,8 @@ class JankObserverHelper { // Counters for the two types of jank we measure. base::StatsCounter slow_processing_counter_; // Msgs w/ long proc time. base::StatsCounter queueing_delay_counter_; // Msgs w/ long queueing delay. - scoped_refptr<base::Histogram> process_times_; // Time spent proc. task. - scoped_refptr<base::Histogram> total_times_; // Total queueing plus proc. + base::Histogram* const process_times_; // Time spent proc. task. + base::Histogram* const total_times_; // Total queueing plus proc. JankWatchdog total_time_watchdog_; // Watching for excessive total_time. DISALLOW_COPY_AND_ASSIGN(JankObserverHelper); @@ -135,13 +135,13 @@ JankObserverHelper::JankObserverHelper( events_till_measurement_(0), slow_processing_counter_(std::string("Chrome.SlowMsg") + thread_name), queueing_delay_counter_(std::string("Chrome.DelayMsg") + thread_name), + process_times_(base::Histogram::FactoryGet( + std::string("Chrome.ProcMsgL ") + thread_name, + 1, 3600000, 50, base::Histogram::kUmaTargetedHistogramFlag)), + total_times_(base::Histogram::FactoryGet( + std::string("Chrome.TotalMsgL ") + thread_name, + 1, 3600000, 50, base::Histogram::kUmaTargetedHistogramFlag)), total_time_watchdog_(excessive_duration, thread_name, watchdog_enable) { - process_times_ = base::Histogram::FactoryGet( - std::string("Chrome.ProcMsgL ") + thread_name, - 1, 3600000, 50, base::Histogram::kUmaTargetedHistogramFlag); - total_times_ = base::Histogram::FactoryGet( - std::string("Chrome.TotalMsgL ") + thread_name, - 1, 3600000, 50, base::Histogram::kUmaTargetedHistogramFlag); if (discard_count_ > 0) { // Select a vaguely random sample-start-point. events_till_measurement_ = static_cast<int>( diff --git a/chrome/browser/metrics/thread_watcher.cc b/chrome/browser/metrics/thread_watcher.cc index dcad2bd..8318f8c 100644 --- a/chrome/browser/metrics/thread_watcher.cc +++ b/chrome/browser/metrics/thread_watcher.cc @@ -28,6 +28,7 @@ ThreadWatcher::ThreadWatcher(const BrowserThread::ID& thread_id, ping_sequence_number_(0), active_(false), ping_count_(kPingCount), + histogram_(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { Initialize(); } diff --git a/chrome/browser/metrics/thread_watcher.h b/chrome/browser/metrics/thread_watcher.h index ed9f84c..53cdb8d 100644 --- a/chrome/browser/metrics/thread_watcher.h +++ b/chrome/browser/metrics/thread_watcher.h @@ -186,7 +186,7 @@ class ThreadWatcher { int ping_count_; // Histogram that keeps track of response times for the watched thread. - scoped_refptr<base::Histogram> histogram_; + base::Histogram* histogram_; // We use this factory to create callback tasks for ThreadWatcher object. We // use this during ping-pong messaging between WatchDog thread and watched diff --git a/chrome/browser/net/url_info.cc b/chrome/browser/net/url_info.cc index 3ed81a1..9606ff5 100644 --- a/chrome/browser/net/url_info.cc +++ b/chrome/browser/net/url_info.cc @@ -120,10 +120,11 @@ void UrlInfo::RemoveFromQueue() { } // Make a custom linear histogram for the region from 0 to boundary. const size_t kBucketCount = 52; - scoped_refptr<base::Histogram> histogram = - base::LinearHistogram::FactoryTimeGet( - "DNS.QueueRecycledUnder2", TimeDelta(), kBoundary, kBucketCount, - base::Histogram::kUmaTargetedHistogramFlag); + static base::Histogram* histogram(NULL); + if (!histogram) + histogram = base::LinearHistogram::FactoryTimeGet( + "DNS.QueueRecycledUnder2", TimeDelta(), kBoundary, kBucketCount, + base::Histogram::kUmaTargetedHistogramFlag); histogram->AddTime(queue_duration_); } diff --git a/chrome/browser/net/websocket_experiment/websocket_experiment_task.cc b/chrome/browser/net/websocket_experiment/websocket_experiment_task.cc index c410778..6e59658 100644 --- a/chrome/browser/net/websocket_experiment/websocket_experiment_task.cc +++ b/chrome/browser/net/websocket_experiment/websocket_experiment_task.cc @@ -173,7 +173,6 @@ static Histogram* GetEnumsHistogramForConfig( Histogram* counter = LinearHistogram::FactoryGet( counter_name, 1, boundary_value, boundary_value + 1, Histogram::kUmaTargetedHistogramFlag); - counter->AddRef(); // Released in ReleaseHistogram(). g_histogram_table->insert(std::make_pair(counter_name, counter)); return counter; } @@ -194,7 +193,6 @@ static Histogram* GetTimesHistogramForConfig( Histogram* counter = Histogram::FactoryTimeGet( counter_name, min, max, bucket_count, Histogram::kUmaTargetedHistogramFlag); - counter->AddRef(); // Released in ReleaseHistogram(). g_histogram_table->insert(std::make_pair(counter_name, counter)); return counter; } @@ -223,15 +221,6 @@ static void UpdateHistogramTimes( /* static */ void WebSocketExperimentTask::ReleaseHistogram() { DCHECK(g_histogram_table); - for (base::hash_map<std::string, Histogram*>::iterator iter = - g_histogram_table->begin(); - iter != g_histogram_table->end(); - ++iter) { - Histogram* counter = iter->second; - if (counter != NULL) - counter->Release(); - iter->second = NULL; - } delete g_histogram_table; g_histogram_table = NULL; } diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc index c98f7b3..bf60878 100644 --- a/chrome/browser/sessions/session_restore.cc +++ b/chrome/browser/sessions/session_restore.cc @@ -300,7 +300,7 @@ void TabLoader::Observe(NotificationType type, // contention. std::string time_for_count = StringPrintf("SessionRestore.FirstTabPainted_%d", tab_count_); - scoped_refptr<base::Histogram> counter_for_count = + base::Histogram* counter_for_count = base::Histogram::FactoryTimeGet( time_for_count, base::TimeDelta::FromMilliseconds(10), @@ -388,7 +388,7 @@ void TabLoader::HandleTabClosedOrLoaded(NavigationController* tab) { // Record a time for the number of tabs, to help track down contention. std::string time_for_count = StringPrintf("SessionRestore.AllTabsLoaded_%d", tab_count_); - scoped_refptr<base::Histogram> counter_for_count = + base::Histogram* counter_for_count = base::Histogram::FactoryTimeGet( time_for_count, base::TimeDelta::FromMilliseconds(10), diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index 77b6fcc..456bedf 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -798,13 +798,9 @@ static void* CreateHistogram( const char *name, int min, int max, size_t buckets) { if (min <= 0) min = 1; - scoped_refptr<base::Histogram> histogram = base::Histogram::FactoryGet( + base::Histogram* histogram = base::Histogram::FactoryGet( name, min, max, buckets, base::Histogram::kUmaTargetedHistogramFlag); - // We'll end up leaking these histograms, unless there is some code hiding in - // there to do the dec-ref. - // TODO(jar): Handle reference counting in webkit glue. - histogram->AddRef(); - return histogram.get(); + return histogram; } static void AddHistogramSample(void* hist, int sample) { diff --git a/chrome/renderer/renderer_main.cc b/chrome/renderer/renderer_main.cc index cd3bb5d..df75219e 100644 --- a/chrome/renderer/renderer_main.cc +++ b/chrome/renderer/renderer_main.cc @@ -197,7 +197,7 @@ class RendererMessageLoopObserver : public MessageLoop::TaskObserver { private: base::TimeTicks begin_process_message_; - scoped_refptr<base::Histogram> process_times_; + base::Histogram* const process_times_; DISALLOW_COPY_AND_ASSIGN(RendererMessageLoopObserver); }; diff --git a/content/browser/renderer_host/buffered_resource_handler.cc b/content/browser/renderer_host/buffered_resource_handler.cc index d11bff9..d1c233a 100644 --- a/content/browser/renderer_host/buffered_resource_handler.cc +++ b/content/browser/renderer_host/buffered_resource_handler.cc @@ -29,21 +29,24 @@ namespace { void RecordSnifferMetrics(bool sniffing_blocked, bool we_would_like_to_sniff, const std::string& mime_type) { - scoped_refptr<base::Histogram> nosniff_usage = - base::BooleanHistogram::FactoryGet( - "nosniff.usage", base::Histogram::kUmaTargetedHistogramFlag); + static base::Histogram* nosniff_usage(NULL); + if (!nosniff_usage) + nosniff_usage = base::BooleanHistogram::FactoryGet( + "nosniff.usage", base::Histogram::kUmaTargetedHistogramFlag); nosniff_usage->AddBoolean(sniffing_blocked); if (sniffing_blocked) { - scoped_refptr<base::Histogram> nosniff_otherwise = - base::BooleanHistogram::FactoryGet( - "nosniff.otherwise", base::Histogram::kUmaTargetedHistogramFlag); + static base::Histogram* nosniff_otherwise(NULL); + if (!nosniff_otherwise) + nosniff_otherwise = base::BooleanHistogram::FactoryGet( + "nosniff.otherwise", base::Histogram::kUmaTargetedHistogramFlag); nosniff_otherwise->AddBoolean(we_would_like_to_sniff); - scoped_refptr<base::Histogram> nosniff_empty_mime_type = - base::BooleanHistogram::FactoryGet( - "nosniff.empty_mime_type", - base::Histogram::kUmaTargetedHistogramFlag); + static base::Histogram* nosniff_empty_mime_type(NULL); + if (!nosniff_empty_mime_type) + nosniff_empty_mime_type = base::BooleanHistogram::FactoryGet( + "nosniff.empty_mime_type", + base::Histogram::kUmaTargetedHistogramFlag); nosniff_empty_mime_type->AddBoolean(mime_type.empty()); } } diff --git a/net/base/connection_type_histograms.cc b/net/base/connection_type_histograms.cc index 06cdead..e64619c 100644 --- a/net/base/connection_type_histograms.cc +++ b/net/base/connection_type_histograms.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -21,12 +21,8 @@ namespace net { // Each histogram has an unused bucket at the end to allow seamless future // expansion. void UpdateConnectionTypeHistograms(ConnectionType type) { - // TODO(wtc): Bug 74467 Move these stats up to a higher level, where the - // explicit static (shown below) and the implicit statics (inside the - // HISTOGRAM macros) will be thread safe. -#if 0 // Don't do anything for now. - - static bool had_connection_type[NUM_OF_CONNECTION_TYPES]; + // TODO(wtc): Bug 74467 Move these stats up to a higher level. + static bool had_connection_type[NUM_OF_CONNECTION_TYPES]; // Default false. if (type >= 0 && type < NUM_OF_CONNECTION_TYPES) { if (!had_connection_type[type]) { @@ -40,7 +36,6 @@ void UpdateConnectionTypeHistograms(ConnectionType type) { } else { NOTREACHED(); // Someone's logging an invalid type! } -#endif // 0 } } // namespace net diff --git a/net/base/cookie_monster.h b/net/base/cookie_monster.h index 8a0d591..92cc4f8 100644 --- a/net/base/cookie_monster.h +++ b/net/base/cookie_monster.h @@ -469,17 +469,17 @@ class CookieMonster : public CookieStore { // Histogram variables; see CookieMonster::InitializeHistograms() in // cookie_monster.cc for details. - scoped_refptr<base::Histogram> histogram_expiration_duration_minutes_; - scoped_refptr<base::Histogram> histogram_between_access_interval_minutes_; - scoped_refptr<base::Histogram> histogram_evicted_last_access_minutes_; - scoped_refptr<base::Histogram> histogram_count_; - scoped_refptr<base::Histogram> histogram_domain_count_; - scoped_refptr<base::Histogram> histogram_etldp1_count_; - scoped_refptr<base::Histogram> histogram_domain_per_etldp1_count_; - scoped_refptr<base::Histogram> histogram_number_duplicate_db_cookies_; - scoped_refptr<base::Histogram> histogram_cookie_deletion_cause_; - scoped_refptr<base::Histogram> histogram_time_get_; - scoped_refptr<base::Histogram> histogram_time_load_; + base::Histogram* histogram_expiration_duration_minutes_; + base::Histogram* histogram_between_access_interval_minutes_; + base::Histogram* histogram_evicted_last_access_minutes_; + base::Histogram* histogram_count_; + base::Histogram* histogram_domain_count_; + base::Histogram* histogram_etldp1_count_; + base::Histogram* histogram_domain_per_etldp1_count_; + base::Histogram* histogram_number_duplicate_db_cookies_; + base::Histogram* histogram_cookie_deletion_cause_; + base::Histogram* histogram_time_get_; + base::Histogram* histogram_time_load_; CookieMap cookies_; diff --git a/net/base/cookie_monster_unittest.cc b/net/base/cookie_monster_unittest.cc index a430833..abaf84c 100644 --- a/net/base/cookie_monster_unittest.cc +++ b/net/base/cookie_monster_unittest.cc @@ -2238,7 +2238,7 @@ TEST(CookieMonsterTest, HistogramCheck) { // Should match call in InitializeHistograms, but doesn't really matter // since the histogram should have been initialized by the CM construction // above. - scoped_refptr<base::Histogram> expired_histogram = + base::Histogram* expired_histogram = base::Histogram::FactoryGet( "Cookie.ExpirationDurationMinutes", 1, 10 * 365 * 24 * 60, 50, base::Histogram::kUmaTargetedHistogramFlag); diff --git a/net/base/mime_sniffer.cc b/net/base/mime_sniffer.cc index 25b94ec..b0b6d03 100644 --- a/net/base/mime_sniffer.cc +++ b/net/base/mime_sniffer.cc @@ -209,9 +209,9 @@ static const MagicNumber kSniffableTags[] = { MAGIC_HTML_TAG("p") // Mozilla }; -static scoped_refptr<base::Histogram> UMASnifferHistogramGet(const char* name, - int array_size) { - scoped_refptr<base::Histogram> counter = +static base::Histogram* UMASnifferHistogramGet(const char* name, + int array_size) { + base::Histogram* counter = base::LinearHistogram::FactoryGet(name, 1, array_size - 1, array_size, base::Histogram::kUmaTargetedHistogramFlag); return counter; @@ -308,13 +308,14 @@ static bool SniffForHTML(const char* content, if (!IsAsciiWhitespace(*pos)) break; } - scoped_refptr<base::Histogram> counter = - UMASnifferHistogramGet("mime_sniffer.kSniffableTags2", - arraysize(kSniffableTags)); + static base::Histogram* counter(NULL); + if (!counter) + counter = UMASnifferHistogramGet("mime_sniffer.kSniffableTags2", + arraysize(kSniffableTags)); // |pos| now points to first non-whitespace character (or at end). return CheckForMagicNumbers(pos, end - pos, kSniffableTags, arraysize(kSniffableTags), - counter.get(), result); + counter, result); } // Returns true and sets result if the content matches any of kMagicNumbers. @@ -326,12 +327,13 @@ static bool SniffForMagicNumbers(const char* content, *have_enough_content &= TruncateSize(kBytesRequiredForMagic, &size); // Check our big table of Magic Numbers - scoped_refptr<base::Histogram> counter = - UMASnifferHistogramGet("mime_sniffer.kMagicNumbers2", - arraysize(kMagicNumbers)); + static base::Histogram* counter(NULL); + if (!counter) + counter = UMASnifferHistogramGet("mime_sniffer.kMagicNumbers2", + arraysize(kMagicNumbers)); return CheckForMagicNumbers(content, size, kMagicNumbers, arraysize(kMagicNumbers), - counter.get(), result); + counter, result); } // Byte order marks @@ -367,9 +369,10 @@ static bool SniffXML(const char* content, // We want to skip XML processing instructions (of the form "<?xml ...") // and stop at the first "plain" tag, then make a decision on the mime-type // based on the name (or possibly attributes) of that tag. - scoped_refptr<base::Histogram> counter = - UMASnifferHistogramGet("mime_sniffer.kMagicXML2", - arraysize(kMagicXML)); + static base::Histogram* counter(NULL); + if (!counter) + counter = UMASnifferHistogramGet("mime_sniffer.kMagicXML2", + arraysize(kMagicXML)); const int kMaxTagIterations = 5; for (int i = 0; i < kMaxTagIterations && pos < end; ++i) { pos = reinterpret_cast<const char*>(memchr(pos, '<', end - pos)); @@ -389,7 +392,7 @@ static bool SniffXML(const char* content, if (CheckForMagicNumbers(pos, end - pos, kMagicXML, arraysize(kMagicXML), - counter.get(), result)) + counter, result)) return true; // TODO(evanm): handle RSS 1.0, which is an RDF format and more difficult @@ -451,13 +454,14 @@ static bool SniffBinary(const char* content, const bool is_truncated = TruncateSize(kMaxBytesToSniff, &size); // First, we look for a BOM. - scoped_refptr<base::Histogram> counter = - UMASnifferHistogramGet("mime_sniffer.kByteOrderMark2", - arraysize(kByteOrderMark)); + static base::Histogram* counter(NULL); + if (!counter) + counter = UMASnifferHistogramGet("mime_sniffer.kByteOrderMark2", + arraysize(kByteOrderMark)); std::string unused; if (CheckForMagicNumbers(content, size, kByteOrderMark, arraysize(kByteOrderMark), - counter.get(), &unused)) { + counter, &unused)) { // If there is BOM, we think the buffer is not binary. result->assign("text/plain"); return false; @@ -493,9 +497,10 @@ static bool IsUnknownMimeType(const std::string& mime_type) { // Firefox rejects a mime type if it is exactly */* "*/*", }; - scoped_refptr<base::Histogram> counter = - UMASnifferHistogramGet("mime_sniffer.kUnknownMimeTypes2", - arraysize(kUnknownMimeTypes) + 1); + static base::Histogram* counter(NULL); + if (!counter) + counter = UMASnifferHistogramGet("mime_sniffer.kUnknownMimeTypes2", + arraysize(kUnknownMimeTypes) + 1); for (size_t i = 0; i < arraysize(kUnknownMimeTypes); ++i) { if (mime_type == kUnknownMimeTypes[i]) { counter->Add(i); @@ -519,8 +524,9 @@ static bool SniffCRX(const char* content, const std::string& type_hint, bool* have_enough_content, std::string* result) { - scoped_refptr<base::Histogram> counter = - UMASnifferHistogramGet("mime_sniffer.kSniffCRX", 3); + static base::Histogram* counter(NULL); + if (!counter) + counter = UMASnifferHistogramGet("mime_sniffer.kSniffCRX", 3); // Technically, the crx magic number is just Cr24, but the bytes after that // are a version number which changes infrequently. Including it in the @@ -557,8 +563,10 @@ static bool SniffCRX(const char* content, } bool ShouldSniffMimeType(const GURL& url, const std::string& mime_type) { - scoped_refptr<base::Histogram> should_sniff_counter = - UMASnifferHistogramGet("mime_sniffer.ShouldSniffMimeType2", 3); + static base::Histogram* should_sniff_counter(NULL); + if (!should_sniff_counter) + should_sniff_counter = + UMASnifferHistogramGet("mime_sniffer.ShouldSniffMimeType2", 3); // We are willing to sniff the mime type for HTTP, HTTPS, and FTP bool sniffable_scheme = url.is_empty() || url.SchemeIs("http") || @@ -582,9 +590,10 @@ bool ShouldSniffMimeType(const GURL& url, const std::string& mime_type) { "text/xml", "application/xml", }; - scoped_refptr<base::Histogram> counter = - UMASnifferHistogramGet("mime_sniffer.kSniffableTypes2", - arraysize(kSniffableTypes) + 1); + static base::Histogram* counter(NULL); + if (!counter) + counter = UMASnifferHistogramGet("mime_sniffer.kSniffableTypes2", + arraysize(kSniffableTypes) + 1); for (size_t i = 0; i < arraysize(kSniffableTypes); ++i) { if (mime_type == kSniffableTypes[i]) { counter->Add(i); diff --git a/net/disk_cache/histogram_macros.h b/net/disk_cache/histogram_macros.h index e238599..0dc12c5 100644 --- a/net/disk_cache/histogram_macros.h +++ b/net/disk_cache/histogram_macros.h @@ -17,10 +17,12 @@ // These histograms follow the definition of UMA_HISTOGRAMN_XXX except that // whenever the name changes (the experiment group changes), the histrogram // object is re-created. +// Note: These macros are only run on one thread, so the declarations of +// |counter| was made static (i.e., there will be no race for reinitialization). #define CACHE_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ do { \ - scoped_refptr<base::Histogram> counter; \ + static base::Histogram* counter(NULL); \ if (!counter || name != counter->histogram_name()) \ counter = base::Histogram::FactoryGet( \ name, min, max, bucket_count, \ @@ -39,7 +41,7 @@ #define CACHE_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ do { \ - scoped_refptr<base::Histogram> counter; \ + static base::Histogram* counter(NULL); \ if (!counter || name != counter->histogram_name()) \ counter = base::Histogram::FactoryTimeGet( \ name, min, max, bucket_count, \ @@ -52,7 +54,7 @@ base::TimeDelta::FromSeconds(10), 50) #define CACHE_HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \ - scoped_refptr<base::Histogram> counter; \ + static base::Histogram* counter(NULL); \ if (!counter || name != counter->histogram_name()) \ counter = base::LinearHistogram::FactoryGet( \ name, 1, boundary_value, boundary_value + 1, \ diff --git a/net/disk_cache/stats.cc b/net/disk_cache/stats.cc index d9a9d12..23991c0 100644 --- a/net/disk_cache/stats.cc +++ b/net/disk_cache/stats.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -116,7 +116,7 @@ bool CreateStats(BackendImpl* backend, Addr* address, OnDiskStats* stats) { return StoreStats(backend, *address, stats); } -Stats::Stats() : backend_(NULL) { +Stats::Stats() : backend_(NULL), size_histogram_(NULL) { } Stats::~Stats() { @@ -146,7 +146,7 @@ bool Stats::Init(BackendImpl* backend, uint32* storage_addr) { if (first_time) { first_time = false; // ShouldReportAgain() will re-enter this object. - if (!size_histogram_.get() && backend->cache_type() == net::DISK_CACHE && + if (!size_histogram_ && backend->cache_type() == net::DISK_CACHE && backend->ShouldReportAgain()) { // Stats may be reused when the cache is re-created, but we want only one // histogram at any given time. diff --git a/net/disk_cache/stats.h b/net/disk_cache/stats.h index ba0d7dd..1f5aa59 100644 --- a/net/disk_cache/stats.h +++ b/net/disk_cache/stats.h @@ -86,7 +86,7 @@ class Stats { uint32 storage_addr_; int data_sizes_[kDataSizesLength]; int64 counters_[MAX_COUNTER]; - scoped_refptr<StatsHistogram> size_histogram_; + StatsHistogram* size_histogram_; DISALLOW_COPY_AND_ASSIGN(Stats); }; diff --git a/net/disk_cache/stats_histogram.cc b/net/disk_cache/stats_histogram.cc index e9d7696..6d3097a 100644 --- a/net/disk_cache/stats_histogram.cc +++ b/net/disk_cache/stats_histogram.cc @@ -21,23 +21,23 @@ StatsHistogram::~StatsHistogram() { stats_ = NULL; } -scoped_refptr<StatsHistogram> StatsHistogram::StatsHistogramFactoryGet( +StatsHistogram* StatsHistogram::StatsHistogramFactoryGet( const std::string& name) { - scoped_refptr<Histogram> histogram(NULL); + Histogram* histogram(NULL); Sample minimum = 1; Sample maximum = disk_cache::Stats::kDataSizesLength - 1; size_t bucket_count = disk_cache::Stats::kDataSizesLength; if (StatisticsRecorder::FindHistogram(name, &histogram)) { - DCHECK(histogram.get() != NULL); + DCHECK(histogram != NULL); } else { - StatsHistogram* stats_histogram = new StatsHistogram(name, minimum, maximum, - bucket_count); + // To avoid racy destruction at shutdown, the following will be leaked. + StatsHistogram* stats_histogram = + new StatsHistogram(name, minimum, maximum, bucket_count); stats_histogram->InitializeBucketRange(); - histogram = stats_histogram; - histogram->SetFlags(kUmaTargetedHistogramFlag); - StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram); + stats_histogram->SetFlags(kUmaTargetedHistogramFlag); + histogram = StatisticsRecorder::RegisterOrDeleteDuplicate(stats_histogram); } DCHECK(HISTOGRAM == histogram->histogram_type()); @@ -45,13 +45,10 @@ scoped_refptr<StatsHistogram> StatsHistogram::StatsHistogramFactoryGet( // We're preparing for an otherwise unsafe upcast by ensuring we have the // proper class type. - Histogram* temp_histogram = histogram.get(); - StatsHistogram* temp_stats_histogram = - static_cast<StatsHistogram*>(temp_histogram); + StatsHistogram* return_histogram = static_cast<StatsHistogram*>(histogram); // Validate upcast by seeing that we're probably providing the checksum. - CHECK_EQ(temp_stats_histogram->StatsHistogram::CalculateRangeChecksum(), - temp_stats_histogram->CalculateRangeChecksum()); - scoped_refptr<StatsHistogram> return_histogram(temp_stats_histogram); + CHECK_EQ(return_histogram->StatsHistogram::CalculateRangeChecksum(), + return_histogram->CalculateRangeChecksum()); return return_histogram; } diff --git a/net/disk_cache/stats_histogram.h b/net/disk_cache/stats_histogram.h index 249327c..83d359c 100644 --- a/net/disk_cache/stats_histogram.h +++ b/net/disk_cache/stats_histogram.h @@ -1,4 +1,4 @@ -// Copyright (c) 2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -35,8 +35,7 @@ class StatsHistogram : public base::Histogram { : Histogram(name, minimum, maximum, bucket_count), init_(false) {} ~StatsHistogram(); - static scoped_refptr<StatsHistogram> - StatsHistogramFactoryGet(const std::string& name); + static StatsHistogram* StatsHistogramFactoryGet(const std::string& name); // We'll be reporting data from the given set of cache stats. bool Init(const Stats* stats); diff --git a/net/socket/client_socket_pool_histograms.h b/net/socket/client_socket_pool_histograms.h index 493d34a..0e5afff 100644 --- a/net/socket/client_socket_pool_histograms.h +++ b/net/socket/client_socket_pool_histograms.h @@ -28,10 +28,10 @@ class ClientSocketPoolHistograms { void AddReusedIdleTime(base::TimeDelta time) const; private: - scoped_refptr<base::Histogram> socket_type_; - scoped_refptr<base::Histogram> request_time_; - scoped_refptr<base::Histogram> unused_idle_time_; - scoped_refptr<base::Histogram> reused_idle_time_; + base::Histogram* socket_type_; + base::Histogram* request_time_; + base::Histogram* unused_idle_time_; + base::Histogram* reused_idle_time_; bool is_http_proxy_connection_; bool is_socks_connection_; diff --git a/net/socket_stream/socket_stream_metrics_unittest.cc b/net/socket_stream/socket_stream_metrics_unittest.cc index 72ae142..23f227d 100644 --- a/net/socket_stream/socket_stream_metrics_unittest.cc +++ b/net/socket_stream/socket_stream_metrics_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -25,7 +25,7 @@ TEST(SocketStreamMetricsTest, Initialize) { } TEST(SocketStreamMetricsTest, ProtocolType) { - scoped_refptr<Histogram> histogram; + Histogram* histogram; // First we'll preserve the original values. We need to do this // as histograms can get affected by other tests. In particular, @@ -57,7 +57,7 @@ TEST(SocketStreamMetricsTest, ProtocolType) { } TEST(SocketStreamMetricsTest, ConnectionType) { - scoped_refptr<Histogram> histogram; + Histogram* histogram; // First we'll preserve the original values. Histogram::SampleSet original; @@ -91,7 +91,7 @@ TEST(SocketStreamMetricsTest, ConnectionType) { } TEST(SocketStreamMetricsTest, OtherNumbers) { - scoped_refptr<Histogram> histogram; + Histogram* histogram; // First we'll preserve the original values. int64 original_received_bytes = 0; diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt index 5bd5b68..148abe3 100644 --- a/tools/valgrind/memcheck/suppressions.txt +++ b/tools/valgrind/memcheck/suppressions.txt @@ -877,6 +877,20 @@ fun:PL_ArenaAllocate fun:PORT_ArenaAlloc_Util } +{ + # Histograms are used on un-joined threads, and can't be deleted atexit. + Histograms via FactoryGet including Linear Custom Boolean and Basic + Memcheck:Leak + fun:_Znw* + fun:_ZN4base*Histogram10FactoryGet* +} +{ + # Histograms are used on un-joined threads, and can't be deleted atexit. + Histograms via FactoryGet including Stats for disk_cache + Memcheck:Leak + fun:_Znw* + fun:_ZN10disk_cache14StatsHistogram24StatsHistogramFactoryGet* +} #----------------------------------------------------------------------- # 3. Suppressions for real chromium bugs that are not yet fixed. diff --git a/webkit/glue/webkitclient_impl.cc b/webkit/glue/webkitclient_impl.cc index 4fc05e6..4e2b10a 100644 --- a/webkit/glue/webkitclient_impl.cc +++ b/webkit/glue/webkitclient_impl.cc @@ -264,24 +264,22 @@ void WebKitClientImpl::histogramCustomCounts( const char* name, int sample, int min, int max, int bucket_count) { // Copied from histogram macro, but without the static variable caching // the histogram because name is dynamic. - scoped_refptr<base::Histogram> counter = + base::Histogram* counter = base::Histogram::FactoryGet(name, min, max, bucket_count, base::Histogram::kUmaTargetedHistogramFlag); DCHECK_EQ(name, counter->histogram_name()); - if (counter.get()) - counter->Add(sample); + counter->Add(sample); } void WebKitClientImpl::histogramEnumeration( const char* name, int sample, int boundary_value) { // Copied from histogram macro, but without the static variable caching // the histogram because name is dynamic. - scoped_refptr<base::Histogram> counter = + base::Histogram* counter = base::LinearHistogram::FactoryGet(name, 1, boundary_value, boundary_value + 1, base::Histogram::kUmaTargetedHistogramFlag); DCHECK_EQ(name, counter->histogram_name()); - if (counter.get()) - counter->Add(sample); + counter->Add(sample); } void WebKitClientImpl::traceEventBegin(const char* name, void* id, |