分类: LINUX
2013-04-09 14:23:54
硬件级的原子操作:在单处理器系统(UniProcessor)中,能够在单条指令中完成的操作都可以认为是“原子操作”,因为中断只发生在指令边缘。在多处理器结构中(Symmetric Multi-Processor)就不同了,由于系统中有多个处理器独立运行,即使能在单条指令中完成的操作也有可能受到干扰。在X86平台生,CPU提供了在指令执行期间对总线加锁的手段。CPU上有一根引线#HLOCK pin连到北桥,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。对于其他平台的CPU,实现各不相同,有的是通过关中断来实现原子操作(sparc),有的通过CMPXCHG系列的指令来实现原子操作(IA64)。本文主要探讨X86平台下原子操作的实现。
BT, BTS, BTR, BTC (mem, reg/imm)
XCHG, XADD (reg, mem / mem, reg)
ADD, OR, ADC, SBB (mem, reg/imm)
AND, SUB, XOR (mem, reg/imm)
NOT, NEG, INC, DEC (mem)
void __fastcall atomic_inc (volatile int* pNum)
{
__asm
{
lock inc dword ptr [ECX]
ret
}
}
static __inline__ void atomic_add(int i, atomic_t *v)
{
__asm__ __volatile__(
LOCK_PREFIX "addl %1,%0"
:"+m" (v->counter)
:"ir" (i));
}
#ifdef CONFIG_SMP
#define LOCK_PREFIX \
".section .smp_locks,\"a\"\n" \
" .align 4\n" \
" .long 661f\n" /* address */ \
".previous\n" \
"661:\n\tlock; "
#else /* ! CONFIG_SMP */
#define LOCK_PREFIX ""
#endif