Chromium Code Reviews| 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_ |