c++ - 仅使用 8 字节 CAS 无锁? C++

标签 c++ c c++11 thread-safety atomic

我使用的 64 位 x86 系统限制为最多 8 个字节用于比较和交换操作。由于指针是 8 字节,我需要一个计数器来避免 ABA 问题,是否可以修改未用于存储计数器的指针的高 16 位?

pointer_as_dec = reinterpret_cast<uintptr_t>(&node); // Node address
pointer_as_dec+(1LLU<<48); // Initialize the counter in one of the upper bits

是否可以使用__sync_bool_compare_and_swap函数来存储修改后的指针地址?

最佳答案

好吧,这不能保证根据任何标准工作——您真正允许将指针转换为 int 的唯一事情是将其原封不动地转换回指针。但实际上,它可以在任何 x86_64 平台和几乎任何其他当前平台上运行。显然,您并不期望特定于 gcc、特定于 x86_64 的代码是可移植的。所以,这里没问题。

此外,uintptr_t 不是 supported types 之一对于 gcc 原子函数——但它与 unsigned long long int 完全兼容,也就是。 (如果您担心这一点,您可以随时添加第二个 Actor ……)所以,这里也没有问题。

与此同时,__sync_bool_compare_and_swap 并不关心您是否在那个 uintptr_t 中走私指针;就它而言,它只是一个无符号的 64 位整数。所以,这里没问题。

你真的能确定前 16 位总是空的吗?在 x86_64 linux 中,它们用于您的普通用户内存。它们可能用于指向内核内存或内存映射硬件的指针,并且它们可能不在其他 x86_64 系统上——但如果不是,它们将全部为 1。正如 Brendan 指出的那样,在没有 128 位 CAS 的 x86_64 硬件上运行的任何东西都可以得到保证。*因此,如果您需要指向此类系统的此类内存或端口,只需使用 15 位而不是 16 位。(即使那不是真的,假设你指向的是 64 位对齐的对象,你在指针的另一端也有 6 个空闲位,你可以使用它来代替/另外使用。)所以,不这里也有问题。


* 除非 AMD 或 Intel 或其他人决定更改虚拟地址大小并且还决定取消 128 位 CAS 的可能性极小......

关于c++ - 仅使用 8 字节 CAS 无锁? C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21274053/

相关文章:

C++11 右值两次调用析构函数

c - 有没有办法覆盖 C 中的 malloc/free 函数?

c++ - vim YouCompleteMe GoTo 不起作用

c++ - 如果增加一个等于 STL 容器的结束迭代器的迭代器会发生什么

c - 将指针添加到指针数组

c++ - 将当前模板用作模板参数之一的模板参数

c++ - 如何通过未定义类型定义元函数?

c++ - "multiple overloads"使用具有重复类型的模板类

c++ - std::async,std::promise 和 std::packaged_task 会阻塞主线程,它们是什么意思?

java - 仅使用 +、- 和递归检查数字是否为偶数