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 #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 |