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

Unified Diff: base/metrics/sample_vector.h

Issue 2811713003: Embed a single sample in histogram metadata. (Closed)
Patch Set: rebased 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
« no previous file with comments | « base/metrics/sample_map.cc ('k') | base/metrics/sample_vector.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/metrics/sample_vector.h
diff --git a/base/metrics/sample_vector.h b/base/metrics/sample_vector.h
index ee26c52101912df69856d107ebc330390269b0cf..a264b7e7d44684629c71635be39e4f5f9b2843c9 100644
--- a/base/metrics/sample_vector.h
+++ b/base/metrics/sample_vector.h
@@ -14,28 +14,28 @@
#include <memory>
#include <vector>
+#include "base/atomicops.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
+#include "base/metrics/bucket_ranges.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_samples.h"
+#include "base/metrics/persistent_memory_allocator.h"
namespace base {
class BucketRanges;
-class BASE_EXPORT SampleVector : public HistogramSamples {
+class BASE_EXPORT SampleVectorBase : public HistogramSamples {
public:
- explicit SampleVector(const BucketRanges* bucket_ranges);
- SampleVector(uint64_t id, const BucketRanges* bucket_ranges);
- SampleVector(uint64_t id,
- HistogramBase::AtomicCount* counts,
- size_t counts_size,
- Metadata* meta,
- const BucketRanges* bucket_ranges);
- ~SampleVector() override;
+ SampleVectorBase(uint64_t id, const BucketRanges* bucket_ranges);
+ SampleVectorBase(uint64_t id,
+ Metadata* meta,
+ const BucketRanges* bucket_ranges);
+ ~SampleVectorBase() override;
- // HistogramSamples implementation:
+ // HistogramSamples:
void Accumulate(HistogramBase::Sample value,
HistogramBase::Count count) override;
HistogramBase::Count GetCount(HistogramBase::Sample value) const override;
@@ -52,25 +52,103 @@ class BASE_EXPORT SampleVector : public HistogramSamples {
virtual size_t GetBucketIndex(HistogramBase::Sample value) const;
+ // Moves the single-sample value to a mounted "counts" array.
+ void MoveSingleSampleToCounts();
+
+ // Mounts (creating if necessary) an array of "counts" for multi-value
+ // storage.
+ void MountCountsStorageAndMoveSingleSample();
+
+ // Mounts "counts" storage that already exists. This does not attempt to move
+ // any single-sample information to that storage as that would violate the
+ // "const" restriction that is often used to indicate read-only memory.
+ virtual bool MountExistingCountsStorage() const = 0;
+
+ // Creates "counts" storage and returns a pointer to it. Ownership of the
+ // array remains with the called method but will never change. This must be
+ // called while some sort of lock is held to prevent reentry.
+ virtual HistogramBase::Count* CreateCountsStorageWhileLocked() = 0;
+
+ HistogramBase::AtomicCount* counts() {
+ return reinterpret_cast<HistogramBase::AtomicCount*>(
+ subtle::Acquire_Load(&counts_));
+ }
+
+ const HistogramBase::AtomicCount* counts() const {
+ return reinterpret_cast<HistogramBase::AtomicCount*>(
+ subtle::Acquire_Load(&counts_));
+ }
+
+ void set_counts(const HistogramBase::AtomicCount* counts) const {
+ subtle::Release_Store(&counts_, reinterpret_cast<uintptr_t>(counts));
+ }
+
+ size_t counts_size() const { return bucket_ranges_->bucket_count(); }
+
private:
+ friend class SampleVectorTest;
FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts);
FRIEND_TEST_ALL_PREFIXES(SharedHistogramTest, CorruptSampleCounts);
- // In the case where this class manages the memory, here it is.
- std::vector<HistogramBase::AtomicCount> local_counts_;
-
- // These are raw pointers rather than objects for flexibility. The actual
- // memory is either managed by local_counts_ above or by an external object
- // and passed in directly.
- HistogramBase::AtomicCount* counts_;
- size_t counts_size_;
+ // |counts_| is actually a pointer to a HistogramBase::AtomicCount array but
+ // is held as an AtomicWord for concurrency reasons. When combined with the
+ // single_sample held in the metadata, there are four possible states:
+ // 1) single_sample == zero, counts_ == null
+ // 2) single_sample != zero, counts_ == null
+ // 3) single_sample != zero, counts_ != null BUT IS EMPTY
+ // 4) single_sample == zero, counts_ != null and may have data
+ // Once |counts_| is set, it can never revert and any existing single-sample
+ // must be moved to this storage. It is mutable because changing it doesn't
+ // change the (const) data but must adapt if a non-const object causes the
+ // storage to be allocated and updated.
+ mutable subtle::AtomicWord counts_ = 0;
// Shares the same BucketRanges with Histogram object.
const BucketRanges* const bucket_ranges_;
+ DISALLOW_COPY_AND_ASSIGN(SampleVectorBase);
+};
+
+// A sample vector that uses local memory for the counts array.
+class BASE_EXPORT SampleVector : public SampleVectorBase {
+ public:
+ explicit SampleVector(const BucketRanges* bucket_ranges);
+ SampleVector(uint64_t id, const BucketRanges* bucket_ranges);
+ ~SampleVector() override;
+
+ private:
+ // SampleVectorBase:
+ bool MountExistingCountsStorage() const override;
+ HistogramBase::Count* CreateCountsStorageWhileLocked() override;
+
+ // Simple local storage for counts.
+ mutable std::vector<HistogramBase::AtomicCount> local_counts_;
+
DISALLOW_COPY_AND_ASSIGN(SampleVector);
};
+// A sample vector that uses persistent memory for the counts array.
+class BASE_EXPORT PersistentSampleVector : public SampleVectorBase {
+ public:
+ PersistentSampleVector(uint64_t id,
+ const BucketRanges* bucket_ranges,
+ Metadata* meta,
+ const DelayedPersistentAllocation& counts);
+ ~PersistentSampleVector() override;
+
+ private:
+ // SampleVectorBase:
+ bool MountExistingCountsStorage() const override;
+ HistogramBase::Count* CreateCountsStorageWhileLocked() override;
+
+ // Persistent storage for counts.
+ DelayedPersistentAllocation persistent_counts_;
+
+ DISALLOW_COPY_AND_ASSIGN(PersistentSampleVector);
+};
+
+// An iterator for sample vectors. This could be defined privately in the .cc
+// file but is here for easy testing.
class BASE_EXPORT SampleVectorIterator : public SampleCountIterator {
public:
SampleVectorIterator(const std::vector<HistogramBase::AtomicCount>* counts,
« no previous file with comments | « base/metrics/sample_map.cc ('k') | base/metrics/sample_vector.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698