我的自旋锁实现如下所示,我不认为它会导致任何数据竞争,但是当我用-fsanitize = thread测试我的代码时,它报告spin_unlock有写数据竞争。怎么会发生这种情况?这是一个误报吗?
#define barrier() asm volatile("": : :"memory")
#define cpu_relax() asm volatile("pause\n": : :"memory")
static inline void spin_lock(volatile int *lock) {
while (1)
{
int i = 0;
if (!atomic_swap(lock, EBUSY)) return;
while (*lock) {
i++;
if (i == 4000) {
i = 0;
thread_yield();
}
cpu_relax();
}
}
}
static inline void spin_unlock(volatile int *lock) {
barrier();
*lock = 0;
}
atomic_swap是一个函数:
static inline int atomic_swap(volatile void *lockword, int value) {
unsigned long tmp;
int result;
__asm__ __volatile__ ("dmb" : : : "memory");
__asm__ __volatile__("@ atomic_swap\n"
"1: ldrex %0, [%2]\n"
" strex %1, %3, [%2]\n"
" teq %1, #0\n"
" bne 1b"
: "=&r" (result), "=&r" (tmp)
: "r" (lockword), "Ir" (value)
: "cc");
__asm__ __volatile__ ("dmb" : : : "memory");
return result;
}
答案 0 :(得分:0)
ThreadSanitizer不了解本土atomic_swap()
或barrier()
函数的语义。来自ThreadSanitizer FAQ:
问:支持哪些同步原语? TSan支持pthread同步原语,内置编译器原子操作(sync / atomic),llvm libc ++支持C ++操作(不是非常直接[原文如此]虽然测试过。
所以它不知道atomic_swap()
应该做什么以及ThreadSanitizer currently doesn't support memory fences之上。