我为32位系统做了一个无锁堆栈,使用了比较和交换头指针的classic 算法.为了防止ABA问题,我还必须存储一个单调递增的计数器,并将其与指针交换.在64位系统上,这意味着将计数器填充到指针的未使用的高位中.在32位系统中,这稍微容易一点,因为你可以使用32位指针,32位计数器,并将它们都放入AtomicU64中.
对于64位系统,您可以将填充指针存储为AtomicPtr.如果不屏蔽计数器位,它是无效的,但AFAIK不违反pointer provenance.对于一个32位的系统,你真的别无 Select ,只能使用AtomicU64,然后将它的一半转换为指针.这是Rust中的未定义行为,如果我理解正确的话.编译器做了正确的事情,但它仍然是UB.
我能看到的避免UB的唯一方法是用C语言实现整个代码,因为指针出处是doesn't apply there yet (PDF).或者在汇编语言中,谢天谢地,一个字节仍然只是一个字节.有没有其他方法来解决这个问题,在稳定或夜间 rust 病?
我很想把它作为图书馆出版,但如果它有UB,就没有人会用它了.
我真的希望有一种方法可以告诉编译器:这是一个来源未知的指针,它可以为任何东西起别名,不要插手.