Lock-free atomic operations in Android

在多线程环境中,对共享的变量的访问,可以使用基于Compare And Swap这种lock free的技术进行实现,这种实现的好处是效率高。下面是代码片段来自Android的system/core/libcutils /atomic.c(针对X86):
#elif defined(__i386__) || defined(__x86_64__)

void android_atomic_write(int32_t value, volatile int32_t* addr) {
int32_t oldValue;
do {
oldValue = *addr;
} while (android_atomic_cmpxchg(oldValue, value, addr));
}

int32_t android_atomic_inc(volatile int32_t* addr) {
int32_t oldValue;
do {
oldValue = *addr;
} while (android_atomic_cmpxchg(oldValue, oldValue+1, addr));
return oldValue;
}

int32_t android_atomic_dec(volatile int32_t* addr) {
int32_t oldValue;
do {
oldValue = *addr;
} while (android_atomic_cmpxchg(oldValue, oldValue-1, addr));
return oldValue;
}

int32_t android_atomic_add(int32_t value, volatile int32_t* addr) {
int32_t oldValue;
do {
oldValue = *addr;
} while (android_atomic_cmpxchg(oldValue, oldValue+value, addr));
return oldValue;
}

int android_atomic_cmpxchg(int32_t oldvalue, int32_t newvalue, volatile int32_t* addr) {
int xchg;
asm volatile
(
" lock; cmpxchg %%ecx, (%%edx);"
" setne %%al;"
" andl $1, %%eax"
: "=a" (xchg)
: "a" (oldvalue), "c" (newvalue), "d" (addr)
);
return xchg;
}

android_atomic_cmpxchg是使用GNU C嵌入汇编实现,使用X86提供的对CAS的原子支持的指令。
oldvalue放在eax寄存器中,newvalue放在ecx中,addr(pointer)放在edx中。cmpxchg指令首先比较addr指向的内存与oldvalue(eax),如果二者相等,将newvalue(ecx)放到addr所指向的内存中,同时设置Z标志1。setne与andl 指令的操作的结果很简单:如果Z标志被设置,则eax为0,否则为1。程序执行最终eax放到xchg变量里。下面对cmpxchg命令的解释。
[lock] (注:支持smp) cmpxchg reg(注:source operand), reg/mem(注:destination operand)
If (accumulator(eax) == destination)
{ ZF <-1; destination <- source; }
If (accumulator (eax)!= destination)
{ ZF <-0; accumulator <- destination; }

http://blog.sina.com.cn/s/blog_6074fcd20100g0ba.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值