Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 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 #ifndef BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ | 5 #ifndef BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ |
| 6 #define BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ | 6 #define BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <atomic> | 10 #include <atomic> |
| (...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 760 // PersistentMemoryAllocator: | 760 // PersistentMemoryAllocator: |
| 761 void FlushPartial(size_t length, bool sync) override; | 761 void FlushPartial(size_t length, bool sync) override; |
| 762 | 762 |
| 763 private: | 763 private: |
| 764 std::unique_ptr<MemoryMappedFile> mapped_file_; | 764 std::unique_ptr<MemoryMappedFile> mapped_file_; |
| 765 | 765 |
| 766 DISALLOW_COPY_AND_ASSIGN(FilePersistentMemoryAllocator); | 766 DISALLOW_COPY_AND_ASSIGN(FilePersistentMemoryAllocator); |
| 767 }; | 767 }; |
| 768 #endif // !defined(OS_NACL) | 768 #endif // !defined(OS_NACL) |
| 769 | 769 |
| 770 // An allocation that is defined but not executed until required at a later | |
| 771 // time. This allows for potential users of an allocation to be decoupled | |
| 772 // from the logic that defines it. In addition, there can be multiple users | |
| 773 // of the same allocation or any region thereof that are guaranteed to always | |
| 774 // use the same space. It's okay to copy/move these objects. | |
| 775 // | |
| 776 // This is a top-level class instead of an inner class of the PMA so that it | |
| 777 // can be forward-declared in other header files without the need to include | |
| 778 // the full contents of this file. | |
| 779 class BASE_EXPORT DelayedPersistentAllocation { | |
| 780 public: | |
| 781 using Reference = PersistentMemoryAllocator::Reference; | |
| 782 | |
| 783 // Creates a delayed allocation using the specified |allocator|. When | |
| 784 // needed, the memory will be allocated using the specified |type| and | |
| 785 // |size|. If |offset| is given, the returned pointer will be at that | |
|
Alexei Svitkine (slow)
2017/04/12 17:04:25
Please expand comment to make explicit whether |si
bcwhite
2017/04/12 21:23:43
Done.
| |
| 786 // offset into the segment; this allows combining allocations into a | |
| 787 // single persistent segment to reduce overhead and means as "all or | |
|
Alexei Svitkine (slow)
2017/04/12 17:04:25
Nit: "means as" -> "means an"
bcwhite
2017/04/12 21:23:42
Done.
| |
| 788 // nothing" request. | |
| 789 // | |
| 790 // Once allocated, a reference to the segment will be stored at |ref|. | |
| 791 // This shared location must be initialized to zero (0); it is checked | |
| 792 // with every Get() request to see if the allocation has already been | |
| 793 // done. | |
| 794 // | |
| 795 // For conveience, methods taking both Atomic32 and std::atomic<Reference> | |
|
Alexei Svitkine (slow)
2017/04/12 17:04:25
Nit: convenience
bcwhite
2017/04/12 21:23:42
Done.
| |
| 796 // are defined. | |
| 797 DelayedPersistentAllocation(PersistentMemoryAllocator* allocator, | |
| 798 subtle::Atomic32* ref, | |
| 799 uint32_t type, | |
| 800 size_t size); | |
| 801 DelayedPersistentAllocation(PersistentMemoryAllocator* allocator, | |
| 802 subtle::Atomic32* ref, | |
| 803 uint32_t type, | |
| 804 size_t size, | |
| 805 size_t offset); | |
| 806 DelayedPersistentAllocation(PersistentMemoryAllocator* allocator, | |
| 807 std::atomic<Reference>* ref, | |
| 808 uint32_t type, | |
| 809 size_t size); | |
| 810 DelayedPersistentAllocation(PersistentMemoryAllocator* allocator, | |
| 811 std::atomic<Reference>* ref, | |
| 812 uint32_t type, | |
| 813 size_t size, | |
| 814 size_t offset); | |
| 815 ~DelayedPersistentAllocation(); | |
| 816 | |
| 817 // Make this allocation "iterable" when realized. | |
| 818 void MakeIterable(); | |
| 819 | |
| 820 // Gets a pointer to the defined allocation. This will realize the request | |
| 821 // and update the reference provided during construction. The memory will | |
| 822 // be zeroed the first time it is returned, after that it is shared with | |
| 823 // all other Get() requests and so shows any changes made to it elsewhere. | |
| 824 // | |
| 825 // If the allocation fails for any reason, null will be returned. This works | |
| 826 // even on "const" objects because the allocation is already defined, just | |
| 827 // delayed. | |
| 828 void* Get() const; | |
| 829 | |
| 830 // Gets the internal reference value. If this returns a non-zero value then | |
| 831 // a subsequent call to Get() will do nothing but convert that reference into | |
| 832 // a memory location -- useful for accessing an existing allocation without | |
| 833 // creating one unnecessarily. | |
| 834 Reference reference() const { | |
| 835 return reference_->load(std::memory_order_relaxed); | |
| 836 } | |
| 837 | |
| 838 private: | |
| 839 // The underlying object that does the actual allocation of memory. Its | |
| 840 // lifetime must exceed that of all DelayedPersistentAllocation objects | |
| 841 // that use it. | |
| 842 PersistentMemoryAllocator* const allocator_; | |
| 843 | |
| 844 // The desired type and size of the allocated segment plus the offset | |
| 845 // within it for the defined request. | |
| 846 uint32_t const type_; | |
|
Alexei Svitkine (slow)
2017/04/12 17:04:25
Nit: I think for primitive types, it's more common
bcwhite
2017/04/12 21:23:42
Done.
| |
| 847 size_t const size_; | |
| 848 size_t const offset_; | |
| 849 | |
| 850 // The location at which a reference to the allocated segment is to be | |
| 851 // stored once the allocation is complete. If multiple delayed allocations | |
| 852 // share the same pointer then an allocation on one will amount to an | |
| 853 // allocation for all. | |
| 854 volatile std::atomic<Reference>* const reference_; | |
| 855 | |
| 856 // Flag indicating if allocation should be made iterable when done. | |
| 857 bool make_iterable_ = false; | |
| 858 }; | |
|
Alexei Svitkine (slow)
2017/04/12 17:04:25
DISALLOW_COPY_AND_ASSIGN()?
bcwhite
2017/04/12 21:23:42
No, it's explicitly allowed and safe. This makes
Alexei Svitkine (slow)
2017/04/21 15:14:16
Okay, add a comment about it then in the same plac
bcwhite
2017/04/21 15:59:04
Done.
| |
| 859 | |
| 770 } // namespace base | 860 } // namespace base |
| 771 | 861 |
| 772 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ | 862 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ |
| OLD | NEW |