| 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/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 void GlobalHistogramAllocator::CreateWithLocalMemory( | 679 void GlobalHistogramAllocator::CreateWithLocalMemory( |
| 680 size_t size, | 680 size_t size, |
| 681 uint64_t id, | 681 uint64_t id, |
| 682 StringPiece name) { | 682 StringPiece name) { |
| 683 Set(WrapUnique(new GlobalHistogramAllocator( | 683 Set(WrapUnique(new GlobalHistogramAllocator( |
| 684 MakeUnique<LocalPersistentMemoryAllocator>(size, id, name)))); | 684 MakeUnique<LocalPersistentMemoryAllocator>(size, id, name)))); |
| 685 } | 685 } |
| 686 | 686 |
| 687 #if !defined(OS_NACL) | 687 #if !defined(OS_NACL) |
| 688 // static | 688 // static |
| 689 void GlobalHistogramAllocator::CreateWithFile( | 689 bool GlobalHistogramAllocator::CreateWithFile( |
| 690 const FilePath& file_path, | 690 const FilePath& file_path, |
| 691 size_t size, | 691 size_t size, |
| 692 uint64_t id, | 692 uint64_t id, |
| 693 StringPiece name) { | 693 StringPiece name) { |
| 694 bool exists = PathExists(file_path); | 694 bool exists = PathExists(file_path); |
| 695 File file( | 695 File file( |
| 696 file_path, File::FLAG_OPEN_ALWAYS | File::FLAG_SHARE_DELETE | | 696 file_path, File::FLAG_OPEN_ALWAYS | File::FLAG_SHARE_DELETE | |
| 697 File::FLAG_READ | File::FLAG_WRITE); | 697 File::FLAG_READ | File::FLAG_WRITE); |
| 698 | 698 |
| 699 std::unique_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile()); | 699 std::unique_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile()); |
| 700 if (exists) { | 700 if (exists) { |
| 701 mmfile->Initialize(std::move(file), MemoryMappedFile::READ_WRITE); | 701 mmfile->Initialize(std::move(file), MemoryMappedFile::READ_WRITE); |
| 702 } else { | 702 } else { |
| 703 mmfile->Initialize(std::move(file), {0, static_cast<int64_t>(size)}, | 703 mmfile->Initialize(std::move(file), {0, static_cast<int64_t>(size)}, |
| 704 MemoryMappedFile::READ_WRITE_EXTEND); | 704 MemoryMappedFile::READ_WRITE_EXTEND); |
| 705 } | 705 } |
| 706 if (!mmfile->IsValid() || | 706 if (!mmfile->IsValid() || |
| 707 !FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, true)) { | 707 !FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, true)) { |
| 708 NOTREACHED(); | 708 NOTREACHED(); |
| 709 return; | 709 return false; |
| 710 } | 710 } |
| 711 | 711 |
| 712 Set(WrapUnique( | 712 Set(WrapUnique( |
| 713 new GlobalHistogramAllocator(MakeUnique<FilePersistentMemoryAllocator>( | 713 new GlobalHistogramAllocator(MakeUnique<FilePersistentMemoryAllocator>( |
| 714 std::move(mmfile), size, id, name, false)))); | 714 std::move(mmfile), size, id, name, false)))); |
| 715 Get()->SetPersistentLocation(file_path); |
| 716 return true; |
| 715 } | 717 } |
| 716 #endif | 718 |
| 719 // static |
| 720 bool GlobalHistogramAllocator::CreateWithActiveFile(const FilePath& base_path, |
| 721 const FilePath& active_path, |
| 722 size_t size, |
| 723 uint64_t id, |
| 724 StringPiece name) { |
| 725 if (!base::ReplaceFile(active_path, base_path, nullptr)) |
| 726 base::DeleteFile(base_path, /*recursive=*/false); |
| 727 |
| 728 return base::GlobalHistogramAllocator::CreateWithFile(active_path, size, id, |
| 729 name); |
| 730 } |
| 731 |
| 732 // static |
| 733 bool GlobalHistogramAllocator::CreateWithActiveFileInDir(const FilePath& dir, |
| 734 size_t size, |
| 735 uint64_t id, |
| 736 StringPiece name) { |
| 737 FilePath base_path, active_path; |
| 738 ConstructFilePaths(dir, name, &base_path, &active_path); |
| 739 return CreateWithActiveFile(base_path, active_path, size, id, name); |
| 740 } |
| 741 |
| 742 // static |
| 743 void GlobalHistogramAllocator::ConstructFilePaths(const FilePath& dir, |
| 744 StringPiece name, |
| 745 FilePath* out_base_path, |
| 746 FilePath* out_active_path) { |
| 747 if (out_base_path) { |
| 748 *out_base_path = dir.AppendASCII(name).AddExtension( |
| 749 PersistentMemoryAllocator::kFileExtension); |
| 750 } |
| 751 if (out_active_path) { |
| 752 *out_active_path = |
| 753 dir.AppendASCII(name.as_string() + std::string("-active")) |
| 754 .AddExtension(PersistentMemoryAllocator::kFileExtension); |
| 755 } |
| 756 } |
| 757 #endif // !defined(OS_NACL) |
| 717 | 758 |
| 718 // static | 759 // static |
| 719 void GlobalHistogramAllocator::CreateWithSharedMemory( | 760 void GlobalHistogramAllocator::CreateWithSharedMemory( |
| 720 std::unique_ptr<SharedMemory> memory, | 761 std::unique_ptr<SharedMemory> memory, |
| 721 size_t size, | 762 size_t size, |
| 722 uint64_t id, | 763 uint64_t id, |
| 723 StringPiece name) { | 764 StringPiece name) { |
| 724 if ((!memory->memory() && !memory->Map(size)) || | 765 if ((!memory->memory() && !memory->Map(size)) || |
| 725 !SharedPersistentMemoryAllocator::IsSharedMemoryAcceptable(*memory)) { | 766 !SharedPersistentMemoryAllocator::IsSharedMemoryAcceptable(*memory)) { |
| 726 NOTREACHED(); | 767 NOTREACHED(); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 contents)) { | 871 contents)) { |
| 831 LOG(ERROR) << "Could not write \"" << Name() << "\" persistent histograms" | 872 LOG(ERROR) << "Could not write \"" << Name() << "\" persistent histograms" |
| 832 << " to file: " << persistent_location_.value(); | 873 << " to file: " << persistent_location_.value(); |
| 833 return false; | 874 return false; |
| 834 } | 875 } |
| 835 | 876 |
| 836 return true; | 877 return true; |
| 837 #endif | 878 #endif |
| 838 } | 879 } |
| 839 | 880 |
| 881 void GlobalHistogramAllocator::DeletePersistentLocation() { |
| 882 #if defined(OS_NACL) |
| 883 NOTREACHED(); |
| 884 #else |
| 885 if (persistent_location_.empty()) |
| 886 return; |
| 887 |
| 888 // Open (with delete) and then immediately close the file by going out of |
| 889 // scope. This is the only cross-platform safe way to delete a file that may |
| 890 // be open elsewhere. Open handles will continue to operate normally but |
| 891 // new opens will not be possible. |
| 892 File file(persistent_location_, |
| 893 File::FLAG_OPEN | File::FLAG_READ | File::FLAG_DELETE_ON_CLOSE); |
| 894 #endif |
| 895 } |
| 896 |
| 840 GlobalHistogramAllocator::GlobalHistogramAllocator( | 897 GlobalHistogramAllocator::GlobalHistogramAllocator( |
| 841 std::unique_ptr<PersistentMemoryAllocator> memory) | 898 std::unique_ptr<PersistentMemoryAllocator> memory) |
| 842 : PersistentHistogramAllocator(std::move(memory)), | 899 : PersistentHistogramAllocator(std::move(memory)), |
| 843 import_iterator_(this) {} | 900 import_iterator_(this) {} |
| 844 | 901 |
| 845 void GlobalHistogramAllocator::ImportHistogramsToStatisticsRecorder() { | 902 void GlobalHistogramAllocator::ImportHistogramsToStatisticsRecorder() { |
| 846 // Skip the import if it's the histogram that was last created. Should a | 903 // Skip the import if it's the histogram that was last created. Should a |
| 847 // race condition cause the "last created" to be overwritten before it | 904 // race condition cause the "last created" to be overwritten before it |
| 848 // is recognized here then the histogram will be created and be ignored | 905 // is recognized here then the histogram will be created and be ignored |
| 849 // when it is detected as a duplicate by the statistics-recorder. This | 906 // when it is detected as a duplicate by the statistics-recorder. This |
| 850 // simple check reduces the time of creating persistent histograms by | 907 // simple check reduces the time of creating persistent histograms by |
| 851 // about 40%. | 908 // about 40%. |
| 852 Reference record_to_ignore = last_created(); | 909 Reference record_to_ignore = last_created(); |
| 853 | 910 |
| 854 // There is no lock on this because the iterator is lock-free while still | 911 // There is no lock on this because the iterator is lock-free while still |
| 855 // guaranteed to only return each entry only once. The StatisticsRecorder | 912 // guaranteed to only return each entry only once. The StatisticsRecorder |
| 856 // has its own lock so the Register operation is safe. | 913 // has its own lock so the Register operation is safe. |
| 857 while (true) { | 914 while (true) { |
| 858 std::unique_ptr<HistogramBase> histogram = | 915 std::unique_ptr<HistogramBase> histogram = |
| 859 import_iterator_.GetNextWithIgnore(record_to_ignore); | 916 import_iterator_.GetNextWithIgnore(record_to_ignore); |
| 860 if (!histogram) | 917 if (!histogram) |
| 861 break; | 918 break; |
| 862 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); | 919 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); |
| 863 } | 920 } |
| 864 } | 921 } |
| 865 | 922 |
| 866 } // namespace base | 923 } // namespace base |
| OLD | NEW |