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

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

Issue 2634093002: Revert simplification of memory ordering that is causing TSAN errors. (Closed)
Patch Set: Created 3 years, 11 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 if (!block) { // Memory is corrupt. 211 if (!block) { // Memory is corrupt.
212 allocator_->SetCorrupt(); 212 allocator_->SetCorrupt();
213 return kReferenceNull; 213 return kReferenceNull;
214 } 214 }
215 215
216 // Update the "last_record" pointer to be the reference being returned. 216 // Update the "last_record" pointer to be the reference being returned.
217 // If it fails then another thread has already iterated past it so loop 217 // If it fails then another thread has already iterated past it so loop
218 // again. Failing will also load the existing value into "last" so there 218 // again. Failing will also load the existing value into "last" so there
219 // is no need to do another such load when the while-loop restarts. A 219 // is no need to do another such load when the while-loop restarts. A
220 // "strong" compare-exchange is used because failing unnecessarily would 220 // "strong" compare-exchange is used because failing unnecessarily would
221 // mean repeating some fairly costly validations above. This operation 221 // mean repeating some fairly costly validations above.
222 // is "relaxed" because the iterator has no other values to protect and
223 // the referenced object will be accessed via an "acquire" in GetAsObject.
224 if (last_record_.compare_exchange_strong( 222 if (last_record_.compare_exchange_strong(
225 last, next, std::memory_order_relaxed, std::memory_order_relaxed)) { 223 last, next, std::memory_order_acq_rel, std::memory_order_acquire)) {
226 *type_return = block->type_id.load(std::memory_order_relaxed); 224 *type_return = block->type_id.load(std::memory_order_relaxed);
227 break; 225 break;
228 } 226 }
229 } 227 }
230 228
231 // Memory corruption could cause a loop in the list. Such must be detected 229 // Memory corruption could cause a loop in the list. Such must be detected
232 // so as to not cause an infinite loop in the caller. This is done by simply 230 // so as to not cause an infinite loop in the caller. This is done by simply
233 // making sure it doesn't iterate more times than the absolute maximum 231 // making sure it doesn't iterate more times than the absolute maximum
234 // number of allocations that could have been made. Callers are likely 232 // number of allocations that could have been made. Callers are likely
235 // to loop multiple times before it is detected but at least it stops. 233 // to loop multiple times before it is detected but at least it stops.
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 // zero then something must have previously run amuck through memory, 629 // zero then something must have previously run amuck through memory,
632 // writing beyond the allocated space and into unallocated space. 630 // writing beyond the allocated space and into unallocated space.
633 if (block->size != 0 || 631 if (block->size != 0 ||
634 block->cookie != kBlockCookieFree || 632 block->cookie != kBlockCookieFree ||
635 block->type_id.load(std::memory_order_relaxed) != 0 || 633 block->type_id.load(std::memory_order_relaxed) != 0 ||
636 block->next.load(std::memory_order_relaxed) != 0) { 634 block->next.load(std::memory_order_relaxed) != 0) {
637 SetCorrupt(); 635 SetCorrupt();
638 return kReferenceNull; 636 return kReferenceNull;
639 } 637 }
640 638
639 // Load information into the block header. There is no "release" of the
640 // data here because this memory can, currently, be seen only by the thread
641 // performing the allocation. When it comes time to share this, the thread
642 // will call MakeIterable() which does the release operation.
641 block->size = size; 643 block->size = size;
642 block->cookie = kBlockCookieAllocated; 644 block->cookie = kBlockCookieAllocated;
643 block->type_id.store(type_id, std::memory_order_relaxed); 645 block->type_id.store(type_id, std::memory_order_relaxed);
644 return freeptr; 646 return freeptr;
645 } 647 }
646 } 648 }
647 649
648 void PersistentMemoryAllocator::GetMemoryInfo(MemoryInfo* meminfo) const { 650 void PersistentMemoryAllocator::GetMemoryInfo(MemoryInfo* meminfo) const {
649 uint32_t remaining = std::max( 651 uint32_t remaining = std::max(
650 mem_size_ - shared_meta()->freeptr.load(std::memory_order_relaxed), 652 mem_size_ - shared_meta()->freeptr.load(std::memory_order_relaxed),
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 925
924 // static 926 // static
925 bool FilePersistentMemoryAllocator::IsFileAcceptable( 927 bool FilePersistentMemoryAllocator::IsFileAcceptable(
926 const MemoryMappedFile& file, 928 const MemoryMappedFile& file,
927 bool read_only) { 929 bool read_only) {
928 return IsMemoryAcceptable(file.data(), file.length(), 0, read_only); 930 return IsMemoryAcceptable(file.data(), file.length(), 0, read_only);
929 } 931 }
930 #endif // !defined(OS_NACL) 932 #endif // !defined(OS_NACL)
931 933
932 } // namespace base 934 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698