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

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

Issue 1731453002: Reduce histogram creation time by avoiding import of those just created. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: clear last-histogram when releasing allocator Created 4 years, 10 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
« no previous file with comments | « no previous file | base/metrics/histogram_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 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/histogram_persistence.h" 5 #include "base/metrics/histogram_persistence.h"
6 6
7 #include "base/atomicops.h"
7 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
8 #include "base/logging.h" 9 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
10 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
11 #include "base/metrics/histogram_base.h" 12 #include "base/metrics/histogram_base.h"
12 #include "base/metrics/histogram_samples.h" 13 #include "base/metrics/histogram_samples.h"
13 #include "base/metrics/statistics_recorder.h" 14 #include "base/metrics/statistics_recorder.h"
14 #include "base/synchronization/lock.h" 15 #include "base/synchronization/lock.h"
15 16
16 namespace base { 17 namespace base {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 PersistentMemoryAllocator::Reference counts_ref; 81 PersistentMemoryAllocator::Reference counts_ref;
81 HistogramSamples::Metadata samples_metadata; 82 HistogramSamples::Metadata samples_metadata;
82 HistogramSamples::Metadata logged_metadata; 83 HistogramSamples::Metadata logged_metadata;
83 84
84 // Space for the histogram name will be added during the actual allocation 85 // Space for the histogram name will be added during the actual allocation
85 // request. This must be the last field of the structure. A zero-size array 86 // request. This must be the last field of the structure. A zero-size array
86 // or a "flexible" array would be preferred but is not (yet) valid C++. 87 // or a "flexible" array would be preferred but is not (yet) valid C++.
87 char name[1]; 88 char name[1];
88 }; 89 };
89 90
91 // This is the offset of the last histogram that was created. It is used to
92 // avoid trying to import the same thing just to have it rejected because
93 // it already exists.
94 subtle::AtomicWord g_last_created_histogram = 0;
95
90 // The object held here will obviously not be destructed at process exit 96 // The object held here will obviously not be destructed at process exit
91 // but that's okay since PersistentMemoryAllocator objects are explicitly 97 // but that's okay since PersistentMemoryAllocator objects are explicitly
92 // forbidden from doing anything essential at exit anyway due to the fact 98 // forbidden from doing anything essential at exit anyway due to the fact
93 // that they depend on data managed elsewhere and which could be destructed 99 // that they depend on data managed elsewhere and which could be destructed
94 // first. 100 // first.
95 PersistentMemoryAllocator* g_allocator = nullptr; 101 PersistentMemoryAllocator* g_allocator = nullptr;
96 102
97 // Take an array of range boundaries and create a proper BucketRanges object 103 // Take an array of range boundaries and create a proper BucketRanges object
98 // which is returned to the caller. A return of nullptr indicates that the 104 // which is returned to the caller. A return of nullptr indicates that the
99 // passed boundaries are invalid. 105 // passed boundaries are invalid.
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 // If that memory segment were to be deleted, future calls to create 224 // If that memory segment were to be deleted, future calls to create
219 // persistent histograms would crash. To avoid this, have the test call 225 // persistent histograms would crash. To avoid this, have the test call
220 // the method GetCreateHistogramResultHistogram() *before* setting the 226 // the method GetCreateHistogramResultHistogram() *before* setting the
221 // (temporary) memory allocator via SetPersistentMemoryAllocator() so 227 // (temporary) memory allocator via SetPersistentMemoryAllocator() so
222 // that the histogram is instead allocated from the process heap. 228 // that the histogram is instead allocated from the process heap.
223 DCHECK_NE(kResultHistogram, histogram_data->name); 229 DCHECK_NE(kResultHistogram, histogram_data->name);
224 } 230 }
225 } 231 }
226 232
227 g_allocator = nullptr; 233 g_allocator = nullptr;
234 subtle::NoBarrier_Store(&g_last_created_histogram, 0);
228 return allocator; 235 return allocator;
229 }; 236 };
230 237
231 HistogramBase* CreatePersistentHistogram( 238 HistogramBase* CreatePersistentHistogram(
232 PersistentMemoryAllocator* allocator, 239 PersistentMemoryAllocator* allocator,
233 PersistentHistogramData* histogram_data_ptr) { 240 PersistentHistogramData* histogram_data_ptr) {
234 if (!histogram_data_ptr) { 241 if (!histogram_data_ptr) {
235 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA_POINTER); 242 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA_POINTER);
236 NOTREACHED(); 243 NOTREACHED();
237 return nullptr; 244 return nullptr;
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 // Create the histogram using resources in persistent memory. This ends up 470 // Create the histogram using resources in persistent memory. This ends up
464 // resolving the "ref" values stored in histogram_data instad of just 471 // resolving the "ref" values stored in histogram_data instad of just
465 // using what is already known above but avoids duplicating the switch 472 // using what is already known above but avoids duplicating the switch
466 // statement here and serves as a double-check that everything is 473 // statement here and serves as a double-check that everything is
467 // correct before commiting the new histogram to persistent space. 474 // correct before commiting the new histogram to persistent space.
468 HistogramBase* histogram = 475 HistogramBase* histogram =
469 CreatePersistentHistogram(allocator, histogram_data); 476 CreatePersistentHistogram(allocator, histogram_data);
470 DCHECK(histogram); 477 DCHECK(histogram);
471 if (ref_ptr != nullptr) 478 if (ref_ptr != nullptr)
472 *ref_ptr = histogram_ref; 479 *ref_ptr = histogram_ref;
480 subtle::NoBarrier_Store(&g_last_created_histogram, histogram_ref);
473 return histogram; 481 return histogram;
474 } 482 }
475 483
476 CreateHistogramResultType result; 484 CreateHistogramResultType result;
477 if (allocator->IsCorrupt()) { 485 if (allocator->IsCorrupt()) {
478 RecordCreateHistogramResult(CREATE_HISTOGRAM_ALLOCATOR_NEWLY_CORRUPT); 486 RecordCreateHistogramResult(CREATE_HISTOGRAM_ALLOCATOR_NEWLY_CORRUPT);
479 result = CREATE_HISTOGRAM_ALLOCATOR_CORRUPT; 487 result = CREATE_HISTOGRAM_ALLOCATOR_CORRUPT;
480 } else if (allocator->IsFull()) { 488 } else if (allocator->IsFull()) {
481 result = CREATE_HISTOGRAM_ALLOCATOR_FULL; 489 result = CREATE_HISTOGRAM_ALLOCATOR_FULL;
482 } else { 490 } else {
(...skipping 13 matching lines...) Expand all
496 if (g_allocator) { 504 if (g_allocator) {
497 base::AutoLock auto_lock(lock.Get()); 505 base::AutoLock auto_lock(lock.Get());
498 506
499 // Each call resumes from where it last left off so need persistant 507 // Each call resumes from where it last left off so need persistant
500 // iterator. This class has a constructor so even the definition has 508 // iterator. This class has a constructor so even the definition has
501 // to be protected by the lock in order to be thread-safe. 509 // to be protected by the lock in order to be thread-safe.
502 static PersistentMemoryAllocator::Iterator iter; 510 static PersistentMemoryAllocator::Iterator iter;
503 if (iter.is_clear()) 511 if (iter.is_clear())
504 g_allocator->CreateIterator(&iter); 512 g_allocator->CreateIterator(&iter);
505 513
506 while (true) { 514 PersistentMemoryAllocator::Reference last_created =
507 HistogramBase* histogram = GetNextPersistentHistogram(g_allocator, &iter); 515 subtle::NoBarrier_Load(&g_last_created_histogram);
508 if (!histogram) 516
509 break; 517 PersistentMemoryAllocator::Reference ref;
510 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram); 518 uint32_t type_id;
519 while ((ref = g_allocator->GetNextIterable(&iter, &type_id)) != 0) {
520 // Ignore any other type of objects in the allocator.
521 if (type_id != kTypeIdHistogram)
522 continue;
523
524 // Skip the import if it's the histogram that was last created.
525 // Should a race condition cause the "last created" to be overwritten
526 // before it is recognized here then the histogram will be created
527 // and be ignored when it is detected as a duplicate by the
528 // statistics-recorder.
529 if (ref == last_created)
530 continue;
531
532 // Create the histogram from contents in persistent memory and add it
533 // to the set of known ones.
534 HistogramBase* histogram = GetPersistentHistogram(g_allocator, ref);
535 if (histogram)
536 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram);
511 } 537 }
512 } 538 }
513 } 539 }
514 540
515 } // namespace base 541 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | base/metrics/histogram_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698