参照元†
- アトミック値から指定した値を加算し、加算後の値を返す。
返り値†
/**
* atomic_add_return - add integer and return
* @v: pointer of type atomic_t
* @i: integer value to add
*
* Atomically adds @i to @v and returns @i + @v
*/
static inline int atomic_add_return(int i, atomic_t *v)
{
int __i;
#ifdef CONFIG_M386
unsigned long flags;
if (unlikely(boot_cpu_data.x86 <= 3))
goto no_xadd;
- プロセッサファミリが 3以下(386 以前のプロセッサ)の場合は、
xadd 命令がサポートされていない。
#endif
/* Modern 486+ processor */
__i = i;
asm volatile(LOCK_PREFIX "xaddl %0, %1"
: "+r" (i), "+m" (v->counter)
: : "memory");
- xaddl: xadd 命令(Exchange and Add)の 32ビット版である。
ロックプリフィクスと組み合わせるとアトミックな加算が実行できる。
- v->counter と i を交換して、合計を v->counter にロードする。
return i + __i;
- i は加算する前の v->counter の値が入っている。
- なお、この return にいたる前に、
別の誰かが v->counter を更新する可能性があるため、
return v->counter; と書くことはできない。
#ifdef CONFIG_M386
no_xadd: /* Legacy 386 processor */
local_irq_save(flags);
__i = atomic_read(v);
atomic_set(v, i + __i);
local_irq_restore(flags);
return i + __i;
#endif
}
コメント†