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

Unified Diff: base/metrics/persistent_memory_allocator.cc

Issue 2806403002: Support delayed allocations from persistent memory. (Closed)
Patch Set: fixed build problems Created 3 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 side-by-side diff with in-line comments
Download patch
Index: base/metrics/persistent_memory_allocator.cc
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc
index d381d8784d1094e1d883db24a6ce03eee6300e27..4f372b8ca113a5642bafed23959ac6ab594f420a 100644
--- a/base/metrics/persistent_memory_allocator.cc
+++ b/base/metrics/persistent_memory_allocator.cc
@@ -1063,4 +1063,95 @@ void FilePersistentMemoryAllocator::FlushPartial(size_t length, bool sync) {
}
#endif // !defined(OS_NACL)
+//----- DelayedPersistentAllocation --------------------------------------------
+
+// Forwarding constructors.
+DelayedPersistentAllocation::DelayedPersistentAllocation(
+ PersistentMemoryAllocator* allocator,
+ subtle::Atomic32* ref,
+ uint32_t type,
+ size_t size)
+ : DelayedPersistentAllocation(
+ allocator,
+ reinterpret_cast<std::atomic<Reference>*>(ref),
+ type,
+ size,
+ 0) {}
Alexei Svitkine (slow) 2017/04/12 17:04:24 Nit: Add empty lines between ctors to make it easi
bcwhite 2017/04/12 21:23:42 Done.
+DelayedPersistentAllocation::DelayedPersistentAllocation(
+ PersistentMemoryAllocator* allocator,
+ subtle::Atomic32* ref,
+ uint32_t type,
+ size_t size,
+ size_t offset)
+ : DelayedPersistentAllocation(
+ allocator,
+ reinterpret_cast<std::atomic<Reference>*>(ref),
+ type,
+ size,
+ offset) {}
+DelayedPersistentAllocation::DelayedPersistentAllocation(
+ PersistentMemoryAllocator* allocator,
+ std::atomic<Reference>* ref,
+ uint32_t type,
+ size_t size)
+ : DelayedPersistentAllocation(allocator, ref, type, size, 0) {}
+
+// Real constructor.
+DelayedPersistentAllocation::DelayedPersistentAllocation(
+ PersistentMemoryAllocator* allocator,
+ std::atomic<Reference>* ref,
+ uint32_t type,
+ size_t size,
+ size_t offset)
+ : allocator_(allocator),
+ type_(type),
+ size_(size),
+ offset_(offset),
+ reference_(ref) {}
Alexei Svitkine (slow) 2017/04/12 17:04:25 Nit: Add a DCHECK() on the ref ptr not being null?
bcwhite 2017/04/12 21:23:42 Done.
+
+DelayedPersistentAllocation::~DelayedPersistentAllocation() {}
+
+void DelayedPersistentAllocation::MakeIterable() {
+ make_iterable_ = true;
Alexei Svitkine (slow) 2017/04/12 17:04:24 How about the case where it was created already an
bcwhite 2017/04/12 21:23:42 It would be called when the object is created and
Alexei Svitkine (slow) 2017/04/21 15:14:16 Let's make it a ctor param them - to avoid confusi
bcwhite 2017/04/21 15:59:04 I like it better as a ctor parameter. Less confus
+}
+
+void* DelayedPersistentAllocation::Get() const {
+ // Relaxed operations is acceptable here because it's not protecting the
Alexei Svitkine (slow) 2017/04/12 17:04:25 Nit: is -> are
bcwhite 2017/04/12 21:23:42 Done.
+ // contents of the allocation in any way.
+ Reference ref = reference_->load(std::memory_order_relaxed);
+ if (!ref) {
+ ref = allocator_->Allocate(size_, type_);
+ if (!ref)
+ return nullptr;
+
+ // Store the new reference in its proper location using compare-and-swap.
+ // Use a "strong" exchange to ensure no false-negatives since the operation
+ // cannot be retried.
+ Reference existing = 0; // Must be mutable; receives actual value.
+ if (reference_->compare_exchange_strong(existing, ref,
+ std::memory_order_relaxed,
+ std::memory_order_relaxed)) {
+ if (make_iterable_)
+ allocator_->MakeIterable(ref);
+ } else {
+ // Failure indicates that something else has raced ahead, performed the
+ // allocation, and stored its reference. Purge the allocation just done
Alexei Svitkine (slow) 2017/04/12 17:04:25 Nit: "that was just done" as otherwise it's a bit
bcwhite 2017/04/12 21:23:42 Done.
+ // and use the other one instead.
+ DCHECK_EQ(type_, allocator_->GetType(existing));
+ DCHECK_LE(size_, allocator_->GetAllocSize(existing));
+ allocator_->ChangeType(ref, 0, type_, /*clear=*/false);
+ ref = existing;
+ }
+ }
+
+ char* mem = allocator_->GetAsArray<char>(ref, type_, size_);
+ if (!mem) {
+ // This should never happen but be tolerant if it does as corruption from
+ // the outside is something to guard against.
+ NOTREACHED();
+ return nullptr;
+ }
+ return mem + offset_;
+}
+
} // namespace base

Powered by Google App Engine
This is Rietveld 408576698