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 ConstructBaseActivePairFilePaths(dir, name, &base_path, &active_path); |
| 739 return CreateWithActiveFile(base_path, active_path, size, id, name); |
| 740 } |
| 741 |
| 742 // static |
| 743 void GlobalHistogramAllocator::ConstructBaseActivePairFilePaths( |
| 744 const FilePath& dir, |
| 745 StringPiece name, |
| 746 FilePath* out_base_path, |
| 747 FilePath* out_active_path) { |
| 748 *out_base_path = dir.AppendASCII(name) |
| 749 .AddExtension(PersistentMemoryAllocator::kFileExtension); |
| 750 *out_active_path = |
| 751 dir.AppendASCII(name.as_string() + std::string("-active")) |
| 752 .AddExtension(PersistentMemoryAllocator::kFileExtension); |
| 753 } |
| 754 #endif // !OS_NACL |
717 | 755 |
718 // static | 756 // static |
719 void GlobalHistogramAllocator::CreateWithSharedMemory( | 757 void GlobalHistogramAllocator::CreateWithSharedMemory( |
720 std::unique_ptr<SharedMemory> memory, | 758 std::unique_ptr<SharedMemory> memory, |
721 size_t size, | 759 size_t size, |
722 uint64_t id, | 760 uint64_t id, |
723 StringPiece name) { | 761 StringPiece name) { |
724 if ((!memory->memory() && !memory->Map(size)) || | 762 if ((!memory->memory() && !memory->Map(size)) || |
725 !SharedPersistentMemoryAllocator::IsSharedMemoryAcceptable(*memory)) { | 763 !SharedPersistentMemoryAllocator::IsSharedMemoryAcceptable(*memory)) { |
726 NOTREACHED(); | 764 NOTREACHED(); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 contents)) { | 868 contents)) { |
831 LOG(ERROR) << "Could not write \"" << Name() << "\" persistent histograms" | 869 LOG(ERROR) << "Could not write \"" << Name() << "\" persistent histograms" |
832 << " to file: " << persistent_location_.value(); | 870 << " to file: " << persistent_location_.value(); |
833 return false; | 871 return false; |
834 } | 872 } |
835 | 873 |
836 return true; | 874 return true; |
837 #endif | 875 #endif |
838 } | 876 } |
839 | 877 |
| 878 void GlobalHistogramAllocator::DeletePersistentLocation() { |
| 879 if (persistent_location_.empty()) |
| 880 return; |
| 881 |
| 882 // Open (with delete) and then immediately close the file by going out of |
| 883 // scope. This is the only cross-platform safe way to delete a file that may |
| 884 // be open elsewhere. Open handles will continue to operate normally but |
| 885 // new opens will not be possible. |
| 886 File file(persistent_location_, |
| 887 File::FLAG_OPEN | File::FLAG_READ | File::FLAG_DELETE_ON_CLOSE); |
| 888 } |
| 889 |
840 GlobalHistogramAllocator::GlobalHistogramAllocator( | 890 GlobalHistogramAllocator::GlobalHistogramAllocator( |
841 std::unique_ptr<PersistentMemoryAllocator> memory) | 891 std::unique_ptr<PersistentMemoryAllocator> memory) |
842 : PersistentHistogramAllocator(std::move(memory)), | 892 : PersistentHistogramAllocator(std::move(memory)), |
843 import_iterator_(this) {} | 893 import_iterator_(this) {} |
844 | 894 |
845 void GlobalHistogramAllocator::ImportHistogramsToStatisticsRecorder() { | 895 void GlobalHistogramAllocator::ImportHistogramsToStatisticsRecorder() { |
846 // Skip the import if it's the histogram that was last created. Should a | 896 // 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 | 897 // race condition cause the "last created" to be overwritten before it |
848 // is recognized here then the histogram will be created and be ignored | 898 // 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 | 899 // when it is detected as a duplicate by the statistics-recorder. This |
850 // simple check reduces the time of creating persistent histograms by | 900 // simple check reduces the time of creating persistent histograms by |
851 // about 40%. | 901 // about 40%. |
852 Reference record_to_ignore = last_created(); | 902 Reference record_to_ignore = last_created(); |
853 | 903 |
854 // There is no lock on this because the iterator is lock-free while still | 904 // 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 | 905 // guaranteed to only return each entry only once. The StatisticsRecorder |
856 // has its own lock so the Register operation is safe. | 906 // has its own lock so the Register operation is safe. |
857 while (true) { | 907 while (true) { |
858 std::unique_ptr<HistogramBase> histogram = | 908 std::unique_ptr<HistogramBase> histogram = |
859 import_iterator_.GetNextWithIgnore(record_to_ignore); | 909 import_iterator_.GetNextWithIgnore(record_to_ignore); |
860 if (!histogram) | 910 if (!histogram) |
861 break; | 911 break; |
862 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); | 912 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); |
863 } | 913 } |
864 } | 914 } |
865 | 915 |
866 } // namespace base | 916 } // namespace base |
OLD | NEW |