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
 
沒有留言:
張貼留言