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

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

Issue 1803253002: Improved iterator for persistent memory allocator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@refactor-hp
Patch Set: rebased Created 4 years, 8 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 // segment. In other words, don't share the segment until at least one 43 // segment. In other words, don't share the segment until at least one
44 // allocator has been attached to it. 44 // allocator has been attached to it.
45 // 45 //
46 // Note that memory not in active use is not accessed so it is possible to 46 // Note that memory not in active use is not accessed so it is possible to
47 // use virtual memory, including memory-mapped files, as backing storage with 47 // use virtual memory, including memory-mapped files, as backing storage with
48 // the OS "pinning" new (zeroed) physical RAM pages only as they are needed. 48 // the OS "pinning" new (zeroed) physical RAM pages only as they are needed.
49 class BASE_EXPORT PersistentMemoryAllocator { 49 class BASE_EXPORT PersistentMemoryAllocator {
50 public: 50 public:
51 typedef uint32_t Reference; 51 typedef uint32_t Reference;
52 52
53 // Internal state information when iterating over memory allocations. 53 // Iterator for going through all iterable memory records in an allocator.
54 class Iterator { 54 // Like the allocator itself, iterators are lock-free and thread-secure.
55 // That means that multiple threads can share an iterator and the same
56 // reference will not be returned twice.
57 //
58 // Iteration, in general, is tolerant of corrupted memory. It will return
59 // what it can and stop only when corruption forces it to. Bad corruption
60 // could cause the same object to be returned many times but it will
61 // eventually quit.
62 class BASE_EXPORT Iterator {
55 public: 63 public:
56 Iterator() : last(0) {} 64 // Constructs an iterator on a given |allocator|, starting at the beginning.
65 // The allocator must live beyond the lifetime of the iterator. This class
66 // has read-only access to the allocator (hence "const") but the returned
67 // references can be used on a read/write version, too.
68 explicit Iterator(const PersistentMemoryAllocator* allocator);
57 69
58 bool operator==(const Iterator& rhs) const { return last == rhs.last; } 70 // As above but resuming from the |starting_after| reference. The first call
59 bool operator!=(const Iterator& rhs) const { return last != rhs.last; } 71 // to GetNext() will return the next object found after that reference. The
72 // reference must be to an "iterable" object; references to non-iterable
73 // objects (those that never had MakeIterable() called for them) will cause
74 // a run-time error.
75 Iterator(const PersistentMemoryAllocator* allocator,
76 Reference starting_after);
60 77
61 void clear() { last = 0; } 78 // Gets the next iterable, storing that type in |type_return|. The actual
62 bool is_clear() const { return last == 0; } 79 // return value is a reference to the allocation inside the allocator or
80 // zero if there are no more. GetNext() may still be called again at a
81 // later time to retrieve any new allocations that have been added.
82 Reference GetNext(uint32_t* type_return);
83
84 // Similar to above but gets the next iterable of a specific |type_match|.
85 // This should not be mixed with calls to GetNext() because any allocations
86 // skipped here due to a type mis-match will never be returned by later
87 // calls to GetNext() meaning it's possible to completely miss entries.
88 Reference GetNextOfType(uint32_t type_match);
89
90 // Converts references to objects. This is a convenience method so that
91 // users of the iterator don't need to also have their own pointer to the
92 // allocator over which the iterator runs in order to retrieve objects.
93 // Because the iterator is not read/write, only "const" objects can be
94 // fetched. Non-const objects can be fetched using the reference on a
95 // non-const (external) pointer to the same allocator (or use const_cast
96 // to remove the qualifier).
97 template <typename T>
98 const T* GetAsObject(Reference ref, uint32_t type_id) const {
99 return allocator_->GetAsObject<T>(ref, type_id);
100 }
63 101
64 private: 102 private:
65 friend class PersistentMemoryAllocator; 103 // Weak-pointer to memory allocator being iterated over.
104 const PersistentMemoryAllocator* allocator_;
66 105
67 Reference last; 106 // The last record that was returned.
68 uint32_t niter; 107 std::atomic<Reference> last_record_;
108
109 // The number of records found; used for detecting loops.
110 std::atomic<uint32_t> record_count_;
111
112 DISALLOW_COPY_AND_ASSIGN(Iterator);
69 }; 113 };
70 114
71 // Returned information about the internal state of the heap. 115 // Returned information about the internal state of the heap.
72 struct MemoryInfo { 116 struct MemoryInfo {
73 size_t total; 117 size_t total;
74 size_t free; 118 size_t free;
75 }; 119 };
76 120
77 enum : uint32_t { 121 enum : uint32_t {
78 kTypeIdAny = 0 // Match any type-id inside GetAsObject(). 122 kTypeIdAny = 0 // Match any type-id inside GetAsObject().
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 // Once an object is made iterable, its position in iteration can never 249 // Once an object is made iterable, its position in iteration can never
206 // change; new iterable objects will always be added after it in the series. 250 // change; new iterable objects will always be added after it in the series.
207 void MakeIterable(Reference ref); 251 void MakeIterable(Reference ref);
208 252
209 // Get the information about the amount of free space in the allocator. The 253 // Get the information about the amount of free space in the allocator. The
210 // amount of free space should be treated as approximate due to extras from 254 // amount of free space should be treated as approximate due to extras from
211 // alignment and metadata. Concurrent allocations from other threads will 255 // alignment and metadata. Concurrent allocations from other threads will
212 // also make the true amount less than what is reported. 256 // also make the true amount less than what is reported.
213 void GetMemoryInfo(MemoryInfo* meminfo) const; 257 void GetMemoryInfo(MemoryInfo* meminfo) const;
214 258
215 // Iterating uses a |state| structure (initialized by CreateIterator) and
216 // returns both the reference to the object as well as the |type_id| of
217 // that object. A zero return value indicates there are currently no more
218 // objects to be found but future attempts can be made without having to
219 // reset the iterator to "first". Creating an iterator |starting_after|
220 // a known iterable object allows "resume" from that point with the next
221 // call to GetNextIterable returning the object after it.
222 void CreateIterator(Iterator* state) const { CreateIterator(state, 0); };
223 void CreateIterator(Iterator* state, Reference starting_after) const;
224 Reference GetNextIterable(Iterator* state, uint32_t* type_id) const;
225
226 // If there is some indication that the memory has become corrupted, 259 // If there is some indication that the memory has become corrupted,
227 // calling this will attempt to prevent further damage by indicating to 260 // calling this will attempt to prevent further damage by indicating to
228 // all processes that something is not as expected. 261 // all processes that something is not as expected.
229 void SetCorrupt() const; 262 void SetCorrupt() const;
230 263
231 // This can be called to determine if corruption has been detected in the 264 // This can be called to determine if corruption has been detected in the
232 // segment, possibly my a malicious actor. Once detected, future allocations 265 // segment, possibly my a malicious actor. Once detected, future allocations
233 // will fail and iteration may not locate all objects. 266 // will fail and iteration may not locate all objects.
234 bool IsCorrupt() const; 267 bool IsCorrupt() const;
235 268
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 395
363 private: 396 private:
364 std::unique_ptr<MemoryMappedFile> mapped_file_; 397 std::unique_ptr<MemoryMappedFile> mapped_file_;
365 398
366 DISALLOW_COPY_AND_ASSIGN(FilePersistentMemoryAllocator); 399 DISALLOW_COPY_AND_ASSIGN(FilePersistentMemoryAllocator);
367 }; 400 };
368 401
369 } // namespace base 402 } // namespace base
370 403
371 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ 404 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_
OLDNEW
« no previous file with comments | « base/metrics/persistent_histogram_allocator_unittest.cc ('k') | base/metrics/persistent_memory_allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698