ThreadSanitizer说我的spin_lock有数据竞赛,但如何

ThreadSanitizer says my spin_lock has data race, but how?

本文关键字:竞赛 数据 我的 spin lock ThreadSanitizer      更新时间:2023-10-16

我的自旋锁实现如下所示,我认为它不会导致任何数据竞争,但是当我使用 -fsanitize=thread 测试我的代码时,它会报告spin_unlock有写入数据竞赛。怎么会这样?是误报吗?

#define barrier() asm volatile("": : :"memory")
#define cpu_relax() asm volatile("pausen": : :"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_swapn"
    "1: ldrex   %0, [%2]n"
    "   strex   %1, %3, [%2]n"
    "   teq %1, #0n"
    "   bne 1b"
    : "=&r" (result), "=&r" (tmp)
    : "r" (lockword), "Ir" (value)
    : "cc");
    __asm__ __volatile__ ("dmb" : : : "memory");
    return result;
}

ThreadSanitizer不知道你家atomic_swap()barrier()函数的语义。从线程清理器常见问题解答:

问:支持哪些同步原语?TSan 支持 pthread 同步原语、内置编译器原子操作(sync/atomic)C++ llvm libc++ 支持的操作(尽管没有经过非常彻底的 [原文如此] 测试)。

所以它不知道atomic_swap()应该做什么,最重要的是,ThreadSanitizer目前不支持内存围栏。