ARM V6
ARM V6中原子指令是:
SWP 指令
sem_wati:MOV R1,#0 LDR R0,=SEM SWP R1,R1,[R0] ;取出信号量,并设置其为0 CMP R1,#0 ;判断是否有信号 BEQ sem_wait ;若没有信号,则等待
raw_local_irq_save(flags) val = v->counter; v->counter = val += 1; raw_local_irq_restore(flags)
ARM V6 以后, V7, V8中
LDREX <Rt>,[Rn]STREX <Rd>,<Rt>,[Rn] ;STREX成功,Rd置0
static inline void atomic_add(int i, atomic_t *v) static inline void atomic_add(int i, atomic_t *v) { unsigned long tmp; int result; __asm__ __volatile__("@ atomic_addn" "1: ldrex %0, [%3]n" // 先读入counter " add %0, %0, %4n" // 再把counter+i " strex %1, %0, [%3]n" // 把counter再写到result的地址, 并且放返回值到tmp里面. " teq %1, #0n" // 检查tmp和0相等否 " bne 1b" // 如果不相等, 再重新来一次. 防止被其他的CPU或者其他的竞争条件. : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "Ir" (i) : "cc"); }
LDREX loads data from memory.If the physical address has the Shared TLB attribute, LDREX tags the physical address as exclusive access for the current processor, and clears any exclusive access tag for this processor for any other physical address.
Otherwise, it tags the fact that the executing processor has an outstanding tagged physical address.
STREX performs a conditional store to memory. The conditions are as follows:If the physical address does not have the Shared TLB attribute, and the executing processor has an outstanding tagged physical address, the store takes place, the tag is cleared, and the value 0 is returned in Rd.
If the physical address does not have the Shared TLB attribute, and the executing processor does not have an outstanding tagged physical address, the store does not take place, and the value 1 is returned in Rd. (如果物理地址没有在TBL中, 而且当前执行CPU没有一个outstanding tagged physical address, 那么这次store不发生, 并且返回1在Rd中).If the physical address has the Shared TLB attribute, and the physical address is tagged as exclusive access for the executing processor, the store takes place, the tag is cleared, and the value 0 is returned in Rd.
(如果物理地址已经有一个TLB的属性, 而且该物理地址已经被标识为exclusive access, 那么存储发生, 并且清掉TAG, 在Rd中返回0)