 Chromium Code Reviews
 Chromium Code Reviews Issue 1425533011:
  Support "shared" histograms between processes.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@shmem-alloc
    
  
    Issue 1425533011:
  Support "shared" histograms between processes.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@shmem-alloc| Index: components/metrics/metrics_service.h | 
| diff --git a/components/metrics/metrics_service.h b/components/metrics/metrics_service.h | 
| index 234508327238273a11989328dd18d1ef99b617f3..8d81484da9896ad8c643930db52730da2b8b3a1b 100644 | 
| --- a/components/metrics/metrics_service.h | 
| +++ b/components/metrics/metrics_service.h | 
| @@ -37,6 +37,7 @@ namespace base { | 
| class DictionaryValue; | 
| class HistogramSamples; | 
| class PrefService; | 
| +class SharedMemoryAllocator; | 
| } | 
| namespace variations { | 
| @@ -253,6 +254,16 @@ class MetricsService : public base::HistogramFlattener { | 
| // Pushes a log that has been generated by an external component. | 
| void PushExternalLog(const std::string& log); | 
| + // Add a persistent memory segment that contains histograms. Ownership | 
| + // of this object remains with the caller; it must be removed from here | 
| + // before being destroyed. | 
| + void AddPersistentMemorySegment(base::PersistentMemoryAllocator* alloc); | 
| + | 
| + // Remove a persistent memory segment. This should be done only after | 
| + // a final reporting has been done to avoid data loss and incorrect | 
| + // reporting. | 
| + void RemovePersistentMemorySegment(base::PersistentMemoryAllocator* alloc); | 
| + | 
| protected: | 
| // Exposed for testing. | 
| MetricsLogManager* log_manager() { return &log_manager_; } | 
| @@ -281,6 +292,56 @@ class MetricsService : public base::HistogramFlattener { | 
| UNSET | 
| }; | 
| + typedef std::set<base::PersistentMemoryAllocator*> AllocatorSet; | 
| + | 
| + // A class for iterating over the histograms in persistent memory segments. | 
| + class PersistentHistogramIterator { | 
| + // This class provides a reference-counted pointer to a histogram which | 
| + // is necessary for histogram objects that are dynamically generated | 
| + // (generally pointing to persistent memory) and to be owned by an STL | 
| + // iterator which, by necessity, must be copyable. | 
| + class HistogramPointer : public base::RefCounted<HistogramPointer> { | 
| + public: | 
| + HistogramPointer(base::HistogramBase* h) : histogram_(h) {} | 
| + base::HistogramBase* get() { return histogram_.get(); } | 
| + | 
| + private: | 
| + scoped_ptr<base::HistogramBase> histogram_; | 
| + }; | 
| + | 
| + public: | 
| + PersistentHistogramIterator(AllocatorSet& allocators, | 
| + AllocatorSet::iterator pos); | 
| + | 
| + PersistentHistogramIterator& operator++(); | 
| + PersistentHistogramIterator operator++(int) { | 
| + PersistentHistogramIterator tmp(*this); | 
| + operator++(); | 
| + return tmp; | 
| + } | 
| + | 
| + bool operator==(const PersistentHistogramIterator& rhs) const { | 
| + return allocator_iter_ == rhs.allocator_iter_ && | 
| + histogram_iter_ == rhs.histogram_iter_; | 
| + } | 
| + bool operator!=(const PersistentHistogramIterator& rhs) const { | 
| + return allocator_iter_ != rhs.allocator_iter_ || | 
| + histogram_iter_ != rhs.histogram_iter_; | 
| + } | 
| + base::HistogramBase* operator*() { | 
| + return current_histogram_->get(); | 
| + } | 
| 
Alexei Svitkine (slow)
2015/12/15 22:48:52
I think I mentioned this before, but my suggestion
 
bcwhite
2015/12/16 13:54:29
The code taking this iterator accepts standard STL
 
Alexei Svitkine (slow)
2015/12/16 16:33:48
Do we currently pass in other iterators? If indeed
 
bcwhite
2015/12/17 15:55:48
Yes.  The StatisticsRecorder provides an iterator,
 | 
| + | 
| + private: | 
| + AllocatorSet& allocators_; | 
| + AllocatorSet::iterator allocator_iter_; | 
| + base::PersistentMemoryAllocator::Iterator histogram_iter_; | 
| + | 
| + // STL iterators must be copyable so a regular scoped_ptr is not | 
| + // sufficient as it doesn't allow such. A ref-counted one is needed. | 
| + scoped_refptr<HistogramPointer> current_histogram_; | 
| + }; | 
| + | 
| typedef std::vector<SyntheticTrialGroup> SyntheticTrialGroups; | 
| // Calls into the client to initialize some system profile metrics. | 
| @@ -421,6 +482,10 @@ class MetricsService : public base::HistogramFlattener { | 
| // upload or intentional sampling of logs. | 
| void SkipAndDiscardUpload(); | 
| + // Begin and End iterators for going through all the metrics under management. | 
| + PersistentHistogramIterator persistent_begin(); | 
| + PersistentHistogramIterator persistent_end(); | 
| + | 
| // Manager for the various in-flight logs. | 
| MetricsLogManager log_manager_; | 
| @@ -502,6 +567,7 @@ class MetricsService : public base::HistogramFlattener { | 
| FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, | 
| PermutedEntropyCacheClearedWhenLowEntropyReset); | 
| FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, RegisterSyntheticTrial); | 
| + FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, MultiplePersistentAllocators); | 
| // Weak pointers factory used to post task on different threads. All weak | 
| // pointers managed by this factory have the same lifetime as MetricsService. | 
| @@ -511,6 +577,9 @@ class MetricsService : public base::HistogramFlattener { | 
| // this factory are invalidated in ScheduleNextStateSave. | 
| base::WeakPtrFactory<MetricsService> state_saver_factory_; | 
| + // Persistent memory segments that contain histograms created elsewhere. | 
| + AllocatorSet allocators_; | 
| + | 
| DISALLOW_COPY_AND_ASSIGN(MetricsService); | 
| }; |