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

Side by Side Diff: base/metrics/histogram_samples.h

Issue 2832333002: Revert of Embed a single sample in histogram metadata. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/metrics/histogram.cc ('k') | base/metrics/histogram_samples.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 #ifndef BASE_METRICS_HISTOGRAM_SAMPLES_H_ 5 #ifndef BASE_METRICS_HISTOGRAM_SAMPLES_H_
6 #define BASE_METRICS_HISTOGRAM_SAMPLES_H_ 6 #define BASE_METRICS_HISTOGRAM_SAMPLES_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
11 #include <memory> 11 #include <memory>
12 12
13 #include "base/atomicops.h" 13 #include "base/atomicops.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/metrics/histogram_base.h" 15 #include "base/metrics/histogram_base.h"
16 16
17 namespace base { 17 namespace base {
18 18
19 class Pickle; 19 class Pickle;
20 class PickleIterator; 20 class PickleIterator;
21 class SampleCountIterator; 21 class SampleCountIterator;
22 22
23 // HistogramSamples is a container storing all samples of a histogram. All 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. 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 25 // If this structure changes, bump the version number for kTypeIdHistogram
26 // in persistent_histogram_allocator.cc. 26 // in persistent_histogram_allocator.cc.
27 //
28 // Note that though these samples are individually consistent (through the use
29 // of atomic operations on the counts), there is only "eventual consistency"
30 // overall when multiple threads are accessing this data. That means that the
31 // sum, redundant-count, etc. could be momentarily out-of-sync with the stored
32 // counts but will settle to a consistent "steady state" once all threads have
33 // exited this code.
34 class BASE_EXPORT HistogramSamples { 27 class BASE_EXPORT HistogramSamples {
35 public: 28 public:
36 // A single bucket and count. To fit within a single atomic on 32-bit build
37 // architectures, both |bucket| and |count| are limited in size to 16 bits.
38 // This limits the functionality somewhat but if an entry can't fit then
39 // the full array of samples can be allocated and used.
40 struct SingleSample {
41 uint16_t bucket;
42 uint16_t count;
43 };
44
45 // A structure for managing an atomic single sample. Because this is generally
46 // used in association with other atomic values, the defined methods use
47 // acquire/release operations to guarantee ordering with outside values.
48 union AtomicSingleSample {
49 AtomicSingleSample() : as_atomic(0) {}
50 AtomicSingleSample(subtle::Atomic32 rhs) : as_atomic(rhs) {}
51
52 // Returns the single sample in an atomic manner. This in an "acquire"
53 // load. The returned sample isn't shared and thus its fields can be safely
54 // accessed.
55 SingleSample Load() const;
56
57 // Extracts the single sample in an atomic manner. If |disable| is true
58 // then this object will be set so it will never accumulate another value.
59 // This is "no barrier" so doesn't enforce ordering with other atomic ops.
60 SingleSample Extract(bool disable);
61
62 // Adds a given count to the held bucket. If not possible, it returns false
63 // and leaves the parts unchanged. Once extracted/disabled, this always
64 // returns false. This in an "acquire/release" operation.
65 bool Accumulate(size_t bucket, HistogramBase::Count count);
66
67 // Returns if the sample has been "disabled" (via Extract) and thus not
68 // allowed to accept further accumulation.
69 bool IsDisabled() const;
70
71 private:
72 // union field: The actual sample bucket and count.
73 SingleSample as_parts;
74
75 // union field: The sample as an atomic value. Atomic64 would provide
76 // more flexibility but isn't available on all builds. This can hold a
77 // special, internal "disabled" value indicating that it must not accept
78 // further accumulation.
79 subtle::Atomic32 as_atomic;
80 };
81
82 // A structure of information about the data, common to all sample containers.
83 // Because of how this is used in persistent memory, it must be a POD object
84 // that makes sense when initialized to all zeros.
85 struct Metadata { 29 struct Metadata {
86 // Expected size for 32/64-bit check. 30 // Expected size for 32/64-bit check.
87 static constexpr size_t kExpectedInstanceSize = 24; 31 static constexpr size_t kExpectedInstanceSize = 24;
88 32
89 // Initialized when the sample-set is first created with a value provided 33 // Initialized when the sample-set is first created with a value provided
90 // by the caller. It is generally used to identify the sample-set across 34 // by the caller. It is generally used to identify the sample-set across
91 // threads and processes, though not necessarily uniquely as it is possible 35 // threads and processes, though not necessarily uniquely as it is possible
92 // to have multiple sample-sets representing subsets of the data. 36 // to have multiple sample-sets representing subsets of the data.
93 uint64_t id; 37 uint64_t id;
94 38
(...skipping 12 matching lines...) Expand all
107 51
108 // A "redundant" count helps identify memory corruption. It redundantly 52 // A "redundant" count helps identify memory corruption. It redundantly
109 // stores the total number of samples accumulated in the histogram. We 53 // stores the total number of samples accumulated in the histogram. We
110 // can compare this count to the sum of the counts (TotalCount() function), 54 // can compare this count to the sum of the counts (TotalCount() function),
111 // and detect problems. Note, depending on the implementation of different 55 // and detect problems. Note, depending on the implementation of different
112 // histogram types, there might be races during histogram accumulation 56 // histogram types, there might be races during histogram accumulation
113 // and snapshotting that we choose to accept. In this case, the tallies 57 // and snapshotting that we choose to accept. In this case, the tallies
114 // might mismatch even when no memory corruption has happened. 58 // might mismatch even when no memory corruption has happened.
115 HistogramBase::AtomicCount redundant_count; 59 HistogramBase::AtomicCount redundant_count;
116 60
117 // A single histogram value and associated count. This allows histograms 61 // 4 bytes of padding to explicitly extend this structure to a multiple of
118 // that typically report only a single value to not require full storage 62 // 64-bits. This is required to ensure the structure is the same size on
119 // to be allocated. 63 // both 32-bit and 64-bit builds.
120 AtomicSingleSample single_sample; // 32 bits 64 char padding[4];
121 }; 65 };
122 66
123 // Because structures held in persistent memory must be POD, there can be no 67 // Because sturctures held in persistent memory must be POD, there can be no
124 // default constructor to clear the fields. This derived class exists just 68 // default constructor to clear the fields. This derived class exists just
125 // to clear them when being allocated on the heap. 69 // to clear them when being allocated on the heap.
126 struct BASE_EXPORT LocalMetadata : Metadata { 70 struct LocalMetadata : Metadata {
127 LocalMetadata(); 71 LocalMetadata() {
72 id = 0;
73 sum = 0;
74 redundant_count = 0;
75 }
128 }; 76 };
129 77
130 explicit HistogramSamples(uint64_t id); 78 explicit HistogramSamples(uint64_t id);
131 HistogramSamples(uint64_t id, Metadata* meta); 79 HistogramSamples(uint64_t id, Metadata* meta);
132 virtual ~HistogramSamples(); 80 virtual ~HistogramSamples();
133 81
134 virtual void Accumulate(HistogramBase::Sample value, 82 virtual void Accumulate(HistogramBase::Sample value,
135 HistogramBase::Count count) = 0; 83 HistogramBase::Count count) = 0;
136 virtual HistogramBase::Count GetCount(HistogramBase::Sample value) const = 0; 84 virtual HistogramBase::Count GetCount(HistogramBase::Sample value) const = 0;
137 virtual HistogramBase::Count TotalCount() const = 0; 85 virtual HistogramBase::Count TotalCount() const = 0;
(...skipping 19 matching lines...) Expand all
157 } 105 }
158 HistogramBase::Count redundant_count() const { 106 HistogramBase::Count redundant_count() const {
159 return subtle::NoBarrier_Load(&meta_->redundant_count); 107 return subtle::NoBarrier_Load(&meta_->redundant_count);
160 } 108 }
161 109
162 protected: 110 protected:
163 // Based on |op| type, add or subtract sample counts data from the iterator. 111 // Based on |op| type, add or subtract sample counts data from the iterator.
164 enum Operator { ADD, SUBTRACT }; 112 enum Operator { ADD, SUBTRACT };
165 virtual bool AddSubtractImpl(SampleCountIterator* iter, Operator op) = 0; 113 virtual bool AddSubtractImpl(SampleCountIterator* iter, Operator op) = 0;
166 114
167 // Accumulates to the embedded single-sample field if possible. Returns true 115 void IncreaseSum(int64_t diff);
168 // on success, false otherwise. Sum and redundant-count are also updated in 116 void IncreaseRedundantCount(HistogramBase::Count diff);
169 // the success case.
170 bool AccumulateSingleSample(HistogramBase::Sample value,
171 HistogramBase::Count count,
172 size_t bucket);
173
174 // Atomically adjust the sum and redundant-count.
175 void IncreaseSumAndCount(int64_t sum, HistogramBase::Count count);
176
177 AtomicSingleSample& single_sample() { return meta_->single_sample; }
178 const AtomicSingleSample& single_sample() const {
179 return meta_->single_sample;
180 }
181 117
182 private: 118 private:
183 // In order to support histograms shared through an external memory segment, 119 // In order to support histograms shared through an external memory segment,
184 // meta values may be the local storage or external storage depending on the 120 // meta values may be the local storage or external storage depending on the
185 // wishes of the derived class. 121 // wishes of the derived class.
186 LocalMetadata local_meta_; 122 LocalMetadata local_meta_;
187 Metadata* meta_; 123 Metadata* meta_;
188 124
189 DISALLOW_COPY_AND_ASSIGN(HistogramSamples); 125 DISALLOW_COPY_AND_ASSIGN(HistogramSamples);
190 }; 126 };
(...skipping 11 matching lines...) Expand all
202 virtual void Get(HistogramBase::Sample* min, 138 virtual void Get(HistogramBase::Sample* min,
203 HistogramBase::Sample* max, 139 HistogramBase::Sample* max,
204 HistogramBase::Count* count) const = 0; 140 HistogramBase::Count* count) const = 0;
205 141
206 // Get the index of current histogram bucket. 142 // Get the index of current histogram bucket.
207 // For histograms that don't use predefined buckets, it returns false. 143 // For histograms that don't use predefined buckets, it returns false.
208 // Requires: !Done(); 144 // Requires: !Done();
209 virtual bool GetBucketIndex(size_t* index) const; 145 virtual bool GetBucketIndex(size_t* index) const;
210 }; 146 };
211 147
212 class BASE_EXPORT SingleSampleIterator : public SampleCountIterator {
213 public:
214 SingleSampleIterator(HistogramBase::Sample min,
215 HistogramBase::Sample max,
216 HistogramBase::Count count);
217 SingleSampleIterator(HistogramBase::Sample min,
218 HistogramBase::Sample max,
219 HistogramBase::Count count,
220 size_t bucket_index);
221 ~SingleSampleIterator() override;
222
223 // SampleCountIterator:
224 bool Done() const override;
225 void Next() override;
226 void Get(HistogramBase::Sample* min,
227 HistogramBase::Sample* max,
228 HistogramBase::Count* count) const override;
229
230 // SampleVector uses predefined buckets so iterator can return bucket index.
231 bool GetBucketIndex(size_t* index) const override;
232
233 private:
234 // Information about the single value to return.
235 const HistogramBase::Sample min_;
236 const HistogramBase::Sample max_;
237 const size_t bucket_index_;
238 HistogramBase::Count count_;
239 };
240
241 } // namespace base 148 } // namespace base
242 149
243 #endif // BASE_METRICS_HISTOGRAM_SAMPLES_H_ 150 #endif // BASE_METRICS_HISTOGRAM_SAMPLES_H_
OLDNEW
« no previous file with comments | « base/metrics/histogram.cc ('k') | base/metrics/histogram_samples.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698