"lock cmpxchg"如何在装配中工作?
How does "lock cmpxchg" work in assembly?
>我遇到了这个旧的(GCC 低于 4.8.3 - 错误 60272(错误报告 https://gcc.gnu.org/ml/gcc-bugs/2014-02/msg01951.html。现在已修复此问题。但我对此有一个问题。我编译了以下代码片段
#include <atomic>
struct Node { Node* next; };
void Push(std::atomic<Node*>& head, Node* node)
{
node->next = head.load();
while(!head.compare_exchange_weak(node->next, node))
;
}
void Pop(std::atomic<Node*>& head){
for(;;){
Node* value=head.exchange(nullptr);
if(value){
delete value;
break;
}
}
}
跟:
g++ -S -std=c++11 -pthread -O3 test.cc -o test.S
生成的程序集具有以下内容(我只放置了相关部分(:
.....
4 .L4:
5 lock cmpxchgq %rsi, (%rdi)
6 jne .L6
7 rep ret
8 .p2align 4,,10
9 .p2align 3
10 .L6:
11 movq %rax, (%rsi)
12 jmp .L4
.....
这是我的问题。假设此代码与 2 个线程同时运行。对于 T1,第 5 行被执行,然后 T1 被中断,T2 执行一些可能会弹出队列以完成的操作。当操作系统重新调度 T1 时,它将从第 6 行恢复,其中有人应该在执行jne之前重新评估条件。但是,如果不重新评估,则可能导致内存损坏。我的想法是否正确?
cmpxchg 指令只有在与eax
匹配时才设置dst
。否则,它将跳转到更新eax
并重新启动循环L6
。锁定前缀允许独占访问当前指令的任何内存操作数。换句话说,这会以原子方式推动节点,直到它成功。该错误是因为他们最初没有检查结果。
相关文章:
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- "lock cmpxchg"如何在装配中工作?