| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Histogram is an object that aggregates statistics, and can summarize them in | 5 // Histogram is an object that aggregates statistics, and can summarize them in |
| 6 // various forms, including ASCII graphical, HTML, and numerically (as a | 6 // various forms, including ASCII graphical, HTML, and numerically (as a |
| 7 // vector of numbers corresponding to each of the aggregating buckets). | 7 // vector of numbers corresponding to each of the aggregating buckets). |
| 8 // See header file for details and examples. | 8 // See header file for details and examples. |
| 9 | 9 |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, | 66 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, |
| 67 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, | 67 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, |
| 68 0x2d02ef8dL, | 68 0x2d02ef8dL, |
| 69 }; | 69 }; |
| 70 | 70 |
| 71 typedef Histogram::Count Count; | 71 typedef Histogram::Count Count; |
| 72 | 72 |
| 73 // static | 73 // static |
| 74 const size_t Histogram::kBucketCount_MAX = 16384u; | 74 const size_t Histogram::kBucketCount_MAX = 16384u; |
| 75 | 75 |
| 76 scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name, | 76 Histogram* Histogram::FactoryGet(const std::string& name, |
| 77 Sample minimum, Sample maximum, size_t bucket_count, Flags flags) { | 77 Sample minimum, |
| 78 scoped_refptr<Histogram> histogram(NULL); | 78 Sample maximum, |
| 79 size_t bucket_count, |
| 80 Flags flags) { |
| 81 Histogram* histogram(NULL); |
| 79 | 82 |
| 80 // Defensive code. | 83 // Defensive code. |
| 81 if (minimum < 1) | 84 if (minimum < 1) |
| 82 minimum = 1; | 85 minimum = 1; |
| 83 if (maximum > kSampleType_MAX - 1) | 86 if (maximum > kSampleType_MAX - 1) |
| 84 maximum = kSampleType_MAX - 1; | 87 maximum = kSampleType_MAX - 1; |
| 85 | 88 |
| 86 if (!StatisticsRecorder::FindHistogram(name, &histogram)) { | 89 if (!StatisticsRecorder::FindHistogram(name, &histogram)) { |
| 87 histogram = new Histogram(name, minimum, maximum, bucket_count); | 90 // Extra variable is not needed... but this keeps this section basically |
| 88 histogram->InitializeBucketRange(); | 91 // identical to other derived classes in this file (and compiler will |
| 89 histogram->SetFlags(flags); | 92 // optimize away the extra variable. |
| 90 StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram); | 93 // To avoid racy destruction at shutdown, the following will be leaked. |
| 94 Histogram* tentative_histogram = |
| 95 new Histogram(name, minimum, maximum, bucket_count); |
| 96 tentative_histogram->InitializeBucketRange(); |
| 97 tentative_histogram->SetFlags(flags); |
| 98 histogram = |
| 99 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
| 91 } | 100 } |
| 92 | 101 |
| 93 DCHECK_EQ(HISTOGRAM, histogram->histogram_type()); | 102 DCHECK_EQ(HISTOGRAM, histogram->histogram_type()); |
| 94 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count)); | 103 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count)); |
| 95 return histogram; | 104 return histogram; |
| 96 } | 105 } |
| 97 | 106 |
| 98 scoped_refptr<Histogram> Histogram::FactoryTimeGet(const std::string& name, | 107 Histogram* Histogram::FactoryTimeGet(const std::string& name, |
| 99 TimeDelta minimum, | 108 TimeDelta minimum, |
| 100 TimeDelta maximum, | 109 TimeDelta maximum, |
| 101 size_t bucket_count, | 110 size_t bucket_count, |
| 102 Flags flags) { | 111 Flags flags) { |
| 103 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), | 112 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), |
| 104 bucket_count, flags); | 113 bucket_count, flags); |
| 105 } | 114 } |
| 106 | 115 |
| 107 void Histogram::Add(int value) { | 116 void Histogram::Add(int value) { |
| 108 if (value > kSampleType_MAX - 1) | 117 if (value > kSampleType_MAX - 1) |
| 109 value = kSampleType_MAX - 1; | 118 value = kSampleType_MAX - 1; |
| 110 if (value < 0) | 119 if (value < 0) |
| 111 value = 0; | 120 value = 0; |
| 112 size_t index = BucketIndex(value); | 121 size_t index = BucketIndex(value); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 if (declared_max <= 0 || declared_min <= 0 || declared_max < declared_min || | 261 if (declared_max <= 0 || declared_min <= 0 || declared_max < declared_min || |
| 253 INT_MAX / sizeof(Count) <= bucket_count || bucket_count < 2) { | 262 INT_MAX / sizeof(Count) <= bucket_count || bucket_count < 2) { |
| 254 LOG(ERROR) << "Values error decoding Histogram: " << histogram_name; | 263 LOG(ERROR) << "Values error decoding Histogram: " << histogram_name; |
| 255 return false; | 264 return false; |
| 256 } | 265 } |
| 257 | 266 |
| 258 Flags flags = static_cast<Flags>(pickle_flags & ~kIPCSerializationSourceFlag); | 267 Flags flags = static_cast<Flags>(pickle_flags & ~kIPCSerializationSourceFlag); |
| 259 | 268 |
| 260 DCHECK_NE(NOT_VALID_IN_RENDERER, histogram_type); | 269 DCHECK_NE(NOT_VALID_IN_RENDERER, histogram_type); |
| 261 | 270 |
| 262 scoped_refptr<Histogram> render_histogram(NULL); | 271 Histogram* render_histogram(NULL); |
| 263 | 272 |
| 264 if (histogram_type == HISTOGRAM) { | 273 if (histogram_type == HISTOGRAM) { |
| 265 render_histogram = Histogram::FactoryGet( | 274 render_histogram = Histogram::FactoryGet( |
| 266 histogram_name, declared_min, declared_max, bucket_count, flags); | 275 histogram_name, declared_min, declared_max, bucket_count, flags); |
| 267 } else if (histogram_type == LINEAR_HISTOGRAM) { | 276 } else if (histogram_type == LINEAR_HISTOGRAM) { |
| 268 render_histogram = LinearHistogram::FactoryGet( | 277 render_histogram = LinearHistogram::FactoryGet( |
| 269 histogram_name, declared_min, declared_max, bucket_count, flags); | 278 histogram_name, declared_min, declared_max, bucket_count, flags); |
| 270 } else if (histogram_type == BOOLEAN_HISTOGRAM) { | 279 } else if (histogram_type == BOOLEAN_HISTOGRAM) { |
| 271 render_histogram = BooleanHistogram::FactoryGet(histogram_name, flags); | 280 render_histogram = BooleanHistogram::FactoryGet(histogram_name, flags); |
| 272 } else { | 281 } else { |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 } | 763 } |
| 755 | 764 |
| 756 //------------------------------------------------------------------------------ | 765 //------------------------------------------------------------------------------ |
| 757 // LinearHistogram: This histogram uses a traditional set of evenly spaced | 766 // LinearHistogram: This histogram uses a traditional set of evenly spaced |
| 758 // buckets. | 767 // buckets. |
| 759 //------------------------------------------------------------------------------ | 768 //------------------------------------------------------------------------------ |
| 760 | 769 |
| 761 LinearHistogram::~LinearHistogram() { | 770 LinearHistogram::~LinearHistogram() { |
| 762 } | 771 } |
| 763 | 772 |
| 764 scoped_refptr<Histogram> LinearHistogram::FactoryGet(const std::string& name, | 773 Histogram* LinearHistogram::FactoryGet(const std::string& name, |
| 765 Sample minimum, | 774 Sample minimum, |
| 766 Sample maximum, | 775 Sample maximum, |
| 767 size_t bucket_count, | 776 size_t bucket_count, |
| 768 Flags flags) { | 777 Flags flags) { |
| 769 scoped_refptr<Histogram> histogram(NULL); | 778 Histogram* histogram(NULL); |
| 770 | 779 |
| 771 if (minimum < 1) | 780 if (minimum < 1) |
| 772 minimum = 1; | 781 minimum = 1; |
| 773 if (maximum > kSampleType_MAX - 1) | 782 if (maximum > kSampleType_MAX - 1) |
| 774 maximum = kSampleType_MAX - 1; | 783 maximum = kSampleType_MAX - 1; |
| 775 | 784 |
| 776 if (!StatisticsRecorder::FindHistogram(name, &histogram)) { | 785 if (!StatisticsRecorder::FindHistogram(name, &histogram)) { |
| 777 LinearHistogram* linear_histogram = | 786 // To avoid racy destruction at shutdown, the following will be leaked. |
| 787 LinearHistogram* tentative_histogram = |
| 778 new LinearHistogram(name, minimum, maximum, bucket_count); | 788 new LinearHistogram(name, minimum, maximum, bucket_count); |
| 779 linear_histogram->InitializeBucketRange(); | 789 tentative_histogram->InitializeBucketRange(); |
| 780 histogram = linear_histogram; | 790 tentative_histogram->SetFlags(flags); |
| 781 histogram->SetFlags(flags); | 791 histogram = |
| 782 StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram); | 792 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
| 783 } | 793 } |
| 784 | 794 |
| 785 DCHECK_EQ(LINEAR_HISTOGRAM, histogram->histogram_type()); | 795 DCHECK_EQ(LINEAR_HISTOGRAM, histogram->histogram_type()); |
| 786 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count)); | 796 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count)); |
| 787 return histogram; | 797 return histogram; |
| 788 } | 798 } |
| 789 | 799 |
| 790 scoped_refptr<Histogram> LinearHistogram::FactoryTimeGet( | 800 Histogram* LinearHistogram::FactoryTimeGet(const std::string& name, |
| 791 const std::string& name, | 801 TimeDelta minimum, |
| 792 TimeDelta minimum, | 802 TimeDelta maximum, |
| 793 TimeDelta maximum, | 803 size_t bucket_count, |
| 794 size_t bucket_count, | 804 Flags flags) { |
| 795 Flags flags) { | |
| 796 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), | 805 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), |
| 797 bucket_count, flags); | 806 bucket_count, flags); |
| 798 } | 807 } |
| 799 | 808 |
| 800 Histogram::ClassType LinearHistogram::histogram_type() const { | 809 Histogram::ClassType LinearHistogram::histogram_type() const { |
| 801 return LINEAR_HISTOGRAM; | 810 return LINEAR_HISTOGRAM; |
| 802 } | 811 } |
| 803 | 812 |
| 804 void LinearHistogram::SetRangeDescriptions( | 813 void LinearHistogram::SetRangeDescriptions( |
| 805 const DescriptionPair descriptions[]) { | 814 const DescriptionPair descriptions[]) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 | 864 |
| 856 bool LinearHistogram::PrintEmptyBucket(size_t index) const { | 865 bool LinearHistogram::PrintEmptyBucket(size_t index) const { |
| 857 return bucket_description_.find(ranges(index)) == bucket_description_.end(); | 866 return bucket_description_.find(ranges(index)) == bucket_description_.end(); |
| 858 } | 867 } |
| 859 | 868 |
| 860 | 869 |
| 861 //------------------------------------------------------------------------------ | 870 //------------------------------------------------------------------------------ |
| 862 // This section provides implementation for BooleanHistogram. | 871 // This section provides implementation for BooleanHistogram. |
| 863 //------------------------------------------------------------------------------ | 872 //------------------------------------------------------------------------------ |
| 864 | 873 |
| 865 scoped_refptr<Histogram> BooleanHistogram::FactoryGet(const std::string& name, | 874 Histogram* BooleanHistogram::FactoryGet(const std::string& name, Flags flags) { |
| 866 Flags flags) { | 875 Histogram* histogram(NULL); |
| 867 scoped_refptr<Histogram> histogram(NULL); | |
| 868 | 876 |
| 869 if (!StatisticsRecorder::FindHistogram(name, &histogram)) { | 877 if (!StatisticsRecorder::FindHistogram(name, &histogram)) { |
| 870 BooleanHistogram* boolean_histogram = new BooleanHistogram(name); | 878 // To avoid racy destruction at shutdown, the following will be leaked. |
| 871 boolean_histogram->InitializeBucketRange(); | 879 BooleanHistogram* tentative_histogram = new BooleanHistogram(name); |
| 872 histogram = boolean_histogram; | 880 tentative_histogram->InitializeBucketRange(); |
| 873 histogram->SetFlags(flags); | 881 tentative_histogram->SetFlags(flags); |
| 874 StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram); | 882 histogram = |
| 883 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
| 875 } | 884 } |
| 876 | 885 |
| 877 DCHECK_EQ(BOOLEAN_HISTOGRAM, histogram->histogram_type()); | 886 DCHECK_EQ(BOOLEAN_HISTOGRAM, histogram->histogram_type()); |
| 878 return histogram; | 887 return histogram; |
| 879 } | 888 } |
| 880 | 889 |
| 881 Histogram::ClassType BooleanHistogram::histogram_type() const { | 890 Histogram::ClassType BooleanHistogram::histogram_type() const { |
| 882 return BOOLEAN_HISTOGRAM; | 891 return BOOLEAN_HISTOGRAM; |
| 883 } | 892 } |
| 884 | 893 |
| 885 void BooleanHistogram::AddBoolean(bool value) { | 894 void BooleanHistogram::AddBoolean(bool value) { |
| 886 Add(value ? 1 : 0); | 895 Add(value ? 1 : 0); |
| 887 } | 896 } |
| 888 | 897 |
| 889 BooleanHistogram::BooleanHistogram(const std::string& name) | 898 BooleanHistogram::BooleanHistogram(const std::string& name) |
| 890 : LinearHistogram(name, 1, 2, 3) { | 899 : LinearHistogram(name, 1, 2, 3) { |
| 891 } | 900 } |
| 892 | 901 |
| 893 //------------------------------------------------------------------------------ | 902 //------------------------------------------------------------------------------ |
| 894 // CustomHistogram: | 903 // CustomHistogram: |
| 895 //------------------------------------------------------------------------------ | 904 //------------------------------------------------------------------------------ |
| 896 | 905 |
| 897 scoped_refptr<Histogram> CustomHistogram::FactoryGet( | 906 Histogram* CustomHistogram::FactoryGet(const std::string& name, |
| 898 const std::string& name, | 907 const std::vector<Sample>& custom_ranges, |
| 899 const std::vector<Sample>& custom_ranges, | 908 Flags flags) { |
| 900 Flags flags) { | 909 Histogram* histogram(NULL); |
| 901 scoped_refptr<Histogram> histogram(NULL); | |
| 902 | 910 |
| 903 // Remove the duplicates in the custom ranges array. | 911 // Remove the duplicates in the custom ranges array. |
| 904 std::vector<int> ranges = custom_ranges; | 912 std::vector<int> ranges = custom_ranges; |
| 905 ranges.push_back(0); // Ensure we have a zero value. | 913 ranges.push_back(0); // Ensure we have a zero value. |
| 906 std::sort(ranges.begin(), ranges.end()); | 914 std::sort(ranges.begin(), ranges.end()); |
| 907 ranges.erase(std::unique(ranges.begin(), ranges.end()), ranges.end()); | 915 ranges.erase(std::unique(ranges.begin(), ranges.end()), ranges.end()); |
| 908 if (ranges.size() <= 1) { | 916 if (ranges.size() <= 1) { |
| 909 DCHECK(false); | 917 DCHECK(false); |
| 910 // Note that we pushed a 0 in above, so for defensive code.... | 918 // Note that we pushed a 0 in above, so for defensive code.... |
| 911 ranges.push_back(1); // Put in some data so we can index to [1]. | 919 ranges.push_back(1); // Put in some data so we can index to [1]. |
| 912 } | 920 } |
| 913 | 921 |
| 914 DCHECK_LT(ranges.back(), kSampleType_MAX); | 922 DCHECK_LT(ranges.back(), kSampleType_MAX); |
| 915 | 923 |
| 916 if (!StatisticsRecorder::FindHistogram(name, &histogram)) { | 924 if (!StatisticsRecorder::FindHistogram(name, &histogram)) { |
| 917 CustomHistogram* custom_histogram = new CustomHistogram(name, ranges); | 925 // To avoid racy destruction at shutdown, the following will be leaked. |
| 918 custom_histogram->InitializedCustomBucketRange(ranges); | 926 CustomHistogram* tentative_histogram = new CustomHistogram(name, ranges); |
| 919 histogram = custom_histogram; | 927 tentative_histogram->InitializedCustomBucketRange(ranges); |
| 920 histogram->SetFlags(flags); | 928 tentative_histogram->SetFlags(flags); |
| 921 StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram); | 929 histogram = |
| 930 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); |
| 922 } | 931 } |
| 923 | 932 |
| 924 DCHECK_EQ(histogram->histogram_type(), CUSTOM_HISTOGRAM); | 933 DCHECK_EQ(histogram->histogram_type(), CUSTOM_HISTOGRAM); |
| 925 DCHECK(histogram->HasConstructorArguments(ranges[1], ranges.back(), | 934 DCHECK(histogram->HasConstructorArguments(ranges[1], ranges.back(), |
| 926 ranges.size())); | 935 ranges.size())); |
| 927 return histogram; | 936 return histogram; |
| 928 } | 937 } |
| 929 | 938 |
| 930 Histogram::ClassType CustomHistogram::histogram_type() const { | 939 Histogram::ClassType CustomHistogram::histogram_type() const { |
| 931 return CUSTOM_HISTOGRAM; | 940 return CUSTOM_HISTOGRAM; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 } | 1006 } |
| 998 | 1007 |
| 999 // static | 1008 // static |
| 1000 bool StatisticsRecorder::IsActive() { | 1009 bool StatisticsRecorder::IsActive() { |
| 1001 if (lock_ == NULL) | 1010 if (lock_ == NULL) |
| 1002 return false; | 1011 return false; |
| 1003 base::AutoLock auto_lock(*lock_); | 1012 base::AutoLock auto_lock(*lock_); |
| 1004 return NULL != histograms_; | 1013 return NULL != histograms_; |
| 1005 } | 1014 } |
| 1006 | 1015 |
| 1007 // Note: We can't accept a ref_ptr to |histogram| because we *might* not keep a | 1016 Histogram* StatisticsRecorder::RegisterOrDeleteDuplicate(Histogram* histogram) { |
| 1008 // reference, and we are called while in the Histogram constructor. In that | 1017 DCHECK(histogram->HasValidRangeChecksum()); |
| 1009 // scenario, a ref_ptr would have incremented the ref count when the histogram | |
| 1010 // was passed to us, decremented it when we returned, and the instance would be | |
| 1011 // destroyed before assignment (when value was returned by new). | |
| 1012 // static | |
| 1013 void StatisticsRecorder::RegisterOrDiscardDuplicate( | |
| 1014 scoped_refptr<Histogram>* histogram) { | |
| 1015 DCHECK((*histogram)->HasValidRangeChecksum()); | |
| 1016 if (lock_ == NULL) | 1018 if (lock_ == NULL) |
| 1017 return; | 1019 return histogram; |
| 1018 base::AutoLock auto_lock(*lock_); | 1020 base::AutoLock auto_lock(*lock_); |
| 1019 if (!histograms_) | 1021 if (!histograms_) |
| 1020 return; | 1022 return histogram; |
| 1021 const std::string name = (*histogram)->histogram_name(); | 1023 const std::string name = histogram->histogram_name(); |
| 1022 HistogramMap::iterator it = histograms_->find(name); | 1024 HistogramMap::iterator it = histograms_->find(name); |
| 1023 // Avoid overwriting a previous registration. | 1025 // Avoid overwriting a previous registration. |
| 1024 if (histograms_->end() == it) | 1026 if (histograms_->end() == it) { |
| 1025 (*histograms_)[name] = *histogram; | 1027 (*histograms_)[name] = histogram; |
| 1026 else | 1028 } else { |
| 1027 *histogram = it->second; | 1029 delete histogram; // We already have one by this name. |
| 1030 histogram = it->second; |
| 1031 } |
| 1032 return histogram; |
| 1028 } | 1033 } |
| 1029 | 1034 |
| 1030 // static | 1035 // static |
| 1031 void StatisticsRecorder::WriteHTMLGraph(const std::string& query, | 1036 void StatisticsRecorder::WriteHTMLGraph(const std::string& query, |
| 1032 std::string* output) { | 1037 std::string* output) { |
| 1033 if (!IsActive()) | 1038 if (!IsActive()) |
| 1034 return; | 1039 return; |
| 1035 output->append("<html><head><title>About Histograms"); | 1040 output->append("<html><head><title>About Histograms"); |
| 1036 if (!query.empty()) | 1041 if (!query.empty()) |
| 1037 output->append(" - " + query); | 1042 output->append(" - " + query); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 return; | 1085 return; |
| 1081 for (HistogramMap::iterator it = histograms_->begin(); | 1086 for (HistogramMap::iterator it = histograms_->begin(); |
| 1082 histograms_->end() != it; | 1087 histograms_->end() != it; |
| 1083 ++it) { | 1088 ++it) { |
| 1084 DCHECK_EQ(it->first, it->second->histogram_name()); | 1089 DCHECK_EQ(it->first, it->second->histogram_name()); |
| 1085 output->push_back(it->second); | 1090 output->push_back(it->second); |
| 1086 } | 1091 } |
| 1087 } | 1092 } |
| 1088 | 1093 |
| 1089 bool StatisticsRecorder::FindHistogram(const std::string& name, | 1094 bool StatisticsRecorder::FindHistogram(const std::string& name, |
| 1090 scoped_refptr<Histogram>* histogram) { | 1095 Histogram** histogram) { |
| 1091 if (lock_ == NULL) | 1096 if (lock_ == NULL) |
| 1092 return false; | 1097 return false; |
| 1093 base::AutoLock auto_lock(*lock_); | 1098 base::AutoLock auto_lock(*lock_); |
| 1094 if (!histograms_) | 1099 if (!histograms_) |
| 1095 return false; | 1100 return false; |
| 1096 HistogramMap::iterator it = histograms_->find(name); | 1101 HistogramMap::iterator it = histograms_->find(name); |
| 1097 if (histograms_->end() == it) | 1102 if (histograms_->end() == it) |
| 1098 return false; | 1103 return false; |
| 1099 *histogram = it->second; | 1104 *histogram = it->second; |
| 1100 return true; | 1105 return true; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1117 } | 1122 } |
| 1118 | 1123 |
| 1119 // static | 1124 // static |
| 1120 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; | 1125 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; |
| 1121 // static | 1126 // static |
| 1122 base::Lock* StatisticsRecorder::lock_ = NULL; | 1127 base::Lock* StatisticsRecorder::lock_ = NULL; |
| 1123 // static | 1128 // static |
| 1124 bool StatisticsRecorder::dump_on_exit_ = false; | 1129 bool StatisticsRecorder::dump_on_exit_ = false; |
| 1125 | 1130 |
| 1126 } // namespace base | 1131 } // namespace base |
| OLD | NEW |