DescriptionCauses the processor’s LOCK# signal to be asserted during execution of the accompanying instruction (turns the instruction into an atomic instruction). In a multiprocessor environment, the LOCK# signal ensures that the processor has exclusive use of any shared memory while the signal is asserted.The LOCK prefix can be prepended only to the following instructions and only to those forms of the instructions where the destination operand is a memory operand: ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, CMPXCHG16B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG. If the LOCK prefix is used with one of these instructions and the source operand is a memory operand, an undefined opcode exception (#UD) may be generated. An undefined opcode exception will also be generated if the LOCK prefix is used with any instruction not in the above list. The XCHG instruction always asserts the LOCK# signal regardless of the presence or absence of the LOCK prefix.The LOCK prefix is typically used with the BTS instruction to perform a read-modify-write operation on a memory location in shared memory environment.The integrity of the LOCK prefix is not affected by the alignment of the memory field. Memory locking is observed for arbitrarily misaligned fields.在执行伴随的指令期间使处理器的LOCK#信号有效(将指令变为原子指令)。在多处理器环境中,LOCK#信号确保处理器在信号有效时独占使用任何共享存储器。LOCK前缀只能附加在下面的指令之前,并且只适用于那些目标操作数是内存操作数的指令格式:ADD,ADC,AND,BTC,BTR,BTS,CMPXCHG,CMPXCH8B,CMPXCHG16B,DEC,INC, NEG,NOT,OR,SBB,SUB,XOR,XADD和XCHG。如果LOCK前缀与这些指令之一一起使用,并且源操作数是内存操作数,则可能会生成未定义的操作码异常(#UD)。如果LOCK前缀与任何不在上述列表中的指令一起使用,也会产生未定义的操作码异常。无论是否存在LOCK前缀,XCHG指令都始终声明LOCK#信号。LOCK前缀通常与BTS指令一起使用,以在共享存储器环境中的存储器位置上执行读取 – 修改 – 写入操作。LOCK前缀的完整性不受存储器字段对齐的影响。内存锁定是针对任意不对齐的字段。
static __always_inline int atomic_cmpxchg(atomic_t *v, int old, int new)
{
return cmpxchg(&v->counter, old, new);
}
__cmpxchg(ptr, old, new, sizeof(*(ptr)))
__raw_cmpxchg((ptr), (old), (new), (size), LOCK_PREFIX)
({
__typeof__(*(ptr)) __ret;
__typeof__(*(ptr)) __old = (old);
__typeof__(*(ptr)) __new = (new);
switch (size) {
case __X86_CASE_B:
{
volatile u8 *__ptr = (volatile u8 *)(ptr);
asm volatile(lock "cmpxchgb %2,%1"
: "=a" (__ret), "+m" (*__ptr)
: "q" (__new), "0" (__old)
: "memory");
break;
}
case __X86_CASE_W:
{
volatile u16 *__ptr = (volatile u16 *)(ptr);
asm volatile(lock "cmpxchgw %2,%1"
: "=a" (__ret), "+m" (*__ptr)
: "r" (__new), "0" (__old)
: "memory");
break;
}
case __X86_CASE_L:
{
volatile u32 *__ptr = (volatile u32 *)(ptr);
asm volatile(lock "cmpxchgl %2,%1"
: "=a" (__ret), "+m" (*__ptr)
: "r" (__new), "0" (__old)
: "memory");
break;
}
case __X86_CASE_Q:
{
volatile u64 *__ptr = (volatile u64 *)(ptr);
asm volatile(lock "cmpxchgq %2,%1"
: "=a" (__ret), "+m" (*__ptr)
: "r" (__new), "0" (__old)
: "memory");
break;
}
default:
__cmpxchg_wrong_size();
}
__ret;
})
原文标题:对int变量赋值的操作是原子的吗?为什么?
文章出处:【微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。
全部0条评论
快来发表一下你的评论吧 !