Chromium Code Reviews| Index: base/metrics/persistent_histogram_allocator.h |
| diff --git a/base/metrics/persistent_histogram_allocator.h b/base/metrics/persistent_histogram_allocator.h |
| index b2038c4314c704f572771648b76410fdcffd03b0..494ec60b77357734b6edbd539a2f99f5f0fbc3fd 100644 |
| --- a/base/metrics/persistent_histogram_allocator.h |
| +++ b/base/metrics/persistent_histogram_allocator.h |
| @@ -10,13 +10,18 @@ |
| #include "base/atomicops.h" |
| #include "base/base_export.h" |
| #include "base/feature_list.h" |
| +#include "base/id_map.h" |
| #include "base/memory/shared_memory.h" |
| #include "base/metrics/histogram_base.h" |
| #include "base/metrics/persistent_memory_allocator.h" |
| #include "base/strings/string_piece.h" |
| +#include "base/synchronization/lock.h" |
| namespace base { |
| +class PersistentSampleMapRecords; |
| +class PersistentSparseHistogramHelper; |
| + |
| // Feature definition for enabling histogram persistence. |
| BASE_EXPORT extern const Feature kPersistentHistogramsFeature; |
| @@ -101,6 +106,12 @@ class BASE_EXPORT PersistentHistogramAllocator { |
| // True, forgetting it otherwise. |
| void FinalizeHistogram(Reference ref, bool registered); |
| + // Returns the object that manages the persistent-sample-map records for a |
| + // given |id|. There is only one such object per-allocator-per-id on the |
| + // assumption that there is only ever one histogram object at a time that |
| + // would use a particular set of records. Ownership stays with this allocator. |
| + PersistentSampleMapRecords* GetSampleMapRecords(uint64_t id); |
| + |
| // Create internal histograms for tracking memory use and allocation sizes |
| // for allocator of |name| (which can simply be the result of Name()). This |
| // is done seperately from construction for situations such as when the |
| @@ -179,6 +190,9 @@ class BASE_EXPORT PersistentHistogramAllocator { |
| // The memory allocator that provides the actual histogram storage. |
| std::unique_ptr<PersistentMemoryAllocator> memory_allocator_; |
| + // The helper used to improve performance of sparse histograms. |
| + std::unique_ptr<PersistentSparseHistogramHelper> sparse_histogram_helper_; |
|
Alexei Svitkine (slow)
2016/04/13 15:53:50
Why is this a unique_ptr? Can it just be a member?
bcwhite
2016/04/13 22:45:03
I had originally planned to not create it until ne
|
| + |
| // A reference to the last-created histogram in the allocator, used to avoid |
| // trying to import what was just created. |
| // TODO(bcwhite): Change this to std::atomic<PMA::Reference> when available. |
| @@ -262,6 +276,132 @@ class BASE_EXPORT GlobalHistogramAllocator |
| DISALLOW_COPY_AND_ASSIGN(GlobalHistogramAllocator); |
| }; |
| + |
| +// A helper-class for sparse histograms so each instance of such doesn't have |
| +// to separately iterate over the entire memory segment. Though this class |
| +// will generally be accessed through the PersistentHistogramAllocator above, |
| +// it can be used independently on any PersistentMemoryAllocator (making it |
| +// useable for testing). This object supports only one instance of a sparse |
| +// histogram for a given id. Tests that create multiple identical histograms, |
| +// perhaps to simulate multiple processes, should create a separate helper |
| +// for each. |
| +class BASE_EXPORT PersistentSparseHistogramHelper { |
|
Alexei Svitkine (slow)
2016/04/13 15:53:50
Helper is not a very descriptive name. Can this be
bcwhite
2016/04/13 22:45:04
Done.
|
| + public: |
| + // Constructs the helper. The allocator must live longer than any helpers |
| + // that reference it. |
| + PersistentSparseHistogramHelper(PersistentMemoryAllocator* allocator); |
|
Alexei Svitkine (slow)
2016/04/13 15:53:50
Nit: explicit
bcwhite
2016/04/13 22:45:03
Done.
|
| + |
| + ~PersistentSparseHistogramHelper(); |
| + |
| + // Returns the object that manages the persistent-sample-map records for a |
| + // given |id|. There is only one such object per-allocator-per-id on the |
| + // assumption that there is only ever one histogram object at a time that |
| + // would use a particular set of records. Ownership stays with this helper. |
| + PersistentSampleMapRecords* GetSampleMapRecords(uint64_t id); |
| + |
| + // Convenience method that gets the object for a given reference so callers |
| + // don't have to also keep their own pointer to the appropriate allocator. |
| + template <typename T> |
|
Alexei Svitkine (slow)
2016/04/13 15:53:50
Does this need to be a template if we know it's ma
bcwhite
2016/04/13 22:45:03
It's a template because the type on which it's use
Alexei Svitkine (slow)
2016/04/14 19:30:03
Okay, maybe mention that in the method comment. Ot
bcwhite
2016/04/15 02:36:18
Will do.
|
| + T* GetAsObject(PersistentMemoryAllocator::Reference ref, uint32_t type_id) { |
| + return allocator_->GetAsObject<T>(ref, type_id); |
| + } |
| + |
| + private: |
| + friend class PersistentSampleMapRecords; |
| + |
| + // Like GetSampleMapRecords() above but operates when the |lock_| has |
| + // already been acquired. |
| + PersistentSampleMapRecords* GetSampleMapRecordsWhileLocked(uint64_t id); |
| + |
| + // Loads sample-map records looking for those belonging to the specified |
| + // |load_id|. Records found for other sample-maps are held for later use |
| + // without having to iterate again. This should only be called when the |
| + // |lock_| has been acquired. |
| + bool LoadRecordsForSampleMapWhileLocked(uint64_t load_id); |
|
Alexei Svitkine (slow)
2016/04/13 15:53:50
Nit: Why load_id if Load is already part of the me
bcwhite
2016/04/13 22:45:03
Because parameter names here need to match paramet
|
| + |
| + // Weak-pointer to the allocator used by the sparse histograms. |
| + PersistentMemoryAllocator* allocator_; |
| + |
| + // Iterator within the allocator for finding sample records. |
| + PersistentMemoryAllocator::Iterator record_iterator_; |
| + |
| + // Mapping of sample-map IDs to their sample records. |
| + IDMap<PersistentSampleMapRecords, IDMapOwnPointer, uint64_t> sample_records_; |
| + |
| + // A lock used for synchronizing changes to sample_records_. |
| + base::Lock lock_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PersistentSparseHistogramHelper); |
| +}; |
| + |
| + |
| +// This class manages sample-records used by the PersistentSampleMap containers |
| +// that underlie persistent SparseHistogram objects. It is broken out into a |
|
Alexei Svitkine (slow)
2016/04/13 15:53:50
This sentence is confusing since it's using plural
bcwhite
2016/04/13 22:45:03
Done.
|
| +// top-level class so that it can be forward-declared in other header files |
| +// rather than include this entire file as would be necessary if it were |
| +// declared within the PersistentSparseHistogramHelper class above. |
| +class BASE_EXPORT PersistentSampleMapRecords { |
| + public: |
| + // Constructs an instance of this class. The helper object must live longer |
| + // than all instances of this class that reference it, which is not usually |
| + // a problem since these objects are generally managed from within that |
| + // helper instance. |
| + PersistentSampleMapRecords(PersistentSparseHistogramHelper* helper, |
| + uint64_t sample_map_id); |
| + |
| + ~PersistentSampleMapRecords(); |
| + |
| + // Resets the internal state of seen/unseen records for its sample-map. |
| + // This should be done when creating a PersistentSampleMap so it does not |
| + // mistakenly resume from where a previous instance left off. Multiple, |
| + // sequential instances of such are common when reading histograms of |
| + // another process for periodic reporting to UMA. |
| + void Reset(); |
|
Alexei Svitkine (slow)
2016/04/13 15:53:50
I don't quite understand the reasoning here. It fe
bcwhite
2016/04/13 22:45:03
Done.
|
| + |
| + // Gets the next reference to a persistent sample-map record. The type and |
| + // layout of the data being referenced is defined entirely within the |
| + // PersistentSampleMap class. |
| + PersistentMemoryAllocator::Reference GetNext(); |
| + |
| + // Creates a new persistent sample-map record for sample |value| and returns |
| + // a reference to it. |
| + PersistentMemoryAllocator::Reference CreateNew(HistogramBase::Sample value); |
| + |
| + // Convenience method that gets the object for a given reference so callers |
| + // don't have to also keep their own pointer to the appropriate allocator. |
| + template <typename T> |
| + T* GetAsObject(PersistentMemoryAllocator::Reference ref, uint32_t type_id) { |
| + return helper_->GetAsObject<T>(ref, type_id); |
| + } |
| + |
| + private: |
| + friend PersistentSparseHistogramHelper; |
| + |
| + // Weak-pointer to the parent helper object. |
| + PersistentSparseHistogramHelper* helper_; |
| + |
| + // ID of PersistentSampleMap to which these records apply. |
| + uint64_t sample_map_id_; |
|
Alexei Svitkine (slow)
2016/04/13 15:53:50
Nit: const?
bcwhite
2016/04/13 22:45:04
Done.
|
| + |
| + // This is the count of how many "records" have already been read by the |
| + // owning sample-map. |
| + size_t seen_; |
| + |
| + // This is the set of records previously found for a sample map. Because |
| + // there is ever only one object with a given ID (typically a hash of a |
| + // histogram name) and because the parent SparseHistogram has acquired |
| + // its own lock before accessing the PersistentSampleMap it controls, this |
| + // list can be accessed without acquiring any additional lock. |
| + std::vector<PersistentMemoryAllocator::Reference> records_; |
| + |
| + // This is the set of records found during iteration through memory. It |
| + // is appended in bulk to "records". Access to this vector can be done |
| + // only while holding the parent helper's lock. |
| + std::vector<PersistentMemoryAllocator::Reference> found_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PersistentSampleMapRecords); |
| +}; |
| + |
| } // namespace base |
| #endif // BASE_METRICS_HISTOGRAM_PERSISTENCE_H_ |