| 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 MemoryState : uint8_t { |
| 104 // Persistent memory starts all zeros and so shows "uninitialized". |
| 105 MEMORY_UNINITIALIZED = 0, |
| 106 |
| 107 // The header has been written and the memory is ready for use. |
| 108 MEMORY_INITIALIZED = 1, |
| 109 |
| 110 // The data should be considered deleted. This would be set when the |
| 111 // allocator is being cleaned up. If file-backed, the file is likely |
| 112 // to be deleted but since deletion can fail for a variety of reasons, |
| 113 // having this extra status means a future reader can realize what |
| 114 // should have happened. |
| 115 MEMORY_DELETED = 2, |
| 116 |
| 117 // Outside code can create states starting with this number; these too |
| 118 // must also never change between code versions. |
| 119 MEMORY_USER_DEFINED = 100, |
| 120 }; |
| 121 |
| 99 // Iterator for going through all iterable memory records in an allocator. | 122 // Iterator for going through all iterable memory records in an allocator. |
| 100 // Like the allocator itself, iterators are lock-free and thread-secure. | 123 // Like the allocator itself, iterators are lock-free and thread-secure. |
| 101 // That means that multiple threads can share an iterator and the same | 124 // That means that multiple threads can share an iterator and the same |
| 102 // reference will not be returned twice. | 125 // reference will not be returned twice. |
| 103 // | 126 // |
| 104 // The order of the items returned by an iterator matches the order in which | 127 // 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, | 128 // MakeIterable() was called on them. Once an allocation is made iterable, |
| 106 // it is always such so the only possible difference between successive | 129 // it is always such so the only possible difference between successive |
| 107 // iterations is for more to be added to the end. | 130 // iterations is for more to be added to the end. |
| 108 // | 131 // |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 static bool IsMemoryAcceptable(const void* data, size_t size, | 293 static bool IsMemoryAcceptable(const void* data, size_t size, |
| 271 size_t page_size, bool readonly); | 294 size_t page_size, bool readonly); |
| 272 | 295 |
| 273 // Get the internal identifier for this persistent memory segment. | 296 // Get the internal identifier for this persistent memory segment. |
| 274 uint64_t Id() const; | 297 uint64_t Id() const; |
| 275 | 298 |
| 276 // Get the internal name of this allocator (possibly an empty string). | 299 // Get the internal name of this allocator (possibly an empty string). |
| 277 const char* Name() const; | 300 const char* Name() const; |
| 278 | 301 |
| 279 // Is this segment open only for read? | 302 // Is this segment open only for read? |
| 280 bool IsReadonly() { return readonly_; } | 303 bool IsReadonly() const { return readonly_; } |
| 304 |
| 305 // Manage the saved state of the memory. |
| 306 void SetMemoryState(uint8_t memory_state); |
| 307 uint8_t GetMemoryState() const; |
| 281 | 308 |
| 282 // Create internal histograms for tracking memory use and allocation sizes | 309 // Create internal histograms for tracking memory use and allocation sizes |
| 283 // for allocator of |name| (which can simply be the result of Name()). This | 310 // 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 | 311 // is done seperately from construction for situations such as when the |
| 285 // histograms will be backed by memory provided by this very allocator. | 312 // histograms will be backed by memory provided by this very allocator. |
| 286 // | 313 // |
| 287 // IMPORTANT: Callers must update tools/metrics/histograms/histograms.xml | 314 // IMPORTANT: Callers must update tools/metrics/histograms/histograms.xml |
| 288 // with the following histograms: | 315 // with the following histograms: |
| 289 // UMA.PersistentAllocator.name.Errors | 316 // UMA.PersistentAllocator.name.Errors |
| 290 // UMA.PersistentAllocator.name.UsedPct | 317 // UMA.PersistentAllocator.name.UsedPct |
| 291 void CreateTrackingHistograms(base::StringPiece name); | 318 void CreateTrackingHistograms(base::StringPiece name); |
| 292 | 319 |
| 320 // Flushes the persistent memory to any backing store. This typically does |
| 321 // nothing but is used by the FilePersistentMemoryAllocator to inform the |
| 322 // OS that all the data should be sent to the disk immediately. This is |
| 323 // useful in the rare case where something has just been stored that needs |
| 324 // to survive a hard shutdown of the machine like from a power failure. |
| 325 // The |sync| parameter indicates if this call should block until the flush |
| 326 // is complete but is only advisory and may or may not have an effect |
| 327 // depending on the capabilities of the OS. Synchronous flushes are allowed |
| 328 // only from theads that are allowed to do I/O. |
| 329 void Flush(bool sync); |
| 330 |
| 293 // Direct access to underlying memory segment. If the segment is shared | 331 // Direct access to underlying memory segment. If the segment is shared |
| 294 // across threads or processes, reading data through these values does | 332 // across threads or processes, reading data through these values does |
| 295 // not guarantee consistency. Use with care. Do not write. | 333 // not guarantee consistency. Use with care. Do not write. |
| 296 const void* data() const { return const_cast<const char*>(mem_base_); } | 334 const void* data() const { return const_cast<const char*>(mem_base_); } |
| 297 size_t length() const { return mem_size_; } | 335 size_t length() const { return mem_size_; } |
| 298 size_t size() const { return mem_size_; } | 336 size_t size() const { return mem_size_; } |
| 299 size_t used() const; | 337 size_t used() const; |
| 300 | 338 |
| 301 // Get an object referenced by a |ref|. For safety reasons, the |type_id| | 339 // 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 | 340 // 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; | 607 MemoryType type; |
| 570 }; | 608 }; |
| 571 | 609 |
| 572 // Constructs the allocator. Everything is the same as the public allocator | 610 // Constructs the allocator. Everything is the same as the public allocator |
| 573 // except |memory| which is a structure with additional information besides | 611 // except |memory| which is a structure with additional information besides |
| 574 // the base address. | 612 // the base address. |
| 575 PersistentMemoryAllocator(Memory memory, size_t size, size_t page_size, | 613 PersistentMemoryAllocator(Memory memory, size_t size, size_t page_size, |
| 576 uint64_t id, base::StringPiece name, | 614 uint64_t id, base::StringPiece name, |
| 577 bool readonly); | 615 bool readonly); |
| 578 | 616 |
| 617 // Implementation of Flush that accepts how much to flush. |
| 618 virtual void FlushPartial(size_t length, bool sync); |
| 619 |
| 579 volatile char* const mem_base_; // Memory base. (char so sizeof guaranteed 1) | 620 volatile char* const mem_base_; // Memory base. (char so sizeof guaranteed 1) |
| 580 const MemoryType mem_type_; // Type of memory allocation. | 621 const MemoryType mem_type_; // Type of memory allocation. |
| 581 const uint32_t mem_size_; // Size of entire memory segment. | 622 const uint32_t mem_size_; // Size of entire memory segment. |
| 582 const uint32_t mem_page_; // Page size allocations shouldn't cross. | 623 const uint32_t mem_page_; // Page size allocations shouldn't cross. |
| 583 | 624 |
| 584 private: | 625 private: |
| 585 struct SharedMetadata; | 626 struct SharedMetadata; |
| 586 struct BlockHeader; | 627 struct BlockHeader; |
| 587 static const uint32_t kAllocAlignment; | 628 static const uint32_t kAllocAlignment; |
| 588 static const Reference kReferenceQueue; | 629 static const Reference kReferenceQueue; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 base::StringPiece name, | 745 base::StringPiece name, |
| 705 bool read_only); | 746 bool read_only); |
| 706 ~FilePersistentMemoryAllocator() override; | 747 ~FilePersistentMemoryAllocator() override; |
| 707 | 748 |
| 708 // Ensure that the file isn't so invalid that it would crash when passing it | 749 // 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 | 750 // 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 | 751 // won't cause the program to abort. The existing IsCorrupt() call will handle |
| 711 // the rest. | 752 // the rest. |
| 712 static bool IsFileAcceptable(const MemoryMappedFile& file, bool read_only); | 753 static bool IsFileAcceptable(const MemoryMappedFile& file, bool read_only); |
| 713 | 754 |
| 755 protected: |
| 756 // PersistentMemoryAllocator: |
| 757 void FlushPartial(size_t length, bool sync) override; |
| 758 |
| 714 private: | 759 private: |
| 715 std::unique_ptr<MemoryMappedFile> mapped_file_; | 760 std::unique_ptr<MemoryMappedFile> mapped_file_; |
| 716 | 761 |
| 717 DISALLOW_COPY_AND_ASSIGN(FilePersistentMemoryAllocator); | 762 DISALLOW_COPY_AND_ASSIGN(FilePersistentMemoryAllocator); |
| 718 }; | 763 }; |
| 719 #endif // !defined(OS_NACL) | 764 #endif // !defined(OS_NACL) |
| 720 | 765 |
| 721 } // namespace base | 766 } // namespace base |
| 722 | 767 |
| 723 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ | 768 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ |
| OLD | NEW |