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

Unified Diff: base/metrics/histogram_samples.h

Issue 2811713003: Embed a single sample in histogram metadata. (Closed)
Patch Set: addressed review comments by asvitkine 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 side-by-side diff with in-line comments
Download patch
Index: base/metrics/histogram_samples.h
diff --git a/base/metrics/histogram_samples.h b/base/metrics/histogram_samples.h
index 93f6d21c8aabd34eed61dd9c20d2e030cabada8f..9c9716f08c53ef212bfab7c7bdb5a18c4b586bff 100644
--- a/base/metrics/histogram_samples.h
+++ b/base/metrics/histogram_samples.h
@@ -24,8 +24,55 @@ class SampleCountIterator;
// elements must be of a fixed width to ensure 32/64-bit interoperability.
// If this structure changes, bump the version number for kTypeIdHistogram
// in persistent_histogram_allocator.cc.
+//
+// Note that though these samples are individually consistent (through the use
+// of atomic operations on the counts), there is only "eventual consistency"
+// overall when multiple threads are accessing this data. That means that the
+// sum, redundant-count, etc. could be momentarily out-of-sync with the stored
+// counts but will settle to a consistent "steady state" once all threads have
+// exited this code.
class BASE_EXPORT HistogramSamples {
public:
+ // A single value and count. To fit within a single atomic on 32-bit build
+ // architectures, both |value| and |count| are reduced in size to 16 bits.
+ // This limits the functionality somewhat but if an entry can't fit then
+ // the full array of samples can be allocated and used.
+ struct SingleSample {
+ 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
+ int16_t count;
+ };
+
+ // A structure for managing an atomic single sample. Because this is generally
+ // used in association with other atomic values, the defined methods use
+ // acquire/release operations to guarantee ordering with outside values.
+ union AtomicSingleSample {
+ AtomicSingleSample() : as_atomic(0) {}
+ AtomicSingleSample(subtle::Atomic32 rhs) : as_atomic(rhs) {}
+
+ // Returns the single value in an atomic manner. This in an "acquire"
+ // load. The returned value isn't shared and thus its parts can be safely
+ // accessed.
+ SingleSample Load() const;
+
+ // Extracts the single value in an atomic manner. If |disable| is true then
+ // the single-sample will be set so it can never accumulate another value.
+ // This is "no barrier" so doesn't enforce ordering with other atomic ops.
+ SingleSample Extract(bool disable);
+
+ // Adds a given count to the held value. If not possible, it returns false
+ // and leaves the internal value unchanged. This in an "acquire/release"
+ // operation. Once extracted/disabled, this always returns false.
+ bool Accumulate(HistogramBase::Sample value, HistogramBase::Count count);
+
+ private:
+ // The actual sample value and count.
+ SingleSample as_parts;
+
+ // The sample as an atomic value. Atomic64 would provide more flexibility
+ // 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.
+ subtle::Atomic32 as_atomic;
+ };
+
struct Metadata {
// Expected size for 32/64-bit check.
static constexpr size_t kExpectedInstanceSize = 24;
@@ -58,21 +105,17 @@ class BASE_EXPORT HistogramSamples {
// might mismatch even when no memory corruption has happened.
HistogramBase::AtomicCount redundant_count;
- // 4 bytes of padding to explicitly extend this structure to a multiple of
- // 64-bits. This is required to ensure the structure is the same size on
- // both 32-bit and 64-bit builds.
- char padding[4];
+ // A single histogram value and associated count. This allows histograms
+ // that typically report only a single value to not require full storage
+ // to be allocated.
+ AtomicSingleSample single_sample; // 32 bits
};
// 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.
// default constructor to clear the fields. This derived class exists just
// to clear them when being allocated on the heap.
- struct LocalMetadata : Metadata {
- LocalMetadata() {
- id = 0;
- sum = 0;
- redundant_count = 0;
- }
+ struct BASE_EXPORT LocalMetadata : Metadata {
+ LocalMetadata();
};
explicit HistogramSamples(uint64_t id);
@@ -112,8 +155,15 @@ class BASE_EXPORT HistogramSamples {
enum Operator { ADD, SUBTRACT };
virtual bool AddSubtractImpl(SampleCountIterator* iter, Operator op) = 0;
- void IncreaseSum(int64_t diff);
- void IncreaseRedundantCount(HistogramBase::Count diff);
+ bool AccumulateSingleSample(HistogramBase::Sample value,
+ HistogramBase::Count count);
+
+ void IncreaseSumAndCount(int64_t sum, HistogramBase::Count count);
+
+ AtomicSingleSample& single_sample() { return meta_->single_sample; }
+ const AtomicSingleSample& single_sample() const {
+ return meta_->single_sample;
+ }
private:
// In order to support histograms shared through an external memory segment,
@@ -145,6 +195,35 @@ class BASE_EXPORT SampleCountIterator {
virtual bool GetBucketIndex(size_t* index) const;
};
+class BASE_EXPORT SingleSampleIterator : public SampleCountIterator {
+ public:
+ SingleSampleIterator(HistogramBase::Sample min,
+ HistogramBase::Sample max,
+ HistogramBase::Count count);
+ SingleSampleIterator(HistogramBase::Sample min,
+ HistogramBase::Sample max,
+ HistogramBase::Count count,
+ size_t bucket_index);
+ ~SingleSampleIterator() override;
+
+ // 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.
+ bool Done() const override;
+ void Next() override;
+ void Get(HistogramBase::Sample* min,
+ HistogramBase::Sample* max,
+ HistogramBase::Count* count) const override;
+
+ // SampleVector uses predefined buckets, so iterator can return bucket index.
+ bool GetBucketIndex(size_t* index) const override;
+
+ private:
+ // Information about the single value to return.
+ const HistogramBase::Sample min_;
+ const HistogramBase::Sample max_;
+ const size_t bucket_index_;
+ HistogramBase::Count count_;
+};
+
} // namespace base
#endif // BASE_METRICS_HISTOGRAM_SAMPLES_H_

Powered by Google App Engine
This is Rietveld 408576698