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 #include <atomic> | 9 #include <atomic> |
10 | 10 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 // segment. In other words, don't share the segment until at least one | 42 // segment. In other words, don't share the segment until at least one |
43 // allocator has been attached to it. | 43 // allocator has been attached to it. |
44 // | 44 // |
45 // Note that memory not in active use is not accessed so it is possible to | 45 // Note that memory not in active use is not accessed so it is possible to |
46 // use virtual memory, including memory-mapped files, as backing storage with | 46 // use virtual memory, including memory-mapped files, as backing storage with |
47 // the OS "pinning" new (zeroed) physical RAM pages only as they are needed. | 47 // the OS "pinning" new (zeroed) physical RAM pages only as they are needed. |
48 class BASE_EXPORT PersistentMemoryAllocator { | 48 class BASE_EXPORT PersistentMemoryAllocator { |
49 public: | 49 public: |
50 typedef uint32_t Reference; | 50 typedef uint32_t Reference; |
51 | 51 |
52 // Internal state information when iterating over memory allocations. | 52 // Iterator for going through all iterable memory records in an allocator. |
53 class Iterator { | 53 // Like the allocator itself, iterators are lock-free and thread-secure. |
54 // That means that multiple threads can share an iterator and the same | |
55 // reference will not be returned twice. | |
56 // | |
57 // Iteration, in general, is tolerant of corrupted memory. It will return | |
58 // what it can and stop only when corruption forces it to. Bad corruption | |
59 // could cause the same object to be returned many times but it will | |
60 // eventually quit. | |
61 class BASE_EXPORT Iterator { | |
54 public: | 62 public: |
55 Iterator() : last(0) {} | 63 // Constructs an iterator on a given |allocator|, starting at the beginning. |
64 Iterator(const PersistentMemoryAllocator* allocator); | |
Ilya Sherman
2016/03/24 02:03:58
nit: explicit
Ilya Sherman
2016/03/24 02:03:58
nit: Please document lifetime expectations for thi
bcwhite
2016/03/24 14:22:34
Done.
bcwhite
2016/03/24 14:22:34
Done.
| |
56 | 65 |
57 bool operator==(const Iterator& rhs) const { return last == rhs.last; } | 66 // As above but resuming from the |starting_after| reference. The first call |
58 bool operator!=(const Iterator& rhs) const { return last != rhs.last; } | 67 // to GetNext() will return the next object found after that reference. The |
68 // reference must be to an "iterable" object; references to non-iterable | |
69 // objects (those that never had MakeIterable() called for them) will cause | |
70 // a run-time error. | |
71 Iterator(const PersistentMemoryAllocator* allocator, | |
72 Reference starting_after); | |
59 | 73 |
60 void clear() { last = 0; } | 74 // Gets the next iterable, storing that type in |type_return|. The actual |
61 bool is_clear() const { return last == 0; } | 75 // return value is a reference to the allocation inside the allocator or |
76 // zero if there are no more. GetNext() may still be called again at a | |
77 // later time to retrieve any new allocations that have been added. | |
78 Reference GetNext(uint32_t* type_return); | |
79 | |
80 // Similar to above but gets the next iterable of a specific |type_match|. | |
81 // This should not be mixed with calls to GetNext() because any allocations | |
82 // skipped here due to a type mis-match will never be returned by later | |
83 // calls to GetNext() meaning it's possible to completely miss entries. | |
84 Reference GetNextOfType(uint32_t type_match); | |
62 | 85 |
63 private: | 86 private: |
64 friend class PersistentMemoryAllocator; | 87 // Weak-pointer to memory allocator being iterated over. |
88 const PersistentMemoryAllocator* allocator_; | |
65 | 89 |
66 Reference last; | 90 // The last record that was returned. |
67 uint32_t niter; | 91 std::atomic<Reference> last_record_; |
92 | |
93 // The number of records found; used for detecting loops. | |
94 std::atomic<uint32_t> record_count_; | |
95 | |
96 DISALLOW_COPY_AND_ASSIGN(Iterator); | |
68 }; | 97 }; |
69 | 98 |
70 // Returned information about the internal state of the heap. | 99 // Returned information about the internal state of the heap. |
71 struct MemoryInfo { | 100 struct MemoryInfo { |
72 size_t total; | 101 size_t total; |
73 size_t free; | 102 size_t free; |
74 }; | 103 }; |
75 | 104 |
76 enum : uint32_t { | 105 enum : uint32_t { |
77 kTypeIdAny = 0 // Match any type-id inside GetAsObject(). | 106 kTypeIdAny = 0 // Match any type-id inside GetAsObject(). |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 // Once an object is made iterable, its position in iteration can never | 233 // Once an object is made iterable, its position in iteration can never |
205 // change; new iterable objects will always be added after it in the series. | 234 // change; new iterable objects will always be added after it in the series. |
206 void MakeIterable(Reference ref); | 235 void MakeIterable(Reference ref); |
207 | 236 |
208 // Get the information about the amount of free space in the allocator. The | 237 // Get the information about the amount of free space in the allocator. The |
209 // amount of free space should be treated as approximate due to extras from | 238 // amount of free space should be treated as approximate due to extras from |
210 // alignment and metadata. Concurrent allocations from other threads will | 239 // alignment and metadata. Concurrent allocations from other threads will |
211 // also make the true amount less than what is reported. | 240 // also make the true amount less than what is reported. |
212 void GetMemoryInfo(MemoryInfo* meminfo) const; | 241 void GetMemoryInfo(MemoryInfo* meminfo) const; |
213 | 242 |
214 // Iterating uses a |state| structure (initialized by CreateIterator) and | |
215 // returns both the reference to the object as well as the |type_id| of | |
216 // that object. A zero return value indicates there are currently no more | |
217 // objects to be found but future attempts can be made without having to | |
218 // reset the iterator to "first". Creating an iterator |starting_after| | |
219 // a known iterable object allows "resume" from that point with the next | |
220 // call to GetNextIterable returning the object after it. | |
221 void CreateIterator(Iterator* state) const { CreateIterator(state, 0); }; | |
222 void CreateIterator(Iterator* state, Reference starting_after) const; | |
223 Reference GetNextIterable(Iterator* state, uint32_t* type_id) const; | |
224 | |
225 // If there is some indication that the memory has become corrupted, | 243 // If there is some indication that the memory has become corrupted, |
226 // calling this will attempt to prevent further damage by indicating to | 244 // calling this will attempt to prevent further damage by indicating to |
227 // all processes that something is not as expected. | 245 // all processes that something is not as expected. |
228 void SetCorrupt() const; | 246 void SetCorrupt() const; |
229 | 247 |
230 // This can be called to determine if corruption has been detected in the | 248 // This can be called to determine if corruption has been detected in the |
231 // segment, possibly my a malicious actor. Once detected, future allocations | 249 // segment, possibly my a malicious actor. Once detected, future allocations |
232 // will fail and iteration may not locate all objects. | 250 // will fail and iteration may not locate all objects. |
233 bool IsCorrupt() const; | 251 bool IsCorrupt() const; |
234 | 252 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 | 376 |
359 private: | 377 private: |
360 scoped_ptr<MemoryMappedFile> mapped_file_; | 378 scoped_ptr<MemoryMappedFile> mapped_file_; |
361 | 379 |
362 DISALLOW_COPY_AND_ASSIGN(FilePersistentMemoryAllocator); | 380 DISALLOW_COPY_AND_ASSIGN(FilePersistentMemoryAllocator); |
363 }; | 381 }; |
364 | 382 |
365 } // namespace base | 383 } // namespace base |
366 | 384 |
367 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ | 385 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ |
OLD | NEW |