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

Side by Side Diff: base/metrics/persistent_histogram_allocator.cc

Issue 1803253002: Improved iterator for persistent memory allocator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@refactor-hp
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 #include "base/metrics/persistent_histogram_allocator.h" 5 #include "base/metrics/persistent_histogram_allocator.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 PersistentMemoryAllocator::Reference counts_ref; 104 PersistentMemoryAllocator::Reference counts_ref;
105 HistogramSamples::Metadata samples_metadata; 105 HistogramSamples::Metadata samples_metadata;
106 HistogramSamples::Metadata logged_metadata; 106 HistogramSamples::Metadata logged_metadata;
107 107
108 // Space for the histogram name will be added during the actual allocation 108 // Space for the histogram name will be added during the actual allocation
109 // request. This must be the last field of the structure. A zero-size array 109 // request. This must be the last field of the structure. A zero-size array
110 // or a "flexible" array would be preferred but is not (yet) valid C++. 110 // or a "flexible" array would be preferred but is not (yet) valid C++.
111 char name[1]; 111 char name[1];
112 }; 112 };
113 113
114 PersistentHistogramAllocator::Iterator::Iterator(
115 PersistentHistogramAllocator* allocator)
116 : allocator_(allocator), memory_iter_(allocator->memory_allocator()) {}
117
118 std::unique_ptr<HistogramBase>
119 PersistentHistogramAllocator::Iterator::GetNextWithIgnore(Reference ignore) {
120 PersistentMemoryAllocator::Reference ref;
121 while ((ref = memory_iter_.GetNextOfType(kTypeIdHistogram)) != 0) {
122 if (ref != ignore)
123 return allocator_->GetHistogram(ref);
124 }
125 return nullptr;
126 }
127
114 PersistentHistogramAllocator::PersistentHistogramAllocator( 128 PersistentHistogramAllocator::PersistentHistogramAllocator(
115 std::unique_ptr<PersistentMemoryAllocator> memory) 129 std::unique_ptr<PersistentMemoryAllocator> memory)
116 : memory_allocator_(std::move(memory)) {} 130 : memory_allocator_(std::move(memory)) {}
117 131
118 PersistentHistogramAllocator::~PersistentHistogramAllocator() {} 132 PersistentHistogramAllocator::~PersistentHistogramAllocator() {}
119 133
120 void PersistentHistogramAllocator::CreateIterator(Iterator* iter) {
121 memory_allocator_->CreateIterator(&iter->memory_iter);
122 }
123
124 void PersistentHistogramAllocator::CreateTrackingHistograms(StringPiece name) { 134 void PersistentHistogramAllocator::CreateTrackingHistograms(StringPiece name) {
125 memory_allocator_->CreateTrackingHistograms(name); 135 memory_allocator_->CreateTrackingHistograms(name);
126 } 136 }
127 137
128 void PersistentHistogramAllocator::UpdateTrackingHistograms() { 138 void PersistentHistogramAllocator::UpdateTrackingHistograms() {
129 memory_allocator_->UpdateTrackingHistograms(); 139 memory_allocator_->UpdateTrackingHistograms();
130 } 140 }
131 141
132 // static 142 // static
133 HistogramBase* 143 HistogramBase*
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 size_t length = memory_allocator_->GetAllocSize(ref); 323 size_t length = memory_allocator_->GetAllocSize(ref);
314 if (!histogram_data || 324 if (!histogram_data ||
315 reinterpret_cast<char*>(histogram_data)[length - 1] != '\0') { 325 reinterpret_cast<char*>(histogram_data)[length - 1] != '\0') {
316 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA); 326 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA);
317 NOTREACHED(); 327 NOTREACHED();
318 return nullptr; 328 return nullptr;
319 } 329 }
320 return CreateHistogram(histogram_data); 330 return CreateHistogram(histogram_data);
321 } 331 }
322 332
323 std::unique_ptr<HistogramBase>
324 PersistentHistogramAllocator::GetNextHistogramWithIgnore(Iterator* iter,
325 Reference ignore) {
326 PersistentMemoryAllocator::Reference ref;
327 uint32_t type_id;
328 while ((ref = memory_allocator_->GetNextIterable(&iter->memory_iter,
329 &type_id)) != 0) {
330 if (ref == ignore)
331 continue;
332 if (type_id == kTypeIdHistogram)
333 return GetHistogram(ref);
334 }
335 return nullptr;
336 }
337
338 void PersistentHistogramAllocator::FinalizeHistogram(Reference ref, 333 void PersistentHistogramAllocator::FinalizeHistogram(Reference ref,
339 bool registered) { 334 bool registered) {
340 // If the created persistent histogram was registered then it needs to 335 // If the created persistent histogram was registered then it needs to
341 // be marked as "iterable" in order to be found by other processes. 336 // be marked as "iterable" in order to be found by other processes.
342 if (registered) 337 if (registered)
343 memory_allocator_->MakeIterable(ref); 338 memory_allocator_->MakeIterable(ref);
344 // If it wasn't registered then a race condition must have caused 339 // If it wasn't registered then a race condition must have caused
345 // two to be created. The allocator does not support releasing the 340 // two to be created. The allocator does not support releasing the
346 // acquired memory so just change the type to be empty. 341 // acquired memory so just change the type to be empty.
347 else 342 else
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 GlobalHistogramAllocator::ReleaseForTesting() { 531 GlobalHistogramAllocator::ReleaseForTesting() {
537 GlobalHistogramAllocator* histogram_allocator = g_allocator; 532 GlobalHistogramAllocator* histogram_allocator = g_allocator;
538 if (!histogram_allocator) 533 if (!histogram_allocator)
539 return nullptr; 534 return nullptr;
540 PersistentMemoryAllocator* memory_allocator = 535 PersistentMemoryAllocator* memory_allocator =
541 histogram_allocator->memory_allocator(); 536 histogram_allocator->memory_allocator();
542 537
543 // Before releasing the memory, it's necessary to have the Statistics- 538 // Before releasing the memory, it's necessary to have the Statistics-
544 // Recorder forget about the histograms contained therein; otherwise, 539 // Recorder forget about the histograms contained therein; otherwise,
545 // some operations will try to access them and the released memory. 540 // some operations will try to access them and the released memory.
546 PersistentMemoryAllocator::Iterator iter; 541 PersistentMemoryAllocator::Iterator iter(memory_allocator);
547 PersistentMemoryAllocator::Reference ref; 542 PersistentMemoryAllocator::Reference ref;
548 uint32_t type_id; 543 while ((ref = iter.GetNextOfType(kTypeIdHistogram)) != 0) {
549 memory_allocator->CreateIterator(&iter); 544 PersistentHistogramData* histogram_data =
550 while ((ref = memory_allocator->GetNextIterable(&iter, &type_id)) != 0) { 545 memory_allocator->GetAsObject<PersistentHistogramData>(
551 if (type_id == kTypeIdHistogram) { 546 ref, kTypeIdHistogram);
552 PersistentHistogramData* histogram_data = 547 DCHECK(histogram_data);
553 memory_allocator->GetAsObject<PersistentHistogramData>( 548 StatisticsRecorder::ForgetHistogramForTesting(histogram_data->name);
554 ref, kTypeIdHistogram);
555 DCHECK(histogram_data);
556 StatisticsRecorder::ForgetHistogramForTesting(histogram_data->name);
557 549
558 // If a test breaks here then a memory region containing a histogram 550 // If a test breaks here then a memory region containing a histogram
559 // actively used by this code is being released back to the test. 551 // actively used by this code is being released back to the test.
560 // If that memory segment were to be deleted, future calls to create 552 // If that memory segment were to be deleted, future calls to create
561 // persistent histograms would crash. To avoid this, have the test call 553 // persistent histograms would crash. To avoid this, have the test call
562 // the method GetCreateHistogramResultHistogram() *before* setting 554 // the method GetCreateHistogramResultHistogram() *before* setting
563 // the (temporary) memory allocator via SetGlobalAllocator() so that 555 // the (temporary) memory allocator via SetGlobalAllocator() so that
564 // histogram is instead allocated from the process heap. 556 // histogram is instead allocated from the process heap.
565 DCHECK_NE(kResultHistogram, histogram_data->name); 557 DCHECK_NE(kResultHistogram, histogram_data->name);
566 }
567 } 558 }
568 559
569 g_allocator = nullptr; 560 g_allocator = nullptr;
570 return WrapUnique(histogram_allocator); 561 return WrapUnique(histogram_allocator);
571 }; 562 };
572 563
573 GlobalHistogramAllocator::GlobalHistogramAllocator( 564 GlobalHistogramAllocator::GlobalHistogramAllocator(
574 std::unique_ptr<PersistentMemoryAllocator> memory) 565 std::unique_ptr<PersistentMemoryAllocator> memory)
575 : PersistentHistogramAllocator(std::move(memory)) { 566 : PersistentHistogramAllocator(std::move(memory)),
576 CreateIterator(&import_iterator_); 567 import_iterator_(this) {}
577 }
578 568
579 void GlobalHistogramAllocator::ImportHistogramsToStatisticsRecorder() { 569 void GlobalHistogramAllocator::ImportHistogramsToStatisticsRecorder() {
580 // Skip the import if it's the histogram that was last created. Should a 570 // Skip the import if it's the histogram that was last created. Should a
581 // race condition cause the "last created" to be overwritten before it 571 // race condition cause the "last created" to be overwritten before it
582 // is recognized here then the histogram will be created and be ignored 572 // is recognized here then the histogram will be created and be ignored
583 // when it is detected as a duplicate by the statistics-recorder. This 573 // when it is detected as a duplicate by the statistics-recorder. This
584 // simple check reduces the time of creating persistent histograms by 574 // simple check reduces the time of creating persistent histograms by
585 // about 40%. 575 // about 40%.
586 Reference record_to_ignore = last_created(); 576 Reference record_to_ignore = last_created();
587 577
588 // There is no lock on this because it's expected to be called only by 578 // There is no lock on this because it's expected to be called only by
589 // the StatisticsRecorder which has its own lock. 579 // the StatisticsRecorder which has its own lock.
590 while (true) { 580 while (true) {
591 std::unique_ptr<HistogramBase> histogram = 581 std::unique_ptr<HistogramBase> histogram =
592 GetNextHistogramWithIgnore(&import_iterator_, record_to_ignore); 582 import_iterator_.GetNextWithIgnore(record_to_ignore);
593 if (!histogram) 583 if (!histogram)
594 break; 584 break;
595 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); 585 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release());
596 } 586 }
597 } 587 }
598 588
599 } // namespace base 589 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/persistent_histogram_allocator.h ('k') | base/metrics/persistent_histogram_allocator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698