1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_METRICS_HISTOGRAM_SAMPLES_H_ 6 #define BASE_METRICS_HISTOGRAM_SAMPLES_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 13 #include "base/atomicops.h" 14 #include "base/macros.h" 15 #include "base/metrics/histogram_base.h" 16 17 namespace base { 18 19 class Pickle; 20 class PickleIterator; 21 class SampleCountIterator; 22 23 // HistogramSamples is a container storing all samples of a histogram. All 24 // elements must be of a fixed width to ensure 32/64-bit interoperability. 25 // If this structure changes, bump the version number for kTypeIdHistogram 26 // in persistent_histogram_allocator.cc. 27 class BASE_EXPORT HistogramSamples { 28 public: 29 struct Metadata { 30 // Initialized when the sample-set is first created with a value provided 31 // by the caller. It is generally used to identify the sample-set across 32 // threads and processes, though not necessarily uniquely as it is possible 33 // to have multiple sample-sets representing subsets of the data. 34 uint64_t id; 35 36 // The sum of all the entries, effectivly the sum(sample * count) for 37 // all samples. Despite being atomic, no guarantees are made on the 38 // accuracy of this value; there may be races during histogram 39 // accumulation and snapshotting that we choose to accept. It should 40 // be treated as approximate. 41 #ifdef ARCH_CPU_64_BITS 42 subtle::Atomic64 sum; 43 #else 44 // 32-bit systems don't have atomic 64-bit operations. Use a basic type 45 // and don't worry about "shearing". 46 int64_t sum; 47 #endif 48 49 // A "redundant" count helps identify memory corruption. It redundantly 50 // stores the total number of samples accumulated in the histogram. We 51 // can compare this count to the sum of the counts (TotalCount() function), 52 // and detect problems. Note, depending on the implementation of different 53 // histogram types, there might be races during histogram accumulation 54 // and snapshotting that we choose to accept. In this case, the tallies 55 // might mismatch even when no memory corruption has happened. 56 HistogramBase::AtomicCount redundant_count; 57 MetadataMetadata58 Metadata() : id(0), sum(0), redundant_count(0) {} 59 }; 60 61 explicit HistogramSamples(uint64_t id); 62 HistogramSamples(uint64_t id, Metadata* meta); 63 virtual ~HistogramSamples(); 64 65 virtual void Accumulate(HistogramBase::Sample value, 66 HistogramBase::Count count) = 0; 67 virtual HistogramBase::Count GetCount(HistogramBase::Sample value) const = 0; 68 virtual HistogramBase::Count TotalCount() const = 0; 69 70 virtual void Add(const HistogramSamples& other); 71 72 // Add from serialized samples. 73 virtual bool AddFromPickle(PickleIterator* iter); 74 75 virtual void Subtract(const HistogramSamples& other); 76 77 virtual std::unique_ptr<SampleCountIterator> Iterator() const = 0; 78 virtual bool Serialize(Pickle* pickle) const; 79 80 // Accessor fuctions. id()81 uint64_t id() const { return meta_->id; } sum()82 int64_t sum() const { 83 #ifdef ARCH_CPU_64_BITS 84 return subtle::NoBarrier_Load(&meta_->sum); 85 #else 86 return meta_->sum; 87 #endif 88 } redundant_count()89 HistogramBase::Count redundant_count() const { 90 return subtle::NoBarrier_Load(&meta_->redundant_count); 91 } 92 93 protected: 94 // Based on |op| type, add or subtract sample counts data from the iterator. 95 enum Operator { ADD, SUBTRACT }; 96 virtual bool AddSubtractImpl(SampleCountIterator* iter, Operator op) = 0; 97 98 void IncreaseSum(int64_t diff); 99 void IncreaseRedundantCount(HistogramBase::Count diff); 100 101 private: 102 // In order to support histograms shared through an external memory segment, 103 // meta values may be the local storage or external storage depending on the 104 // wishes of the derived class. 105 Metadata local_meta_; 106 Metadata* meta_; 107 108 DISALLOW_COPY_AND_ASSIGN(HistogramSamples); 109 }; 110 111 class BASE_EXPORT SampleCountIterator { 112 public: 113 virtual ~SampleCountIterator(); 114 115 virtual bool Done() const = 0; 116 virtual void Next() = 0; 117 118 // Get the sample and count at current position. 119 // |min| |max| and |count| can be NULL if the value is not of interest. 120 // Requires: !Done(); 121 virtual void Get(HistogramBase::Sample* min, 122 HistogramBase::Sample* max, 123 HistogramBase::Count* count) const = 0; 124 125 // Get the index of current histogram bucket. 126 // For histograms that don't use predefined buckets, it returns false. 127 // Requires: !Done(); 128 virtual bool GetBucketIndex(size_t* index) const; 129 }; 130 131 } // namespace base 132 133 #endif // BASE_METRICS_HISTOGRAM_SAMPLES_H_ 134