从 C++ 内存模型的角度来看,这个 seqlock 实现正确吗?

问题描述 投票:0回答:1

我红色了这篇文章Seqlocks 可以与编程语言内存模型相处吗?

并发现其中一个示例(图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(...) { ... }
    // continues to use seq_cst or
    // acquire/release operations on data

Figure 6. Seqlock reader with acquire fence

这里假设在读取 seq0 时,与读取器和“最后一个”写入器进行同步,但内存模型并不能保证这一点。为此,我们必须在读取 seq1if seq1 == seq0 时强制 RMW 操作(例如 seq.fetch_add(0) 或 seq.cas(seq0, seq0))同步,因此读取 seq0 的时间与“最后一个”作者进行 同步 => 发生在之前

c++ memory-model
1个回答
0
投票
Cppref 内存顺序

同步

如果线程 A 中的原子存储是释放操作,则线程 B 中对同一变量的原子加载是获取操作,线程 B 中的加载读取线程 A 中的存储写入的值,然后线程 B 中的存储写入A 与线程 B 中的负载同步。

通过获取订单读取
seq0

就足以建立

synchronizes with
关系,不需要RMW
    

© www.soinside.com 2019 - 2024. All rights reserved.