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 *out_base_path = dir.AppendASCII(name) | |
Alexei Svitkine (slow)
2016/09/15 16:49:44
Nit: I'd prefer to wrap after the =
But you can k
scottmg
2016/09/15 17:41:13
Yeah, this is clang-format output. It doesn't quit
| |
748 .AddExtension(PersistentMemoryAllocator::kFileExtension); | |
749 if (out_active_path) { | |
750 *out_active_path = | |
751 dir.AppendASCII(name.as_string() + std::string("-active")) | |
752 .AddExtension(PersistentMemoryAllocator::kFileExtension); | |
753 } | |
754 } | |
755 #endif // !OS_NACL | |
Alexei Svitkine (slow)
2016/09/15 16:49:44
Nit: !defined(OS_NACL)
scottmg
2016/09/15 17:41:13
Done.
| |
717 | 756 |
718 // static | 757 // static |
719 void GlobalHistogramAllocator::CreateWithSharedMemory( | 758 void GlobalHistogramAllocator::CreateWithSharedMemory( |
720 std::unique_ptr<SharedMemory> memory, | 759 std::unique_ptr<SharedMemory> memory, |
721 size_t size, | 760 size_t size, |
722 uint64_t id, | 761 uint64_t id, |
723 StringPiece name) { | 762 StringPiece name) { |
724 if ((!memory->memory() && !memory->Map(size)) || | 763 if ((!memory->memory() && !memory->Map(size)) || |
725 !SharedPersistentMemoryAllocator::IsSharedMemoryAcceptable(*memory)) { | 764 !SharedPersistentMemoryAllocator::IsSharedMemoryAcceptable(*memory)) { |
726 NOTREACHED(); | 765 NOTREACHED(); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
830 contents)) { | 869 contents)) { |
831 LOG(ERROR) << "Could not write \"" << Name() << "\" persistent histograms" | 870 LOG(ERROR) << "Could not write \"" << Name() << "\" persistent histograms" |
832 << " to file: " << persistent_location_.value(); | 871 << " to file: " << persistent_location_.value(); |
833 return false; | 872 return false; |
834 } | 873 } |
835 | 874 |
836 return true; | 875 return true; |
837 #endif | 876 #endif |
838 } | 877 } |
839 | 878 |
879 void GlobalHistogramAllocator::DeletePersistentLocation() { | |
880 if (persistent_location_.empty()) | |
881 return; | |
882 | |
883 // Open (with delete) and then immediately close the file by going out of | |
884 // scope. This is the only cross-platform safe way to delete a file that may | |
885 // be open elsewhere. Open handles will continue to operate normally but | |
886 // new opens will not be possible. | |
887 File file(persistent_location_, | |
Alexei Svitkine (slow)
2016/09/15 16:49:44
Is this supported for NACL builds? Seems like it s
bcwhite
2016/09/15 17:07:48
Heh. I told him to move it in here along-side Wri
scottmg
2016/09/15 17:41:13
#ifdef'd for now to match and fix the build. As Br
Alexei Svitkine (slow)
2016/09/15 17:49:16
Sure, I'm ok with that being explored in a separat
bcwhite
2016/09/15 17:56:33
If I remember correctly, it's only the .cc file th
| |
888 File::FLAG_OPEN | File::FLAG_READ | File::FLAG_DELETE_ON_CLOSE); | |
889 } | |
890 | |
840 GlobalHistogramAllocator::GlobalHistogramAllocator( | 891 GlobalHistogramAllocator::GlobalHistogramAllocator( |
841 std::unique_ptr<PersistentMemoryAllocator> memory) | 892 std::unique_ptr<PersistentMemoryAllocator> memory) |
842 : PersistentHistogramAllocator(std::move(memory)), | 893 : PersistentHistogramAllocator(std::move(memory)), |
843 import_iterator_(this) {} | 894 import_iterator_(this) {} |
844 | 895 |
845 void GlobalHistogramAllocator::ImportHistogramsToStatisticsRecorder() { | 896 void GlobalHistogramAllocator::ImportHistogramsToStatisticsRecorder() { |
846 // Skip the import if it's the histogram that was last created. Should a | 897 // 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 | 898 // race condition cause the "last created" to be overwritten before it |
848 // is recognized here then the histogram will be created and be ignored | 899 // 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 | 900 // when it is detected as a duplicate by the statistics-recorder. This |
850 // simple check reduces the time of creating persistent histograms by | 901 // simple check reduces the time of creating persistent histograms by |
851 // about 40%. | 902 // about 40%. |
852 Reference record_to_ignore = last_created(); | 903 Reference record_to_ignore = last_created(); |
853 | 904 |
854 // There is no lock on this because the iterator is lock-free while still | 905 // 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 | 906 // guaranteed to only return each entry only once. The StatisticsRecorder |
856 // has its own lock so the Register operation is safe. | 907 // has its own lock so the Register operation is safe. |
857 while (true) { | 908 while (true) { |
858 std::unique_ptr<HistogramBase> histogram = | 909 std::unique_ptr<HistogramBase> histogram = |
859 import_iterator_.GetNextWithIgnore(record_to_ignore); | 910 import_iterator_.GetNextWithIgnore(record_to_ignore); |
860 if (!histogram) | 911 if (!histogram) |
861 break; | 912 break; |
862 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); | 913 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); |
863 } | 914 } |
864 } | 915 } |
865 | 916 |
866 } // namespace base | 917 } // namespace base |
OLD | NEW |