类UNIX系统的原子操作汇编版本

“最轻量级的锁”,通常也叫”原子操作”,之所以加引号是因为他们在汇编级别并不是原子操作,是用多条指令完成的,这些操作大多都是利用CPU支持的汇编指令.在某些构架过时的CPU体系结构上,它们应该是用比较重量级的线程内锁实现的吧(我的猜测).
最常见的原子操作有Compare and Exchange,Self Increase/Decrease等等
80486 CPU相关指令:
LOCK:这是一个指令前缀,在所对应的指令操作期间使此指令的目标操作数指定的存储区域锁定,以得到保护。
XADD:先交换两个操作数的值,再进行算术加法操作。多处理器安全,在80486及以上CPU中支持。
CMPXCHG:比较交换指令,第一操作数先和AL/AX/EAX比较,如果相等ZF置1,第二操作数赋给第一操作数,否则ZF清0,第一操作数赋给AL/AX/EAX。多处理器安全,在80486及以上CPU中支持。
XCHG:交换两个操作数,其中至少有一个是寄存器寻址.其他寄存器和标志位不受影响.
80486以上都支持这四个操作,因此当今几乎100%CPU都支持这两个指令,也能由此用标准C和C++写出一系列几乎可以跨平台的”原子操作”函数和Lock-Free数据结构和算法.
64位平台也有一系列的相关指令,当然他们也有以上提到的指令,其下的64位原子操作函数应该和32位的分开(要问为什么?我现在告诉你恐怕你印象不深,接着看这一系列吧),而道理完全一样.因此,不存在跨CPU体系结构的问题)
“原子操作”函数:
由以上提供的几个汇编指令,我们可以做出以下实现,这些都是最常用的原语.
比较后交换
long __stdcall CompareExchange(long volatile* Destination,long Exchange,long Comperand)
{
   __asm
   {
      mov     ecx
, Destination;
      mov     edx, Exchange;
      mov     eax, Comperand;
      lock cmpxchg [ecx], edx;
   }
}
交换
long __stdcall Exchange(long volatile* Target,long Value)
{
   __asm
   {
      mov      ecx
, Target;
      mov      edx, Value;
label:
      lock cmpxchg [ecx], edx;//加
      jnz      short label;
   }
}
自减
long __stdcall Decrement(long volatile* Addend)
{
   __asm
   {
      mov     ecx
, Addend;
      mov     eax, 0FFFFFFFFh;//-1
      lock xadd [ecx], eax; //加-1
      dec     eax;
   }
}
自增
long __stdcall Increment(long volatile* Addend)
{
   __asm
   {
      mov      ecx
, Addend;
      mov      eax, 1;
      lock xadd [ecx], eax; //加
      inc      eax;
   }
}
相加后交换
long __stdcall ExchangeAdd(long volatile* Addend,long Value)
{
   __asm
   {
      mov      ecx
, Addend;
      mov      eax, Value;
      lock xadd [ecx], eax;
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值