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

你可能感兴趣的:(android)