OLD | NEW |
---|---|
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. | |
27 class BASE_EXPORT HistogramSamples { | 34 class BASE_EXPORT HistogramSamples { |
28 public: | 35 public: |
36 // A single value and count. To fit within a single atomic on 32-bit build | |
37 // architectures, both |value| and |count| are reduced 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 int16_t value; | |
Alexei Svitkine (slow)
2017/04/18 20:52:20
uint16_t for both?
Or is there a valid case for t
bcwhite
2017/04/19 18:13:02
It was significantly simpler this way because the
bcwhite
2017/04/19 20:10:22
Another option is to change it from "value" to "bu
| |
42 int16_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 value in an atomic manner. This in an "acquire" | |
53 // load. The returned value isn't shared and thus its parts can be safely | |
54 // accessed. | |
55 SingleSample Load() const; | |
56 | |
57 // Extracts the single value in an atomic manner. If |disable| is true then | |
58 // the single-sample will be set so it can 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 value. If not possible, it returns false | |
63 // and leaves the internal value unchanged. This in an "acquire/release" | |
64 // operation. Once extracted/disabled, this always returns false. | |
65 bool Accumulate(HistogramBase::Sample value, HistogramBase::Count count); | |
66 | |
67 private: | |
68 // The actual sample value and count. | |
69 SingleSample as_parts; | |
70 | |
71 // The sample as an atomic value. Atomic64 would provide more flexibility | |
72 // but isn't available on all builds. | |
Alexei Svitkine (slow)
2017/04/18 20:52:20
Please expand these field comments to mention that
bcwhite
2017/04/19 18:13:02
Done.
| |
73 subtle::Atomic32 as_atomic; | |
74 }; | |
75 | |
29 struct Metadata { | 76 struct Metadata { |
30 // Expected size for 32/64-bit check. | 77 // Expected size for 32/64-bit check. |
31 static constexpr size_t kExpectedInstanceSize = 24; | 78 static constexpr size_t kExpectedInstanceSize = 24; |
32 | 79 |
33 // Initialized when the sample-set is first created with a value provided | 80 // Initialized when the sample-set is first created with a value provided |
34 // by the caller. It is generally used to identify the sample-set across | 81 // by the caller. It is generally used to identify the sample-set across |
35 // threads and processes, though not necessarily uniquely as it is possible | 82 // threads and processes, though not necessarily uniquely as it is possible |
36 // to have multiple sample-sets representing subsets of the data. | 83 // to have multiple sample-sets representing subsets of the data. |
37 uint64_t id; | 84 uint64_t id; |
38 | 85 |
(...skipping 12 matching lines...) Expand all Loading... | |
51 | 98 |
52 // A "redundant" count helps identify memory corruption. It redundantly | 99 // A "redundant" count helps identify memory corruption. It redundantly |
53 // stores the total number of samples accumulated in the histogram. We | 100 // stores the total number of samples accumulated in the histogram. We |
54 // can compare this count to the sum of the counts (TotalCount() function), | 101 // can compare this count to the sum of the counts (TotalCount() function), |
55 // and detect problems. Note, depending on the implementation of different | 102 // and detect problems. Note, depending on the implementation of different |
56 // histogram types, there might be races during histogram accumulation | 103 // histogram types, there might be races during histogram accumulation |
57 // and snapshotting that we choose to accept. In this case, the tallies | 104 // and snapshotting that we choose to accept. In this case, the tallies |
58 // might mismatch even when no memory corruption has happened. | 105 // might mismatch even when no memory corruption has happened. |
59 HistogramBase::AtomicCount redundant_count; | 106 HistogramBase::AtomicCount redundant_count; |
60 | 107 |
61 // 4 bytes of padding to explicitly extend this structure to a multiple of | 108 // A single histogram value and associated count. This allows histograms |
62 // 64-bits. This is required to ensure the structure is the same size on | 109 // that typically report only a single value to not require full storage |
63 // both 32-bit and 64-bit builds. | 110 // to be allocated. |
64 char padding[4]; | 111 AtomicSingleSample single_sample; // 32 bits |
65 }; | 112 }; |
66 | 113 |
67 // Because sturctures held in persistent memory must be POD, there can be no | 114 // Because sturctures held in persistent memory must be POD, there can be no |
Alexei Svitkine (slow)
2017/04/18 20:52:20
Nit: structures is misspelled
bcwhite
2017/04/19 18:13:02
Done.
| |
68 // default constructor to clear the fields. This derived class exists just | 115 // default constructor to clear the fields. This derived class exists just |
69 // to clear them when being allocated on the heap. | 116 // to clear them when being allocated on the heap. |
70 struct LocalMetadata : Metadata { | 117 struct BASE_EXPORT LocalMetadata : Metadata { |
71 LocalMetadata() { | 118 LocalMetadata(); |
72 id = 0; | |
73 sum = 0; | |
74 redundant_count = 0; | |
75 } | |
76 }; | 119 }; |
77 | 120 |
78 explicit HistogramSamples(uint64_t id); | 121 explicit HistogramSamples(uint64_t id); |
79 HistogramSamples(uint64_t id, Metadata* meta); | 122 HistogramSamples(uint64_t id, Metadata* meta); |
80 virtual ~HistogramSamples(); | 123 virtual ~HistogramSamples(); |
81 | 124 |
82 virtual void Accumulate(HistogramBase::Sample value, | 125 virtual void Accumulate(HistogramBase::Sample value, |
83 HistogramBase::Count count) = 0; | 126 HistogramBase::Count count) = 0; |
84 virtual HistogramBase::Count GetCount(HistogramBase::Sample value) const = 0; | 127 virtual HistogramBase::Count GetCount(HistogramBase::Sample value) const = 0; |
85 virtual HistogramBase::Count TotalCount() const = 0; | 128 virtual HistogramBase::Count TotalCount() const = 0; |
(...skipping 19 matching lines...) Expand all Loading... | |
105 } | 148 } |
106 HistogramBase::Count redundant_count() const { | 149 HistogramBase::Count redundant_count() const { |
107 return subtle::NoBarrier_Load(&meta_->redundant_count); | 150 return subtle::NoBarrier_Load(&meta_->redundant_count); |
108 } | 151 } |
109 | 152 |
110 protected: | 153 protected: |
111 // Based on |op| type, add or subtract sample counts data from the iterator. | 154 // Based on |op| type, add or subtract sample counts data from the iterator. |
112 enum Operator { ADD, SUBTRACT }; | 155 enum Operator { ADD, SUBTRACT }; |
113 virtual bool AddSubtractImpl(SampleCountIterator* iter, Operator op) = 0; | 156 virtual bool AddSubtractImpl(SampleCountIterator* iter, Operator op) = 0; |
114 | 157 |
115 void IncreaseSum(int64_t diff); | 158 bool AccumulateSingleSample(HistogramBase::Sample value, |
116 void IncreaseRedundantCount(HistogramBase::Count diff); | 159 HistogramBase::Count count); |
160 | |
161 void IncreaseSumAndCount(int64_t sum, HistogramBase::Count count); | |
162 | |
163 AtomicSingleSample& single_sample() { return meta_->single_sample; } | |
164 const AtomicSingleSample& single_sample() const { | |
165 return meta_->single_sample; | |
166 } | |
117 | 167 |
118 private: | 168 private: |
119 // In order to support histograms shared through an external memory segment, | 169 // In order to support histograms shared through an external memory segment, |
120 // meta values may be the local storage or external storage depending on the | 170 // meta values may be the local storage or external storage depending on the |
121 // wishes of the derived class. | 171 // wishes of the derived class. |
122 LocalMetadata local_meta_; | 172 LocalMetadata local_meta_; |
123 Metadata* meta_; | 173 Metadata* meta_; |
124 | 174 |
125 DISALLOW_COPY_AND_ASSIGN(HistogramSamples); | 175 DISALLOW_COPY_AND_ASSIGN(HistogramSamples); |
126 }; | 176 }; |
(...skipping 11 matching lines...) Expand all Loading... | |
138 virtual void Get(HistogramBase::Sample* min, | 188 virtual void Get(HistogramBase::Sample* min, |
139 HistogramBase::Sample* max, | 189 HistogramBase::Sample* max, |
140 HistogramBase::Count* count) const = 0; | 190 HistogramBase::Count* count) const = 0; |
141 | 191 |
142 // Get the index of current histogram bucket. | 192 // Get the index of current histogram bucket. |
143 // For histograms that don't use predefined buckets, it returns false. | 193 // For histograms that don't use predefined buckets, it returns false. |
144 // Requires: !Done(); | 194 // Requires: !Done(); |
145 virtual bool GetBucketIndex(size_t* index) const; | 195 virtual bool GetBucketIndex(size_t* index) const; |
146 }; | 196 }; |
147 | 197 |
198 class BASE_EXPORT SingleSampleIterator : public SampleCountIterator { | |
199 public: | |
200 SingleSampleIterator(HistogramBase::Sample min, | |
201 HistogramBase::Sample max, | |
202 HistogramBase::Count count); | |
203 SingleSampleIterator(HistogramBase::Sample min, | |
204 HistogramBase::Sample max, | |
205 HistogramBase::Count count, | |
206 size_t bucket_index); | |
207 ~SingleSampleIterator() override; | |
208 | |
209 // SampleCountIterator implementation: | |
Alexei Svitkine (slow)
2017/04/18 20:52:20
Nit: Just // SampleCounterIterator:
(For new code
bcwhite
2017/04/19 18:13:02
Done.
| |
210 bool Done() const override; | |
211 void Next() override; | |
212 void Get(HistogramBase::Sample* min, | |
213 HistogramBase::Sample* max, | |
214 HistogramBase::Count* count) const override; | |
215 | |
216 // SampleVector uses predefined buckets, so iterator can return bucket index. | |
217 bool GetBucketIndex(size_t* index) const override; | |
218 | |
219 private: | |
220 // Information about the single value to return. | |
221 const HistogramBase::Sample min_; | |
222 const HistogramBase::Sample max_; | |
223 const size_t bucket_index_; | |
224 HistogramBase::Count count_; | |
225 }; | |
226 | |
148 } // namespace base | 227 } // namespace base |
149 | 228 |
150 #endif // BASE_METRICS_HISTOGRAM_SAMPLES_H_ | 229 #endif // BASE_METRICS_HISTOGRAM_SAMPLES_H_ |
OLD | NEW |