1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "device/base/synchronization/one_writer_seqlock.h" 6 7 namespace device { 8 OneWriterSeqLock()9OneWriterSeqLock::OneWriterSeqLock() : sequence_(0) {} 10 ReadBegin(uint32_t max_retries) const11base::subtle::Atomic32 OneWriterSeqLock::ReadBegin(uint32_t max_retries) const { 12 base::subtle::Atomic32 version; 13 for (uint32_t i = 0; i <= max_retries; ++i) { 14 version = base::subtle::Acquire_Load(&sequence_); 15 16 // If the counter is even, then the associated data might be in a 17 // consistent state, so we can try to read. 18 if ((version & 1) == 0) 19 break; 20 21 // Otherwise, the writer is in the middle of an update. Retry the read. 22 // In a multiprocessor environment with short write time, thread yield is 23 // expensive and best be avoided during the first 10~100 iterations. 24 if (i > 10) 25 base::PlatformThread::YieldCurrentThread(); 26 } 27 return version; 28 } 29 ReadRetry(base::subtle::Atomic32 version) const30bool OneWriterSeqLock::ReadRetry(base::subtle::Atomic32 version) const { 31 // If the sequence number was updated then a read should be re-attempted. 32 // -- Load fence, read membarrier 33 return base::subtle::Release_Load(&sequence_) != version; 34 } 35 WriteBegin()36void OneWriterSeqLock::WriteBegin() { 37 // Increment the sequence number to odd to indicate the beginning of a write 38 // update. 39 base::subtle::Barrier_AtomicIncrement(&sequence_, 1); 40 // -- Store fence, write membarrier 41 } 42 WriteEnd()43void OneWriterSeqLock::WriteEnd() { 44 // Increment the sequence to an even number to indicate the completion of 45 // a write update. 46 // -- Store fence, write membarrier 47 base::subtle::Barrier_AtomicIncrement(&sequence_, 1); 48 } 49 50 } // namespace device 51