Linux中的原子访问--来自深入理解Linux内核一书

80x86指令:

  1. 进行0次或1次对齐内存访问的汇编指令是原子的;(如short地址必须是2的倍数、int的地址必须是4的倍数等)
  2. 读-修改-写之间没有其他处理器占用内存总线,则此序列操作是原子的;
  3. 操作码前缀是lock字节(0xf0)的“读-修改-写”汇编语言指令即使在多处理器系统中也是原子的。lock前缀在实际运行过程中,由控制单元检查,并当检查到该前缀时,将“锁定”内存总线,直到指令执行完毕。因此,当加锁的指令执行时,其他处理器不能访问该内存单元;
  4. 操作码前缀是rep(0xf2,0xf3)的汇编语言指令不是原子的,这条指令强行让控制单元多次重复执行相同指令。控制单元在执行新的循环之前要检查挂起的中断;

其中lock可作用指令范围如下:(转自百度知道:https://zhidao.baidu.com/question/1370295334412831499.html

ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, XCHG

LOCK指令只有在目标操作数为内存地址时LOCK指令才会将该指令变为原子指令;

如果目标操作数不为内存则会产生UD(Undefined Opcode,未定义的指令)错误。

另外值得注意的是,部分编译器会将LOCK指令合法的编译在非前面提到的指令前(例如:LOCK MOV [DATA],EAX),但是在运行程序时会同样产生UD错误。

题外话:XCHG的其中一个操作数为内存时会自动插入LOCK指令,使其所需要的周期变得很长。

在Linux中提供了atomic_t类型和一些函数与宏;这些函数和宏作用于atomic_t类型变量,并当做单独的、原子的汇编语言指令来使用。在多处理器系统中,每条这样的指令都有一个lock前缀;

Linux原子操作如下:(内存屏障)

函数说明
atomic_read(v)返回*v
atomic_set(v, i)把*v设置为i
atomic_add(i, v)*v+=i
atomic_sub(i, v)*v-=i
atomic_sub_and_test(i, v)*v-=i,如果结果为0,则返回1;否则返回0
atomic_inc(v)*v+=1
atomic_dec(v)*v-=1
atomic_dec_and_test(v)*v-=1,如果结果为0,则返回1;否则返回0
atomic_inc_and_test(v)*v+=1,如果结果为0,则返回1;否则返回0
atomic_add_negative(i, v)*v+=i,如果结果为负,则返回1;否则返回0
atomic_inc_return(i, v)*v+=1,返回*v新值
atomic_dec_return(i, v)*v-=1,返回*v新值
atomic_add_return(i, v)*v+=i,返回*v新值
atomic_sub_return(i, v)*v-=i,返回*v新值

内存访问重排序,编译器优化可能将源代码中的指令顺序重排;

asm volatile("":::"memory");(内存屏障原语);在原语之后的操作执行之前,原语之前的操作已经执行完毕;告诉控制器,我对内存做了改变,不要优化

volatile字段禁止编译器把asm指令与程序中的其他指令重新组合。memory关键字强调编译器假定RAM中的所有内存单元已经被汇编语言指令修改。

Linux中的内存屏障:

mb() 适用于MP和UP的内存屏障;

rmb() 适用于MP和UP的读内存屏障;

wmb()  适用于MP和UP的写内存屏障;

smp_mb() 仅适用于MP的内存屏障

smp_rmb() 仅适用于MP的读内存屏障

smp_wmb() 仅适用于MP的写内存屏障

在80x86微处理器上,如果CPU支持lfence汇编指令,就把rmb展开为asm volatile("lfence"),否则就展开为asm volatile("lock; addl $0, 0(%%esp)":::"memory");lock前缀使这条指令成为优化屏障;

内存屏障或lock应用十分广泛,如spinlock, rw_lock等;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值