Index: base/metrics/persistent_histogram_allocator.h |
diff --git a/base/metrics/persistent_histogram_allocator.h b/base/metrics/persistent_histogram_allocator.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..60e61e6d829f04d6121b53da18af717e6f07c9df |
--- /dev/null |
+++ b/base/metrics/persistent_histogram_allocator.h |
@@ -0,0 +1,200 @@ |
+// Copyright (c) 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef BASE_METRICS_HISTOGRAM_PERSISTENCE_H_ |
+#define BASE_METRICS_HISTOGRAM_PERSISTENCE_H_ |
+ |
+#include "base/atomicops.h" |
+#include "base/base_export.h" |
+#include "base/feature_list.h" |
+#include "base/memory/scoped_ptr.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" |
+ |
+namespace base { |
+ |
+// Feature definition for enabling histogram persistence. |
+BASE_EXPORT extern const Feature kPersistentHistogramsFeature; |
+ |
+// This class manages histograms created within a PersistentMemoryAllocator. |
+class BASE_EXPORT PersistentHistogramAllocator { |
+ public: |
+ // This iterator is used for fetching persistent histograms from an allocator. |
+ class Iterator { |
+ public: |
+ bool is_clear() { return memory_iter.is_clear(); } |
+ |
+ private: |
+ friend class PersistentHistogramAllocator; |
+ |
+ // The iterator used for stepping through persistent memory iterables. |
+ PersistentMemoryAllocator::Iterator memory_iter; |
+ }; |
+ |
+ using Reference = PersistentMemoryAllocator::Reference; |
+ |
+ // A PersistentHistogramAllocator is constructed from a PersistentMemory- |
+ // Allocator object of which it takes ownership. |
+ PersistentHistogramAllocator(scoped_ptr<PersistentMemoryAllocator> memory); |
+ ~PersistentHistogramAllocator(); |
+ |
+ // Direct access to underlying memory allocator. If the segment is shared |
+ // across threads or processes, reading data through these values does |
+ // not guarantee consistency. Use with care. Do not write. |
+ uint64_t Id() const { return memory_allocator_->Id(); } |
+ const char* Name() const { return memory_allocator_->Name(); } |
+ const void* data() const { return memory_allocator_->data(); } |
+ size_t length() const { return memory_allocator_->length(); } |
+ size_t used() const { return memory_allocator_->used(); } |
Alexei Svitkine (slow)
2016/03/14 19:17:20
Nit: Move these below the memory_allocator() gette
bcwhite
2016/03/14 23:41:50
Done.
I implemented the others so that the "basic
|
+ PersistentMemoryAllocator* memory_allocator() { |
Alexei Svitkine (slow)
2016/03/14 19:17:20
Nit: Add a newline before this.
bcwhite
2016/03/14 23:41:50
Done.
|
+ return memory_allocator_.get(); |
+ } |
+ |
+ // Recreate a Histogram from data held in persistent memory. Though this |
+ // object will be local to the current process, the sample data will be |
+ // shared with all other threads referencing it. This method takes a |ref| |
+ // to where the top-level histogram data may be found in this allocator. |
+ // This method will return null if any problem is detected with the data. |
+ scoped_ptr<HistogramBase> GetHistogram(Reference ref); |
+ |
+ // Get the next histogram in persistent data based on iterator. |
+ scoped_ptr<HistogramBase> GetNextHistogram(Iterator* iter) { |
+ return GetNextHistogramWithIgnore(iter, 0); |
+ } |
+ |
+ // Create an iterator for going through all histograms in an allocator. |
+ void CreateIterator(Iterator* iter); |
Alexei Svitkine (slow)
2016/03/14 19:17:20
Why not return by value?
bcwhite
2016/03/14 23:41:50
This mimics the way iterators are done in the Pers
|
+ |
+ // Allocate a new persistent histogram. The returned histogram will not |
+ // be able to be located by other allocators until it is "finalized". |
+ scoped_ptr<HistogramBase> AllocateHistogram( |
+ HistogramType histogram_type, |
+ const std::string& name, |
+ int minimum, |
+ int maximum, |
+ const BucketRanges* bucket_ranges, |
+ int32_t flags, |
+ Reference* ref_ptr); |
+ |
+ // Finalize the creation of the histogram, making it available to other |
+ // processes if |register| is True, forgetting it otherwise. |
+ void FinalizeHistogram(Reference ref, bool register); |
+ |
+ // Create and update any internal histograms. |
Alexei Svitkine (slow)
2016/03/14 19:17:20
Document what "name" is and how it relates to hist
bcwhite
2016/03/14 23:41:50
Done.
|
+ void CreateTrackingHistograms(StringPiece name); |
+ void UpdateTrackingHistograms(); |
+ |
+ // Manage a PersistentHistogramAllocator for globally storing histograms in |
+ // a space that can be persisted or shared between processes. There is only |
+ // ever one allocator for all such histograms created by a single process. |
+ // This takes ownership of the object and should be called as soon as |
+ // possible during startup to capture as many histograms as possible and |
+ // while operating single-threaded so there are no race-conditions. |
+ static void SetGlobalAllocator( |
+ scoped_ptr<PersistentHistogramAllocator> allocator); |
+ static PersistentHistogramAllocator* GetGlobalAllocator(); |
+ |
+ // This access to the persistent allocator is only for testing; it extracts |
+ // the current allocator completely. This allows easy creation of histograms |
+ // within persistent memory segments which can then be extracted and used |
+ // in other ways. |
+ static scoped_ptr<PersistentHistogramAllocator> |
+ ReleaseGlobalAllocatorForTesting(); |
+ |
+ // These helper methods perform SetGlobalAllocator() calls with allocators |
+ // of the specified type and parameters. |
+ static void CreateGlobalAllocatorOnPersistentMemory( |
+ void* base, |
+ size_t size, |
+ size_t page_size, |
+ uint64_t id, |
+ StringPiece name); |
+ static void CreateGlobalAllocatorOnLocalMemory( |
+ size_t size, |
+ uint64_t id, |
+ StringPiece name); |
+ static void CreateGlobalAllocatorOnSharedMemory( |
+ size_t size, |
+ const SharedMemoryHandle& handle); |
+ |
+ // Import new histograms from the global PersistentHistogramAllocator. It's |
+ // possible for other processes to create histograms in the active memory |
+ // segment; this adds those to the internal list of known histograms to |
+ // avoid creating duplicates that would have to be merged during reporting. |
+ // Every call to this method resumes from the last entry it saw; it costs |
+ // nothing if nothing new has been added. |
+ static void ImportGlobalHistograms(); |
+ |
+ // Histogram containing creation results. Visible for testing. |
+ static HistogramBase* GetCreateHistogramResultHistogram(); |
+ |
+ private: |
+ // Enumerate possible creation results for reporting. |
+ enum CreateHistogramResultType { |
+ // Everything was fine. |
+ CREATE_HISTOGRAM_SUCCESS = 0, |
+ |
+ // Pointer to metadata was not valid. |
+ CREATE_HISTOGRAM_INVALID_METADATA_POINTER, |
+ |
+ // Histogram metadata was not valid. |
+ CREATE_HISTOGRAM_INVALID_METADATA, |
+ |
+ // Ranges information was not valid. |
+ CREATE_HISTOGRAM_INVALID_RANGES_ARRAY, |
+ |
+ // Counts information was not valid. |
+ CREATE_HISTOGRAM_INVALID_COUNTS_ARRAY, |
+ |
+ // Could not allocate histogram memory due to corruption. |
+ CREATE_HISTOGRAM_ALLOCATOR_CORRUPT, |
+ |
+ // Could not allocate histogram memory due to lack of space. |
+ CREATE_HISTOGRAM_ALLOCATOR_FULL, |
+ |
+ // Could not allocate histogram memory due to unknown error. |
+ CREATE_HISTOGRAM_ALLOCATOR_ERROR, |
+ |
+ // Histogram was of unknown type. |
+ CREATE_HISTOGRAM_UNKNOWN_TYPE, |
+ |
+ // Instance has detected a corrupt allocator (recorded only once). |
+ CREATE_HISTOGRAM_ALLOCATOR_NEWLY_CORRUPT, |
+ |
+ // Always keep this at the end. |
+ CREATE_HISTOGRAM_MAX |
+ }; |
+ |
+ // The structure used to hold histogram data in persistent memory. It is |
+ // defined and used entirely within the .cc file. |
+ struct PersistentHistogramData; |
+ |
+ // Get the next histogram in persistent data based on iterator while |
+ // ignoring a particular reference if it is found. |
+ scoped_ptr<HistogramBase> GetNextHistogramWithIgnore( |
+ Iterator* iter, |
+ Reference ignore); |
+ |
+ // Create a histogram based on saved (persistent) information about it. |
+ scoped_ptr<HistogramBase> CreateHistogram( |
+ PersistentHistogramData* histogram_data_ptr); |
+ |
+ // Record the result of a histogram creation. |
+ static void RecordCreateHistogramResult(CreateHistogramResultType result); |
+ |
+ // The memory allocator that provides the actual histogram storage. |
+ scoped_ptr<PersistentMemoryAllocator> memory_allocator_; |
+ |
+ // A reference to the last-created histogram in the allocator, used to avoid |
+ // trying to import what was just created. |
+ subtle::AtomicWord last_created_ = 0; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(PersistentHistogramAllocator); |
+}; |
+ |
+} // namespace base |
+ |
+#endif // BASE_METRICS_HISTOGRAM_PERSISTENCE_H_ |