| OLD | NEW |
| 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/atomicops.h" | 9 #include "base/atomicops.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 std::move(shm), 0, StringPiece(), /*readonly=*/false)))); | 816 std::move(shm), 0, StringPiece(), /*readonly=*/false)))); |
| 817 } | 817 } |
| 818 | 818 |
| 819 // static | 819 // static |
| 820 void GlobalHistogramAllocator::Set( | 820 void GlobalHistogramAllocator::Set( |
| 821 std::unique_ptr<GlobalHistogramAllocator> allocator) { | 821 std::unique_ptr<GlobalHistogramAllocator> allocator) { |
| 822 // Releasing or changing an allocator is extremely dangerous because it | 822 // Releasing or changing an allocator is extremely dangerous because it |
| 823 // likely has histograms stored within it. If the backing memory is also | 823 // likely has histograms stored within it. If the backing memory is also |
| 824 // also released, future accesses to those histograms will seg-fault. | 824 // also released, future accesses to those histograms will seg-fault. |
| 825 CHECK(!subtle::NoBarrier_Load(&g_allocator)); | 825 CHECK(!subtle::NoBarrier_Load(&g_allocator)); |
| 826 subtle::NoBarrier_Store(&g_allocator, | 826 subtle::Release_Store(&g_allocator, |
| 827 reinterpret_cast<uintptr_t>(allocator.release())); | 827 reinterpret_cast<uintptr_t>(allocator.release())); |
| 828 size_t existing = StatisticsRecorder::GetHistogramCount(); | 828 size_t existing = StatisticsRecorder::GetHistogramCount(); |
| 829 | 829 |
| 830 DVLOG_IF(1, existing) | 830 DVLOG_IF(1, existing) |
| 831 << existing << " histograms were created before persistence was enabled."; | 831 << existing << " histograms were created before persistence was enabled."; |
| 832 } | 832 } |
| 833 | 833 |
| 834 // static | 834 // static |
| 835 GlobalHistogramAllocator* GlobalHistogramAllocator::Get() { | 835 GlobalHistogramAllocator* GlobalHistogramAllocator::Get() { |
| 836 return reinterpret_cast<GlobalHistogramAllocator*>( | 836 return reinterpret_cast<GlobalHistogramAllocator*>( |
| 837 subtle::NoBarrier_Load(&g_allocator)); | 837 subtle::Acquire_Load(&g_allocator)); |
| 838 } | 838 } |
| 839 | 839 |
| 840 // static | 840 // static |
| 841 std::unique_ptr<GlobalHistogramAllocator> | 841 std::unique_ptr<GlobalHistogramAllocator> |
| 842 GlobalHistogramAllocator::ReleaseForTesting() { | 842 GlobalHistogramAllocator::ReleaseForTesting() { |
| 843 GlobalHistogramAllocator* histogram_allocator = Get(); | 843 GlobalHistogramAllocator* histogram_allocator = Get(); |
| 844 if (!histogram_allocator) | 844 if (!histogram_allocator) |
| 845 return nullptr; | 845 return nullptr; |
| 846 PersistentMemoryAllocator* memory_allocator = | 846 PersistentMemoryAllocator* memory_allocator = |
| 847 histogram_allocator->memory_allocator(); | 847 histogram_allocator->memory_allocator(); |
| 848 | 848 |
| 849 // Before releasing the memory, it's necessary to have the Statistics- | 849 // Before releasing the memory, it's necessary to have the Statistics- |
| 850 // Recorder forget about the histograms contained therein; otherwise, | 850 // Recorder forget about the histograms contained therein; otherwise, |
| 851 // some operations will try to access them and the released memory. | 851 // some operations will try to access them and the released memory. |
| 852 PersistentMemoryAllocator::Iterator iter(memory_allocator); | 852 PersistentMemoryAllocator::Iterator iter(memory_allocator); |
| 853 const PersistentHistogramData* data; | 853 const PersistentHistogramData* data; |
| 854 while ((data = iter.GetNextOfObject<PersistentHistogramData>()) != nullptr) { | 854 while ((data = iter.GetNextOfObject<PersistentHistogramData>()) != nullptr) { |
| 855 StatisticsRecorder::ForgetHistogramForTesting(data->name); | 855 StatisticsRecorder::ForgetHistogramForTesting(data->name); |
| 856 | 856 |
| 857 // If a test breaks here then a memory region containing a histogram | 857 // If a test breaks here then a memory region containing a histogram |
| 858 // actively used by this code is being released back to the test. | 858 // actively used by this code is being released back to the test. |
| 859 // If that memory segment were to be deleted, future calls to create | 859 // If that memory segment were to be deleted, future calls to create |
| 860 // persistent histograms would crash. To avoid this, have the test call | 860 // persistent histograms would crash. To avoid this, have the test call |
| 861 // the method GetCreateHistogramResultHistogram() *before* setting | 861 // the method GetCreateHistogramResultHistogram() *before* setting |
| 862 // the (temporary) memory allocator via SetGlobalAllocator() so that | 862 // the (temporary) memory allocator via SetGlobalAllocator() so that |
| 863 // histogram is instead allocated from the process heap. | 863 // histogram is instead allocated from the process heap. |
| 864 DCHECK_NE(kResultHistogram, data->name); | 864 DCHECK_NE(kResultHistogram, data->name); |
| 865 } | 865 } |
| 866 | 866 |
| 867 subtle::NoBarrier_Store(&g_allocator, 0); | 867 subtle::Release_Store(&g_allocator, 0); |
| 868 return WrapUnique(histogram_allocator); | 868 return WrapUnique(histogram_allocator); |
| 869 }; | 869 }; |
| 870 | 870 |
| 871 void GlobalHistogramAllocator::SetPersistentLocation(const FilePath& location) { | 871 void GlobalHistogramAllocator::SetPersistentLocation(const FilePath& location) { |
| 872 persistent_location_ = location; | 872 persistent_location_ = location; |
| 873 } | 873 } |
| 874 | 874 |
| 875 const FilePath& GlobalHistogramAllocator::GetPersistentLocation() const { | 875 const FilePath& GlobalHistogramAllocator::GetPersistentLocation() const { |
| 876 return persistent_location_; | 876 return persistent_location_; |
| 877 } | 877 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 941 while (true) { | 941 while (true) { |
| 942 std::unique_ptr<HistogramBase> histogram = | 942 std::unique_ptr<HistogramBase> histogram = |
| 943 import_iterator_.GetNextWithIgnore(record_to_ignore); | 943 import_iterator_.GetNextWithIgnore(record_to_ignore); |
| 944 if (!histogram) | 944 if (!histogram) |
| 945 break; | 945 break; |
| 946 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); | 946 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); |
| 947 } | 947 } |
| 948 } | 948 } |
| 949 | 949 |
| 950 } // namespace base | 950 } // namespace base |
| OLD | NEW |