ThreadSanitizer说我的Atomic Inc / Dec有数据竞赛,误报?

我写了我的atomic_inc增量使用asm整数,它实际上用于引用计数共享对象。 gcc 4.8.2 -sanitize =线程报告数据竞赛,我终于发现它可能是由我的atomic_inc造成的。 我不相信我的代码有一个与数据竞赛有关的bug,是否是由金灿的假阳性?

static inline int atomic_add(volatile int *count, int add) { __asm__ __volatile__( "lock xadd %0, (%1);" : "=a"(add) : "r"(count), "a"(add) : "memory" ); return add; } void MyClass::Ref() { // std::unique_lock<std::mutex> lock(s_ref); atomic_add(&_refs, 1); } void MyClass::Unref() { // std::unique_lock<std::mutex> lock(s_ref); int n = atomic_add(&_refs, -1) - 1; // lock.unlock(); assert(n >= 0); if (n <= 0) { delete this; } } 

你的问题的一部分是,海湾合作委员会不看在ASM里面。

你的问题的另一个部分是volatile不会使线程安全的变量。

鉴于__asm__意味着你致力于gcc,为什么不使用gcc内部函数呢? (他们被记录和测试,gcc会理解他们的语义。)

至于这个警告是否是误报,我不知道。 安全的做法是假设问题是真实的。 在多线程代码中很难看到问题(即使知道它们在那里)。 (一旦我们使用发布的互斥算法剔除了一个非常聪明的代码,并用一个简单的自旋锁代替它,这样就修复了失败,但是我们永远无法找到失败的原因

正如其他人已经表示,该工具无法看到你的内部。 但是你不应该这样做。 只要使用std :: atomic并且完成它 – 这是线程安全和可移植的,并且编译器知道如何优化它 – 不像当前的代码。