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

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

Issue 2709113003: Clear memory in a predictable and atomic manner when changing type. (Closed)
Patch Set: rebased Created 3 years, 9 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 | « base/metrics/persistent_memory_allocator.h ('k') | 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 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 // If clearing the memory, first change it to the "transitioning" type so 533 // If clearing the memory, first change it to the "transitioning" type so
534 // there can be no confusion by other threads. After the memory is cleared, 534 // there can be no confusion by other threads. After the memory is cleared,
535 // it can be changed to its final type. 535 // it can be changed to its final type.
536 if (!block->type_id.compare_exchange_strong( 536 if (!block->type_id.compare_exchange_strong(
537 from_type_id, kTypeIdTransitioning, std::memory_order_acquire, 537 from_type_id, kTypeIdTransitioning, std::memory_order_acquire,
538 std::memory_order_acquire)) { 538 std::memory_order_acquire)) {
539 // Existing type wasn't what was expected: fail (with no changes) 539 // Existing type wasn't what was expected: fail (with no changes)
540 return false; 540 return false;
541 } 541 }
542 542
543 // Clear the memory while the type doesn't match either "from" or "to". 543 // Clear the memory in an atomic manner. Using "release" stores force
544 memset(const_cast<char*>(reinterpret_cast<volatile char*>(block) + 544 // every write to be done after the ones before it. This is better than
545 sizeof(BlockHeader)), 545 // using memset because (a) it supports "volatile" and (b) it creates a
546 0, block->size - sizeof(BlockHeader)); 546 // reliable pattern upon which other threads may rely.
547 volatile std::atomic<int>* data =
548 reinterpret_cast<volatile std::atomic<int>*>(
549 reinterpret_cast<volatile char*>(block) + sizeof(BlockHeader));
550 const uint32_t words = (block->size - sizeof(BlockHeader)) / sizeof(int);
551 DCHECK_EQ(0U, (block->size - sizeof(BlockHeader)) % sizeof(int));
552 for (uint32_t i = 0; i < words; ++i) {
553 data->store(0, std::memory_order_release);
554 ++data;
555 }
547 556
548 // If the destination type is "transitioning" then skip the final exchange. 557 // If the destination type is "transitioning" then skip the final exchange.
549 if (to_type_id == kTypeIdTransitioning) 558 if (to_type_id == kTypeIdTransitioning)
550 return true; 559 return true;
551 560
552 // Finish the change to the desired type. 561 // Finish the change to the desired type.
553 from_type_id = kTypeIdTransitioning; // Exchange needs modifiable original. 562 from_type_id = kTypeIdTransitioning; // Exchange needs modifiable original.
554 bool success = block->type_id.compare_exchange_strong( 563 bool success = block->type_id.compare_exchange_strong(
555 from_type_id, to_type_id, std::memory_order_release, 564 from_type_id, to_type_id, std::memory_order_release,
556 std::memory_order_relaxed); 565 std::memory_order_relaxed);
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 995
987 // static 996 // static
988 bool FilePersistentMemoryAllocator::IsFileAcceptable( 997 bool FilePersistentMemoryAllocator::IsFileAcceptable(
989 const MemoryMappedFile& file, 998 const MemoryMappedFile& file,
990 bool read_only) { 999 bool read_only) {
991 return IsMemoryAcceptable(file.data(), file.length(), 0, read_only); 1000 return IsMemoryAcceptable(file.data(), file.length(), 0, read_only);
992 } 1001 }
993 #endif // !defined(OS_NACL) 1002 #endif // !defined(OS_NACL)
994 1003
995 } // namespace base 1004 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/persistent_memory_allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698