我使用asm编写了我的atomic_inc以增加整数,它实际上用于引用共享对象的计数。 gcc 4.8.2 -fsanitize = thread报告数据竞赛,我终于发现它可能是由我的atomic_inc引起的。我不相信我的代码有一个与数据竞争有关的错误,这是tsan的误报吗?
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;
}
}
答案 0 :(得分:2)
你的部分问题是gcc没有查看asm。
问题的另一部分是volatile
不会使变量成为线程安全的。
鉴于__asm__
意味着你致力于gcc,为什么不使用gcc内在函数? (它们经过记录并经过充分测试,gcc将理解它们的语义。)
至于警告是否是误报,我不知道。安全的做法是假设问题是真的。 真的很难看到多线程代码中的问题(即使你知道他们在那里)。 (一旦我们使用已发布的互斥算法破解了一段非常聪明的代码,并使用简单的自旋锁替换它。这修复了失败,但我们永远无法找到为什么失败。 )
答案 1 :(得分:1)
正如其他人已经说过的那样,该工具无法在你的asm中看到。但无论如何你不应该这样做。 只需使用std :: atomic并完成它 - 这既是线程安全又可移植的,编译器知道如何优化它 - 与当前代码不同。