| 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..7f46dc9664bd6a45d3c010f8cebd100e9ddce25a 100644
|
| --- a/base/metrics/persistent_histogram_allocator.h
|
| +++ b/base/metrics/persistent_histogram_allocator.h
|
| @@ -5,6 +5,7 @@
|
| #ifndef BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
|
| #define BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
|
|
|
| +#include <map>
|
| #include <memory>
|
|
|
| #include "base/atomicops.h"
|
| @@ -14,12 +15,157 @@
|
| #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 PersistentSparseHistogramDataManager;
|
| +
|
| // Feature definition for enabling histogram persistence.
|
| BASE_EXPORT extern const Feature kPersistentHistogramsFeature;
|
|
|
| +
|
| +// A data manager 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 manager
|
| +// for each.
|
| +class BASE_EXPORT PersistentSparseHistogramDataManager {
|
| + public:
|
| + // Constructs the data manager. The allocator must live longer than any
|
| + // managers that reference it.
|
| + explicit PersistentSparseHistogramDataManager(
|
| + PersistentMemoryAllocator* allocator);
|
| +
|
| + ~PersistentSparseHistogramDataManager();
|
| +
|
| + // Returns the object that manages the persistent-sample-map records for a
|
| + // given |id|. Only one |user| of this data is allowed at a time. This does
|
| + // an automatic Acquire() on the records. The user must call Release() on
|
| + // the returned object when it is finished with it. Ownership of the records
|
| + // object stays with this manager.
|
| + PersistentSampleMapRecords* UseSampleMapRecords(uint64_t id,
|
| + const void* user);
|
| +
|
| + // 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 allocator_->GetAsObject<T>(ref, type_id);
|
| + }
|
| +
|
| + private:
|
| + friend class PersistentSampleMapRecords;
|
| +
|
| + // Gets the object holding records for a given sample-map id when |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 be called only from a
|
| + // PersistentSampleMapRecords object because those objects have a contract
|
| + // that there are no other threads accessing the internal records_ field
|
| + // of the object that is passed in.
|
| + bool LoadRecords(PersistentSampleMapRecords* sample_map_records);
|
| +
|
| + // 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.
|
| + std::map<uint64_t, std::unique_ptr<PersistentSampleMapRecords>>
|
| + sample_records_;
|
| +
|
| + // A lock used for synchronizing changes to sample_records_.
|
| + base::Lock lock_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PersistentSparseHistogramDataManager);
|
| +};
|
| +
|
| +
|
| +// This class manages sample-records used by a PersistentSampleMap container
|
| +// that underlies a persistent SparseHistogram object. It is broken out into a
|
| +// 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 PersistentSparseHistogramDataManager class above.
|
| +class BASE_EXPORT PersistentSampleMapRecords {
|
| + public:
|
| + // Constructs an instance of this class. The manager 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
|
| + // manager instance.
|
| + PersistentSampleMapRecords(PersistentSparseHistogramDataManager* data_manager,
|
| + uint64_t sample_map_id);
|
| +
|
| + ~PersistentSampleMapRecords();
|
| +
|
| + // Resets the internal state for a new object using this data. The return
|
| + // value is "this" as a convenience.
|
| + PersistentSampleMapRecords* Acquire(const void* user);
|
| +
|
| + // Indicates that the using object is done with this data.
|
| + void Release(const void* user);
|
| +
|
| + // 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.
|
| + // This is expected to be used with the SampleRecord structure defined inside
|
| + // the persistent_sample_map.cc file but since that isn't exported (for
|
| + // cleanliness of the interface), a template is defined that will be
|
| + // resolved when used inside that file.
|
| + template <typename T>
|
| + T* GetAsObject(PersistentMemoryAllocator::Reference ref, uint32_t type_id) {
|
| + return data_manager_->GetAsObject<T>(ref, type_id);
|
| + }
|
| +
|
| + private:
|
| + friend PersistentSparseHistogramDataManager;
|
| +
|
| + // Weak-pointer to the parent data-manager object.
|
| + PersistentSparseHistogramDataManager* data_manager_;
|
| +
|
| + // ID of PersistentSampleMap to which these records apply.
|
| + const uint64_t sample_map_id_;
|
| +
|
| + // The current user of this set of records. It is used to ensure that no
|
| + // more than one object is using these records at a given time.
|
| + const void* user_ = nullptr;
|
| +
|
| + // This is the count of how many "records" have already been read by the
|
| + // owning sample-map.
|
| + size_t seen_ = 0;
|
| +
|
| + // 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 manager's lock.
|
| + std::vector<PersistentMemoryAllocator::Reference> found_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PersistentSampleMapRecords);
|
| +};
|
| +
|
| +
|
| // This class manages histograms created within a PersistentMemoryAllocator.
|
| class BASE_EXPORT PersistentHistogramAllocator {
|
| public:
|
| @@ -59,7 +205,7 @@ class BASE_EXPORT PersistentHistogramAllocator {
|
|
|
| // A PersistentHistogramAllocator is constructed from a PersistentMemory-
|
| // Allocator object of which it takes ownership.
|
| - PersistentHistogramAllocator(
|
| + explicit PersistentHistogramAllocator(
|
| std::unique_ptr<PersistentMemoryAllocator> memory);
|
| virtual ~PersistentHistogramAllocator();
|
|
|
| @@ -101,6 +247,14 @@ 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|. Only one |user| of this data is allowed at a time. This does
|
| + // an automatic Acquire() on the records. The user must call Release() on
|
| + // the returned object when it is finished with it. Ownership stays with
|
| + // this allocator.
|
| + PersistentSampleMapRecords* UseSampleMapRecords(uint64_t id,
|
| + const void* user);
|
| +
|
| // 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 +333,9 @@ class BASE_EXPORT PersistentHistogramAllocator {
|
| // The memory allocator that provides the actual histogram storage.
|
| std::unique_ptr<PersistentMemoryAllocator> memory_allocator_;
|
|
|
| + // The data-manager used to improve performance of sparse histograms.
|
| + PersistentSparseHistogramDataManager sparse_histogram_data_manager_;
|
| +
|
| // 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.
|
|
|