原子比较和交换实现
Atomic compare and exchange implementation
我有以下代码片段用于比较和交换
18 static size_t compareAndExchange( volatile size_t* addr, size_t oldval, size_t newval )
19 {
20 size_t ret;
21 __asm__ volatile( "lock cmpxchgq %2, %1nt"
22 :"=a"(ret), "+m"(*addr)
23 : "r"(newval), "0"(oldval)
24 : "memory" );
25 return ret;
26 }
下面是比较和交换
的测试 4 struct node
5 {
6 struct node* next;
7 int locked;
8
9 node():next( 0 ), locked( false ) {}
10 };
11
12 int main()
13 {
14 struct node* head = 0;
15 struct node* temp = new struct node;
16
17 struct node* ret = reinterpret_cast< struct node* > (
18 AtomicUtils::compareAndExchange(
19 reinterpret_cast< volatile size_t*>( &head ),
20 0,
21 reinterpret_cast< size_t >( temp )
22 )
23 ) ;
24
25 std::cout<< "nExpected: Ret = " << 0 << "Found: " << 0 << std::endl;
26 std::cout<< "nExpected: head = " << temp << "Found: " << head << std::endl;
27 }
问题:
1)目前自动设置head的值,我通过reinterpret_cast将size_t**转换为size_t*指针来作弊。这看起来很丑。是否有更好的方法(也许是内联汇编的更好实现)来实现相同的效果?
2)为什么参数需要volatile限定符?
在c++中,可以使用模板:
template<typename T>
static T compareAndExchange( volatile T* addr, T oldval, T newval )
{
.... rest of code should remain the same ...
}
你的测试代码现在应该是:
node* ret = AtomicUtils::compareAndExchange(&head, 0, temp);
(我认为你知道std::atomic和它的成员,你只是把它作为一个学习练习[显然不使用它的其他原因,我看到])
gcc还支持内置原子(即编译器可以直接转换为机器代码的函数),其中之一是__sync_bool_compare_and_swap
。
在这里看到更多:https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html
编辑:如果你改变这个,你会注意到它是否出错了:
std::cout<< "nExpected: Ret = " << 0 << "Found: " << 0 << std::endl;
:
std::cout<< "nExpected: Ret = " << 0 << "Found: " << ret << std::endl;
Edit2:关于您的第二个问题,关于volatile
:您不需要它作为交换函数[除了__asm__
本身,因为这会阻止编译器优化它并可能改变指令的顺序等]。如果您打算将volatile T*
参数用于交换函数本身,您确实需要它,或者您需要将const_cast
去掉volatile
属性。
相关文章:
- 对象内部有大量数据容器,实现更高效的对象交换
- 实现交换/复制功能:有没有更好的方法
- 实现了用于滤波器设计的remez交换算法
- 交换对象不实现移动语义时的交换函数
- 在 C++11 中实现复制和交换习语的更好方法
- 替换C 中内置类型的交换实现
- 在低级别实现交换复制位时可能会出现什么问题
- 交换实现:效率和适用范围?
- 在复制和交换习惯用法中实现交换
- 交换接口的实现
- 字节交换方面的一般交换实现
- 在什么情况下,运算符=应该用左值/右值重载而不是复制和交换来实现
- 根据getcontext和setcontext实现交换上下文
- 如何在对象类型未知时实现交换函数
- std::sort 如何仅使用迭代器实现交换操作
- 使用 std::mutex 实现类交换
- 这是交换(多线程)的异常安全实现吗
- 用用户实现的交换来交换std::函数
- 原子比较和交换实现
- GCC 列表节点交换实现过于复杂