| Index: base/metrics/histogram_persistence.cc
|
| diff --git a/base/metrics/histogram_persistence.cc b/base/metrics/histogram_persistence.cc
|
| index bd250ec888a62a1998a4e762576b6bac388408b2..500dc7faa40ff0868e3ce0926327407964895519 100644
|
| --- a/base/metrics/histogram_persistence.cc
|
| +++ b/base/metrics/histogram_persistence.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "base/metrics/histogram_persistence.h"
|
|
|
| +#include "base/atomicops.h"
|
| #include "base/lazy_instance.h"
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| @@ -87,6 +88,11 @@ struct PersistentHistogramData {
|
| char name[1];
|
| };
|
|
|
| +// This is the offset of the last histogram that was created. It is used to
|
| +// avoid trying to import the same thing just to have it rejected because
|
| +// it already exists.
|
| +subtle::AtomicWord g_last_created_histogram = 0;
|
| +
|
| // The object held here will obviously not be destructed at process exit
|
| // but that's okay since PersistentMemoryAllocator objects are explicitly
|
| // forbidden from doing anything essential at exit anyway due to the fact
|
| @@ -225,6 +231,7 @@ ReleasePersistentHistogramMemoryAllocatorForTesting() {
|
| }
|
|
|
| g_allocator = nullptr;
|
| + subtle::NoBarrier_Store(&g_last_created_histogram, 0);
|
| return allocator;
|
| };
|
|
|
| @@ -470,6 +477,7 @@ HistogramBase* AllocatePersistentHistogram(
|
| DCHECK(histogram);
|
| if (ref_ptr != nullptr)
|
| *ref_ptr = histogram_ref;
|
| + subtle::NoBarrier_Store(&g_last_created_histogram, histogram_ref);
|
| return histogram;
|
| }
|
|
|
| @@ -503,11 +511,29 @@ void ImportPersistentHistograms() {
|
| if (iter.is_clear())
|
| g_allocator->CreateIterator(&iter);
|
|
|
| - while (true) {
|
| - HistogramBase* histogram = GetNextPersistentHistogram(g_allocator, &iter);
|
| - if (!histogram)
|
| - break;
|
| - StatisticsRecorder::RegisterOrDeleteDuplicate(histogram);
|
| + PersistentMemoryAllocator::Reference last_created =
|
| + subtle::NoBarrier_Load(&g_last_created_histogram);
|
| +
|
| + PersistentMemoryAllocator::Reference ref;
|
| + uint32_t type_id;
|
| + while ((ref = g_allocator->GetNextIterable(&iter, &type_id)) != 0) {
|
| + // Ignore any other type of objects in the allocator.
|
| + if (type_id != kTypeIdHistogram)
|
| + continue;
|
| +
|
| + // Skip the import if it's the histogram that was last created.
|
| + // Should a race condition cause the "last created" to be overwritten
|
| + // before it is recognized here then the histogram will be created
|
| + // and be ignored when it is detected as a duplicate by the
|
| + // statistics-recorder.
|
| + if (ref == last_created)
|
| + continue;
|
| +
|
| + // Create the histogram from contents in persistent memory and add it
|
| + // to the set of known ones.
|
| + HistogramBase* histogram = GetPersistentHistogram(g_allocator, ref);
|
| + if (histogram)
|
| + StatisticsRecorder::RegisterOrDeleteDuplicate(histogram);
|
| }
|
| }
|
| }
|
|
|