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 #include "base/metrics/persistent_memory_allocator.h" | 5 #include "base/metrics/persistent_memory_allocator.h" |
| 6 | 6 |
| 7 #include <assert.h> | 7 #include <assert.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 | 9 |
| 10 #if defined(OS_WIN) | 10 #if defined(OS_WIN) |
| (...skipping 1045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1056 // been written to disk and so is applicable to "flush". | 1056 // been written to disk and so is applicable to "flush". |
| 1057 int result = ::msync(const_cast<void*>(data()), length, | 1057 int result = ::msync(const_cast<void*>(data()), length, |
| 1058 MS_INVALIDATE | (sync ? MS_SYNC : MS_ASYNC)); | 1058 MS_INVALIDATE | (sync ? MS_SYNC : MS_ASYNC)); |
| 1059 DCHECK_NE(EINVAL, result); | 1059 DCHECK_NE(EINVAL, result); |
| 1060 #else | 1060 #else |
| 1061 #error Unsupported OS. | 1061 #error Unsupported OS. |
| 1062 #endif | 1062 #endif |
| 1063 } | 1063 } |
| 1064 #endif // !defined(OS_NACL) | 1064 #endif // !defined(OS_NACL) |
| 1065 | 1065 |
| 1066 //----- DelayedPersistentAllocation -------------------------------------------- | |
| 1067 | |
| 1068 // Forwarding constructors. | |
| 1069 DelayedPersistentAllocation::DelayedPersistentAllocation( | |
| 1070 PersistentMemoryAllocator* allocator, | |
| 1071 subtle::Atomic32* ref, | |
| 1072 uint32_t type, | |
| 1073 size_t size) | |
| 1074 : DelayedPersistentAllocation( | |
| 1075 allocator, | |
| 1076 reinterpret_cast<std::atomic<Reference>*>(ref), | |
| 1077 type, | |
| 1078 size, | |
| 1079 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.
| |
| 1080 DelayedPersistentAllocation::DelayedPersistentAllocation( | |
| 1081 PersistentMemoryAllocator* allocator, | |
| 1082 subtle::Atomic32* ref, | |
| 1083 uint32_t type, | |
| 1084 size_t size, | |
| 1085 size_t offset) | |
| 1086 : DelayedPersistentAllocation( | |
| 1087 allocator, | |
| 1088 reinterpret_cast<std::atomic<Reference>*>(ref), | |
| 1089 type, | |
| 1090 size, | |
| 1091 offset) {} | |
| 1092 DelayedPersistentAllocation::DelayedPersistentAllocation( | |
| 1093 PersistentMemoryAllocator* allocator, | |
| 1094 std::atomic<Reference>* ref, | |
| 1095 uint32_t type, | |
| 1096 size_t size) | |
| 1097 : DelayedPersistentAllocation(allocator, ref, type, size, 0) {} | |
| 1098 | |
| 1099 // Real constructor. | |
| 1100 DelayedPersistentAllocation::DelayedPersistentAllocation( | |
| 1101 PersistentMemoryAllocator* allocator, | |
| 1102 std::atomic<Reference>* ref, | |
| 1103 uint32_t type, | |
| 1104 size_t size, | |
| 1105 size_t offset) | |
| 1106 : allocator_(allocator), | |
| 1107 type_(type), | |
| 1108 size_(size), | |
| 1109 offset_(offset), | |
| 1110 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.
| |
| 1111 | |
| 1112 DelayedPersistentAllocation::~DelayedPersistentAllocation() {} | |
| 1113 | |
| 1114 void DelayedPersistentAllocation::MakeIterable() { | |
| 1115 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
| |
| 1116 } | |
| 1117 | |
| 1118 void* DelayedPersistentAllocation::Get() const { | |
| 1119 // 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.
| |
| 1120 // contents of the allocation in any way. | |
| 1121 Reference ref = reference_->load(std::memory_order_relaxed); | |
| 1122 if (!ref) { | |
| 1123 ref = allocator_->Allocate(size_, type_); | |
| 1124 if (!ref) | |
| 1125 return nullptr; | |
| 1126 | |
| 1127 // Store the new reference in its proper location using compare-and-swap. | |
| 1128 // Use a "strong" exchange to ensure no false-negatives since the operation | |
| 1129 // cannot be retried. | |
| 1130 Reference existing = 0; // Must be mutable; receives actual value. | |
| 1131 if (reference_->compare_exchange_strong(existing, ref, | |
| 1132 std::memory_order_relaxed, | |
| 1133 std::memory_order_relaxed)) { | |
| 1134 if (make_iterable_) | |
| 1135 allocator_->MakeIterable(ref); | |
| 1136 } else { | |
| 1137 // Failure indicates that something else has raced ahead, performed the | |
| 1138 // 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.
| |
| 1139 // and use the other one instead. | |
| 1140 DCHECK_EQ(type_, allocator_->GetType(existing)); | |
| 1141 DCHECK_LE(size_, allocator_->GetAllocSize(existing)); | |
| 1142 allocator_->ChangeType(ref, 0, type_, /*clear=*/false); | |
| 1143 ref = existing; | |
| 1144 } | |
| 1145 } | |
| 1146 | |
| 1147 char* mem = allocator_->GetAsArray<char>(ref, type_, size_); | |
| 1148 if (!mem) { | |
| 1149 // This should never happen but be tolerant if it does as corruption from | |
| 1150 // the outside is something to guard against. | |
| 1151 NOTREACHED(); | |
| 1152 return nullptr; | |
| 1153 } | |
| 1154 return mem + offset_; | |
| 1155 } | |
| 1156 | |
| 1066 } // namespace base | 1157 } // namespace base |
| OLD | NEW |