OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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_ |
OLD | NEW |