Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: base/metrics/persistent_memory_allocator.h

Issue 2742193002: Harden allocator for file-backed memory. (Closed)
Patch Set: fix some build problems Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698