summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-05 04:48:53 +0000
committerjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-05 04:48:53 +0000
commit81ce9f3b1eb34dc7f6954f0f6657a76b0f01fc12 (patch)
tree41b3caf1a55ba3cfa2f6cf13b0a5ce3d773d631f
parent4f7f4854821e8e4933ad2c662bfd9417eb604a68 (diff)
downloadchromium_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
-rw-r--r--base/message_loop.cc7
-rw-r--r--base/message_loop.h2
-rw-r--r--base/metrics/histogram.cc135
-rw-r--r--base/metrics/histogram.h155
-rw-r--r--base/metrics/histogram_unittest.cc117
-rw-r--r--chrome/browser/autocomplete/autocomplete.cc2
-rw-r--r--chrome/browser/autocomplete/history_quick_provider.cc2
-rw-r--r--chrome/browser/chromeos/boot_times_loader.cc4
-rw-r--r--chrome/browser/chromeos/cros/cros_library_loader.cc10
-rw-r--r--chrome/browser/chromeos/external_metrics.cc6
-rw-r--r--chrome/browser/extensions/extension_metrics_apitest.cc2
-rw-r--r--chrome/browser/extensions/extension_metrics_module.cc4
-rw-r--r--chrome/browser/jankometer.cc16
-rw-r--r--chrome/browser/metrics/thread_watcher.cc1
-rw-r--r--chrome/browser/metrics/thread_watcher.h2
-rw-r--r--chrome/browser/net/url_info.cc9
-rw-r--r--chrome/browser/net/websocket_experiment/websocket_experiment_task.cc11
-rw-r--r--chrome/browser/sessions/session_restore.cc4
-rw-r--r--chrome/renderer/render_thread.cc8
-rw-r--r--chrome/renderer/renderer_main.cc2
-rw-r--r--content/browser/renderer_host/buffered_resource_handler.cc23
-rw-r--r--net/base/connection_type_histograms.cc11
-rw-r--r--net/base/cookie_monster.h22
-rw-r--r--net/base/cookie_monster_unittest.cc2
-rw-r--r--net/base/mime_sniffer.cc67
-rw-r--r--net/disk_cache/histogram_macros.h8
-rw-r--r--net/disk_cache/stats.cc6
-rw-r--r--net/disk_cache/stats.h2
-rw-r--r--net/disk_cache/stats_histogram.cc25
-rw-r--r--net/disk_cache/stats_histogram.h5
-rw-r--r--net/socket/client_socket_pool_histograms.h8
-rw-r--r--net/socket_stream/socket_stream_metrics_unittest.cc8
-rw-r--r--tools/valgrind/memcheck/suppressions.txt14
-rw-r--r--webkit/glue/webkitclient_impl.cc10
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,