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 |