从C++内存模型视角看,该Seqlock实现是否正确?
关于论文《Can Seqlocks Get Along With Programming Language Memory Models?》中seqlock实现的C++内存模型问题
我阅读了这篇论文,发现其中图6的示例从C++内存模型角度来看并不正确。
atomic<unsigned> seq; // seqlock representation // assume big enough to ignore overflow atomic<int> data1, data2; // protected by seq T reader() { int r1, r2; unsigned seq0, seq1; do { seq0 = seq.load(m_o_acquire); r1 = data1.load(m_o_relaxed); r2 = data2.load(m_o_relaxed); atomic_thread_fence(m_o_acquire); seq1 = seq.load(m_o_relaxed); } while (seq0 != seq1 || seq0 & 1); // do something with r1 and r2; } void writer(...) { unsigned seq0 = seq; while (seq0 & 1 || !seq.compare_exchange_weak(seq0, seq0+1)) {} data1 = ...; data2 = ...; seq = seq0 + 2; }
Figure 6. Seqlock reader with acquire fence
该实现假设读取seq0时,reader与“最后一个”writer之间存在synchronize-with关系,但C++内存模型并不能保证这一点。
要正确实现这一点,必须在读取seq1时通过RMW操作(例如seq.fetch_add(0)或seq.compare_exchange_weak(seq0, seq0))强制建立synchronize-with关系;只有当seq1 == seq0时,才能确保读取seq0时与“最后一个”writer之间存在synchronize-with关系,进而满足happens-before要求。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

