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

Side by Side 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: rebased 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_METRICS_HISTOGRAM_PERSISTENCE_H_ 5 #ifndef BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
6 #define BASE_METRICS_HISTOGRAM_PERSISTENCE_H_ 6 #define BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
7 7
8 #include <memory> 8 #include <memory>
9 9
10 #include "base/atomicops.h" 10 #include "base/atomicops.h"
11 #include "base/base_export.h" 11 #include "base/base_export.h"
12 #include "base/feature_list.h" 12 #include "base/feature_list.h"
13 #include "base/id_map.h"
13 #include "base/memory/shared_memory.h" 14 #include "base/memory/shared_memory.h"
14 #include "base/metrics/histogram_base.h" 15 #include "base/metrics/histogram_base.h"
15 #include "base/metrics/persistent_memory_allocator.h" 16 #include "base/metrics/persistent_memory_allocator.h"
16 #include "base/strings/string_piece.h" 17 #include "base/strings/string_piece.h"
18 #include "base/synchronization/lock.h"
17 19
18 namespace base { 20 namespace base {
19 21
22 class PersistentSampleMapRecords;
23 class PersistentSparseHistogramHelper;
24
20 // Feature definition for enabling histogram persistence. 25 // Feature definition for enabling histogram persistence.
21 BASE_EXPORT extern const Feature kPersistentHistogramsFeature; 26 BASE_EXPORT extern const Feature kPersistentHistogramsFeature;
22 27
23 // This class manages histograms created within a PersistentMemoryAllocator. 28 // This class manages histograms created within a PersistentMemoryAllocator.
24 class BASE_EXPORT PersistentHistogramAllocator { 29 class BASE_EXPORT PersistentHistogramAllocator {
25 public: 30 public:
26 // A reference to a histogram. While this is implemented as PMA::Reference, 31 // A reference to a histogram. While this is implemented as PMA::Reference,
27 // it is not conceptually the same thing. Outside callers should always use 32 // it is not conceptually the same thing. Outside callers should always use
28 // a Reference matching the class it is for and not mix the two. 33 // a Reference matching the class it is for and not mix the two.
29 using Reference = PersistentMemoryAllocator::Reference; 34 using Reference = PersistentMemoryAllocator::Reference;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 int maximum, 99 int maximum,
95 const BucketRanges* bucket_ranges, 100 const BucketRanges* bucket_ranges,
96 int32_t flags, 101 int32_t flags,
97 Reference* ref_ptr); 102 Reference* ref_ptr);
98 103
99 // Finalize the creation of the histogram, making it available to other 104 // Finalize the creation of the histogram, making it available to other
100 // processes if |registered| (as in: added to the StatisticsRecorder) is 105 // processes if |registered| (as in: added to the StatisticsRecorder) is
101 // True, forgetting it otherwise. 106 // True, forgetting it otherwise.
102 void FinalizeHistogram(Reference ref, bool registered); 107 void FinalizeHistogram(Reference ref, bool registered);
103 108
109 // Returns the object that manages the persistent-sample-map records for a
110 // given |id|. There is only one such object per-allocator-per-id on the
111 // assumption that there is only ever one histogram object at a time that
112 // would use a particular set of records. Ownership stays with this allocator.
113 PersistentSampleMapRecords* GetSampleMapRecords(uint64_t id);
114
104 // Create internal histograms for tracking memory use and allocation sizes 115 // Create internal histograms for tracking memory use and allocation sizes
105 // for allocator of |name| (which can simply be the result of Name()). This 116 // for allocator of |name| (which can simply be the result of Name()). This
106 // is done seperately from construction for situations such as when the 117 // is done seperately from construction for situations such as when the
107 // histograms will be backed by memory provided by this very allocator. 118 // histograms will be backed by memory provided by this very allocator.
108 // 119 //
109 // IMPORTANT: Callers must update tools/metrics/histograms/histograms.xml 120 // IMPORTANT: Callers must update tools/metrics/histograms/histograms.xml
110 // with the following histograms: 121 // with the following histograms:
111 // UMA.PersistentAllocator.name.Allocs 122 // UMA.PersistentAllocator.name.Allocs
112 // UMA.PersistentAllocator.name.UsedPct 123 // UMA.PersistentAllocator.name.UsedPct
113 void CreateTrackingHistograms(StringPiece name); 124 void CreateTrackingHistograms(StringPiece name);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 // Create a histogram based on saved (persistent) information about it. 183 // Create a histogram based on saved (persistent) information about it.
173 std::unique_ptr<HistogramBase> CreateHistogram( 184 std::unique_ptr<HistogramBase> CreateHistogram(
174 PersistentHistogramData* histogram_data_ptr); 185 PersistentHistogramData* histogram_data_ptr);
175 186
176 // Record the result of a histogram creation. 187 // Record the result of a histogram creation.
177 static void RecordCreateHistogramResult(CreateHistogramResultType result); 188 static void RecordCreateHistogramResult(CreateHistogramResultType result);
178 189
179 // The memory allocator that provides the actual histogram storage. 190 // The memory allocator that provides the actual histogram storage.
180 std::unique_ptr<PersistentMemoryAllocator> memory_allocator_; 191 std::unique_ptr<PersistentMemoryAllocator> memory_allocator_;
181 192
193 // The helper used to improve performance of sparse histograms.
194 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
195
182 // A reference to the last-created histogram in the allocator, used to avoid 196 // A reference to the last-created histogram in the allocator, used to avoid
183 // trying to import what was just created. 197 // trying to import what was just created.
184 // TODO(bcwhite): Change this to std::atomic<PMA::Reference> when available. 198 // TODO(bcwhite): Change this to std::atomic<PMA::Reference> when available.
185 subtle::Atomic32 last_created_ = 0; 199 subtle::Atomic32 last_created_ = 0;
186 200
187 DISALLOW_COPY_AND_ASSIGN(PersistentHistogramAllocator); 201 DISALLOW_COPY_AND_ASSIGN(PersistentHistogramAllocator);
188 }; 202 };
189 203
190 204
191 // A special case of the PersistentHistogramAllocator that operates on a 205 // A special case of the PersistentHistogramAllocator that operates on a
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 // nothing new has been added. 269 // nothing new has been added.
256 void ImportHistogramsToStatisticsRecorder(); 270 void ImportHistogramsToStatisticsRecorder();
257 271
258 // Import always continues from where it left off, making use of a single 272 // Import always continues from where it left off, making use of a single
259 // iterator to continue the work. 273 // iterator to continue the work.
260 Iterator import_iterator_; 274 Iterator import_iterator_;
261 275
262 DISALLOW_COPY_AND_ASSIGN(GlobalHistogramAllocator); 276 DISALLOW_COPY_AND_ASSIGN(GlobalHistogramAllocator);
263 }; 277 };
264 278
279
280 // A helper-class for sparse histograms so each instance of such doesn't have
281 // to separately iterate over the entire memory segment. Though this class
282 // will generally be accessed through the PersistentHistogramAllocator above,
283 // it can be used independently on any PersistentMemoryAllocator (making it
284 // useable for testing). This object supports only one instance of a sparse
285 // histogram for a given id. Tests that create multiple identical histograms,
286 // perhaps to simulate multiple processes, should create a separate helper
287 // for each.
288 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.
289 public:
290 // Constructs the helper. The allocator must live longer than any helpers
291 // that reference it.
292 PersistentSparseHistogramHelper(PersistentMemoryAllocator* allocator);
Alexei Svitkine (slow) 2016/04/13 15:53:50 Nit: explicit
bcwhite 2016/04/13 22:45:03 Done.
293
294 ~PersistentSparseHistogramHelper();
295
296 // Returns the object that manages the persistent-sample-map records for a
297 // given |id|. There is only one such object per-allocator-per-id on the
298 // assumption that there is only ever one histogram object at a time that
299 // would use a particular set of records. Ownership stays with this helper.
300 PersistentSampleMapRecords* GetSampleMapRecords(uint64_t id);
301
302 // Convenience method that gets the object for a given reference so callers
303 // don't have to also keep their own pointer to the appropriate allocator.
304 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.
305 T* GetAsObject(PersistentMemoryAllocator::Reference ref, uint32_t type_id) {
306 return allocator_->GetAsObject<T>(ref, type_id);
307 }
308
309 private:
310 friend class PersistentSampleMapRecords;
311
312 // Like GetSampleMapRecords() above but operates when the |lock_| has
313 // already been acquired.
314 PersistentSampleMapRecords* GetSampleMapRecordsWhileLocked(uint64_t id);
315
316 // Loads sample-map records looking for those belonging to the specified
317 // |load_id|. Records found for other sample-maps are held for later use
318 // without having to iterate again. This should only be called when the
319 // |lock_| has been acquired.
320 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
321
322 // Weak-pointer to the allocator used by the sparse histograms.
323 PersistentMemoryAllocator* allocator_;
324
325 // Iterator within the allocator for finding sample records.
326 PersistentMemoryAllocator::Iterator record_iterator_;
327
328 // Mapping of sample-map IDs to their sample records.
329 IDMap<PersistentSampleMapRecords, IDMapOwnPointer, uint64_t> sample_records_;
330
331 // A lock used for synchronizing changes to sample_records_.
332 base::Lock lock_;
333
334 DISALLOW_COPY_AND_ASSIGN(PersistentSparseHistogramHelper);
335 };
336
337
338 // This class manages sample-records used by the PersistentSampleMap containers
339 // 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.
340 // top-level class so that it can be forward-declared in other header files
341 // rather than include this entire file as would be necessary if it were
342 // declared within the PersistentSparseHistogramHelper class above.
343 class BASE_EXPORT PersistentSampleMapRecords {
344 public:
345 // Constructs an instance of this class. The helper object must live longer
346 // than all instances of this class that reference it, which is not usually
347 // a problem since these objects are generally managed from within that
348 // helper instance.
349 PersistentSampleMapRecords(PersistentSparseHistogramHelper* helper,
350 uint64_t sample_map_id);
351
352 ~PersistentSampleMapRecords();
353
354 // Resets the internal state of seen/unseen records for its sample-map.
355 // This should be done when creating a PersistentSampleMap so it does not
356 // mistakenly resume from where a previous instance left off. Multiple,
357 // sequential instances of such are common when reading histograms of
358 // another process for periodic reporting to UMA.
359 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.
360
361 // Gets the next reference to a persistent sample-map record. The type and
362 // layout of the data being referenced is defined entirely within the
363 // PersistentSampleMap class.
364 PersistentMemoryAllocator::Reference GetNext();
365
366 // Creates a new persistent sample-map record for sample |value| and returns
367 // a reference to it.
368 PersistentMemoryAllocator::Reference CreateNew(HistogramBase::Sample value);
369
370 // Convenience method that gets the object for a given reference so callers
371 // don't have to also keep their own pointer to the appropriate allocator.
372 template <typename T>
373 T* GetAsObject(PersistentMemoryAllocator::Reference ref, uint32_t type_id) {
374 return helper_->GetAsObject<T>(ref, type_id);
375 }
376
377 private:
378 friend PersistentSparseHistogramHelper;
379
380 // Weak-pointer to the parent helper object.
381 PersistentSparseHistogramHelper* helper_;
382
383 // ID of PersistentSampleMap to which these records apply.
384 uint64_t sample_map_id_;
Alexei Svitkine (slow) 2016/04/13 15:53:50 Nit: const?
bcwhite 2016/04/13 22:45:04 Done.
385
386 // This is the count of how many "records" have already been read by the
387 // owning sample-map.
388 size_t seen_;
389
390 // This is the set of records previously found for a sample map. Because
391 // there is ever only one object with a given ID (typically a hash of a
392 // histogram name) and because the parent SparseHistogram has acquired
393 // its own lock before accessing the PersistentSampleMap it controls, this
394 // list can be accessed without acquiring any additional lock.
395 std::vector<PersistentMemoryAllocator::Reference> records_;
396
397 // This is the set of records found during iteration through memory. It
398 // is appended in bulk to "records". Access to this vector can be done
399 // only while holding the parent helper's lock.
400 std::vector<PersistentMemoryAllocator::Reference> found_;
401
402 DISALLOW_COPY_AND_ASSIGN(PersistentSampleMapRecords);
403 };
404
265 } // namespace base 405 } // namespace base
266 406
267 #endif // BASE_METRICS_HISTOGRAM_PERSISTENCE_H_ 407 #endif // BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
OLDNEW
« no previous file with comments | « no previous file | base/metrics/persistent_histogram_allocator.cc » ('j') | base/metrics/persistent_histogram_allocator.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698