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

Unified Diff: base/metrics/persistent_histogram_allocator.h

Issue 1840843004: Improve efficiency of persistent sparse histograms. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@improved-pma-iterator
Patch Set: added comment clarifying loop behavior Created 4 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 | « no previous file | base/metrics/persistent_histogram_allocator.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
« no previous file with comments | « no previous file | base/metrics/persistent_histogram_allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698