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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 // change the type to something indicating it is no longer in use. | 89 // change the type to something indicating it is no longer in use. |
| 90 // | 90 // |
| 91 // Though persistent memory segments are transferrable between programs built | 91 // Though persistent memory segments are transferrable between programs built |
| 92 // for different natural word widths, they CANNOT be exchanged between CPUs | 92 // for different natural word widths, they CANNOT be exchanged between CPUs |
| 93 // of different endianess. Attempts to do so will simply see the existing data | 93 // of different endianess. Attempts to do so will simply see the existing data |
| 94 // as corrupt and refuse to access any of it. | 94 // as corrupt and refuse to access any of it. |
| 95 class BASE_EXPORT PersistentMemoryAllocator { | 95 class BASE_EXPORT PersistentMemoryAllocator { |
| 96 public: | 96 public: |
| 97 typedef uint32_t Reference; | 97 typedef uint32_t Reference; |
| 98 | 98 |
| 99 // These states are used to indicate the overall condition of the memory | |
| 100 // segment irrespective of what is stored within it. Because the data is | |
| 101 // often persistent and thus needs to be readable by different versions of | |
| 102 // a program, these values are fixed and can never change. | |
| 103 enum : uint8_t { | |
| 104 MEMORY_UNINITIALIZED = 0, // Persistent memory starts all zeros. | |
| 105 MEMORY_INITIALIZED = 1, // The header has been written. | |
| 106 MEMORY_DELETED = 2, // The data should be considered deleted. | |
|
Alexei Svitkine (slow)
2017/03/15 15:47:20
Can you define what "considered deleted" means?
bcwhite
2017/03/15 19:21:48
Done.
| |
| 107 | |
| 108 // Outside code can create states starting with this number; these too | |
| 109 // must also never change between code versions. | |
| 110 MEMORY_USER_DEFINED = 100, | |
| 111 }; | |
| 112 | |
| 99 // Iterator for going through all iterable memory records in an allocator. | 113 // Iterator for going through all iterable memory records in an allocator. |
| 100 // Like the allocator itself, iterators are lock-free and thread-secure. | 114 // Like the allocator itself, iterators are lock-free and thread-secure. |
| 101 // That means that multiple threads can share an iterator and the same | 115 // That means that multiple threads can share an iterator and the same |
| 102 // reference will not be returned twice. | 116 // reference will not be returned twice. |
| 103 // | 117 // |
| 104 // The order of the items returned by an iterator matches the order in which | 118 // The order of the items returned by an iterator matches the order in which |
| 105 // MakeIterable() was called on them. Once an allocation is made iterable, | 119 // MakeIterable() was called on them. Once an allocation is made iterable, |
| 106 // it is always such so the only possible difference between successive | 120 // it is always such so the only possible difference between successive |
| 107 // iterations is for more to be added to the end. | 121 // iterations is for more to be added to the end. |
| 108 // | 122 // |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 272 | 286 |
| 273 // Get the internal identifier for this persistent memory segment. | 287 // Get the internal identifier for this persistent memory segment. |
| 274 uint64_t Id() const; | 288 uint64_t Id() const; |
| 275 | 289 |
| 276 // Get the internal name of this allocator (possibly an empty string). | 290 // Get the internal name of this allocator (possibly an empty string). |
| 277 const char* Name() const; | 291 const char* Name() const; |
| 278 | 292 |
| 279 // Is this segment open only for read? | 293 // Is this segment open only for read? |
| 280 bool IsReadonly() { return readonly_; } | 294 bool IsReadonly() { return readonly_; } |
| 281 | 295 |
| 296 // Manage the saved state of the memory. | |
| 297 void SetMemoryState(uint8_t memory_state); | |
| 298 uint8_t GetMemoryState(); | |
| 299 | |
| 282 // Create internal histograms for tracking memory use and allocation sizes | 300 // Create internal histograms for tracking memory use and allocation sizes |
| 283 // for allocator of |name| (which can simply be the result of Name()). This | 301 // for allocator of |name| (which can simply be the result of Name()). This |
| 284 // is done seperately from construction for situations such as when the | 302 // is done seperately from construction for situations such as when the |
| 285 // histograms will be backed by memory provided by this very allocator. | 303 // histograms will be backed by memory provided by this very allocator. |
| 286 // | 304 // |
| 287 // IMPORTANT: Callers must update tools/metrics/histograms/histograms.xml | 305 // IMPORTANT: Callers must update tools/metrics/histograms/histograms.xml |
| 288 // with the following histograms: | 306 // with the following histograms: |
| 289 // UMA.PersistentAllocator.name.Errors | 307 // UMA.PersistentAllocator.name.Errors |
| 290 // UMA.PersistentAllocator.name.UsedPct | 308 // UMA.PersistentAllocator.name.UsedPct |
| 291 void CreateTrackingHistograms(base::StringPiece name); | 309 void CreateTrackingHistograms(base::StringPiece name); |
| 292 | 310 |
| 311 // Flushes the persistent memory to any backing store. This typically does | |
| 312 // nothing but is used by the FilePersistentMemoryAllocator to inform the | |
| 313 // OS that all the data should be sent to the disk immediately. This is | |
| 314 // useful in the rare case where something has just been stored that needs | |
| 315 // to survive a hard shutdown of the machine like from a power failure. | |
| 316 // The |sync| parameter indicates if this call should block until the flush | |
| 317 // is complete but is only advisory and may or may not have an effect | |
| 318 // depending on the capabilities of the OS. Synchronous flushes are allowed | |
| 319 // only from theads that are allowed to do I/O. | |
| 320 void Flush(bool sync) { Flush(used(), sync); } | |
|
Alexei Svitkine (slow)
2017/03/15 15:47:20
Don't overload a protected function with a public
bcwhite
2017/03/15 19:21:48
Done. At some point it may be useful to become Fl
Alexei Svitkine (slow)
2017/03/15 20:05:29
The second part of this comment was about not havi
bcwhite
2017/03/16 15:53:03
Done. Originally it was just providing a default
| |
| 321 | |
| 293 // Direct access to underlying memory segment. If the segment is shared | 322 // Direct access to underlying memory segment. If the segment is shared |
| 294 // across threads or processes, reading data through these values does | 323 // across threads or processes, reading data through these values does |
| 295 // not guarantee consistency. Use with care. Do not write. | 324 // not guarantee consistency. Use with care. Do not write. |
| 296 const void* data() const { return const_cast<const char*>(mem_base_); } | 325 const void* data() const { return const_cast<const char*>(mem_base_); } |
| 297 size_t length() const { return mem_size_; } | 326 size_t length() const { return mem_size_; } |
| 298 size_t size() const { return mem_size_; } | 327 size_t size() const { return mem_size_; } |
| 299 size_t used() const; | 328 size_t used() const; |
| 300 | 329 |
| 301 // Get an object referenced by a |ref|. For safety reasons, the |type_id| | 330 // Get an object referenced by a |ref|. For safety reasons, the |type_id| |
| 302 // code and size-of(|T|) are compared to ensure the reference is valid | 331 // code and size-of(|T|) are compared to ensure the reference is valid |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 569 MemoryType type; | 598 MemoryType type; |
| 570 }; | 599 }; |
| 571 | 600 |
| 572 // Constructs the allocator. Everything is the same as the public allocator | 601 // Constructs the allocator. Everything is the same as the public allocator |
| 573 // except |memory| which is a structure with additional information besides | 602 // except |memory| which is a structure with additional information besides |
| 574 // the base address. | 603 // the base address. |
| 575 PersistentMemoryAllocator(Memory memory, size_t size, size_t page_size, | 604 PersistentMemoryAllocator(Memory memory, size_t size, size_t page_size, |
| 576 uint64_t id, base::StringPiece name, | 605 uint64_t id, base::StringPiece name, |
| 577 bool readonly); | 606 bool readonly); |
| 578 | 607 |
| 608 // Implementation of Flush that accepts how much to flush. | |
| 609 virtual void Flush(size_t length, bool sync); | |
| 610 | |
| 579 volatile char* const mem_base_; // Memory base. (char so sizeof guaranteed 1) | 611 volatile char* const mem_base_; // Memory base. (char so sizeof guaranteed 1) |
| 580 const MemoryType mem_type_; // Type of memory allocation. | 612 const MemoryType mem_type_; // Type of memory allocation. |
| 581 const uint32_t mem_size_; // Size of entire memory segment. | 613 const uint32_t mem_size_; // Size of entire memory segment. |
| 582 const uint32_t mem_page_; // Page size allocations shouldn't cross. | 614 const uint32_t mem_page_; // Page size allocations shouldn't cross. |
| 583 | 615 |
| 584 private: | 616 private: |
| 585 struct SharedMetadata; | 617 struct SharedMetadata; |
| 586 struct BlockHeader; | 618 struct BlockHeader; |
| 587 static const uint32_t kAllocAlignment; | 619 static const uint32_t kAllocAlignment; |
| 588 static const Reference kReferenceQueue; | 620 static const Reference kReferenceQueue; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 704 base::StringPiece name, | 736 base::StringPiece name, |
| 705 bool read_only); | 737 bool read_only); |
| 706 ~FilePersistentMemoryAllocator() override; | 738 ~FilePersistentMemoryAllocator() override; |
| 707 | 739 |
| 708 // Ensure that the file isn't so invalid that it would crash when passing it | 740 // Ensure that the file isn't so invalid that it would crash when passing it |
| 709 // to the allocator. This doesn't guarantee the file is valid, just that it | 741 // to the allocator. This doesn't guarantee the file is valid, just that it |
| 710 // won't cause the program to abort. The existing IsCorrupt() call will handle | 742 // won't cause the program to abort. The existing IsCorrupt() call will handle |
| 711 // the rest. | 743 // the rest. |
| 712 static bool IsFileAcceptable(const MemoryMappedFile& file, bool read_only); | 744 static bool IsFileAcceptable(const MemoryMappedFile& file, bool read_only); |
| 713 | 745 |
| 746 protected: | |
| 747 // PersistentMemoryAllocator: | |
| 748 void Flush(size_t length, bool sync) override; | |
| 749 | |
| 714 private: | 750 private: |
| 715 std::unique_ptr<MemoryMappedFile> mapped_file_; | 751 std::unique_ptr<MemoryMappedFile> mapped_file_; |
| 716 | 752 |
| 717 DISALLOW_COPY_AND_ASSIGN(FilePersistentMemoryAllocator); | 753 DISALLOW_COPY_AND_ASSIGN(FilePersistentMemoryAllocator); |
| 718 }; | 754 }; |
| 719 #endif // !defined(OS_NACL) | 755 #endif // !defined(OS_NACL) |
| 720 | 756 |
| 721 } // namespace base | 757 } // namespace base |
| 722 | 758 |
| 723 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ | 759 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ |
| OLD | NEW |