arm 版 在 arch/arm/include/asm : atomic.h:
static inline int atomic_add_unless(atomic_t *v, int a, int u)
{
int c, old;
c = atomic_read(v);
while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
c = old;
return c != u;
}
然後 cmpxchg 是
static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
{
unsigned long oldval, res;
smp_mb();
do {
__asm__ __volatile__("@ atomic_cmpxchg\n"
"ldrex %1, [%3]\n"
"mov %0, #0\n"
"teq %1, %4\n"
"strexeq %0, %5, [%3]\n"
: "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
: "r" (&ptr->counter), "Ir" (old), "r" (new)
: "cc");
} while (res);
smp_mb();
return oldval;
}
就是 swp. armv6 版.所以重點在
atomic_cmpxchg((v),c , c+a))
關於 atomic 的操作,可以看 Documentation/atomic_ops.txt
Semantics and Behavior of Atomic and Bitmask Operations這個 documsnt 的說明好像跟實做一饃一樣。
atomic_t 宣告在 linux/types.h
typedef struct {
int counter;
} atomic_t;
宣告後,要初始化: (atomic.h)
#define ATOMIC_INIT(i) { (i) }
這一篇說得很清楚喔: http://blog.roodo.com/use_the_force/archives/3420371.html
沒有留言:
張貼留言