multithreading - 多线程实现原子交换的原子增量?

  显示原文与译文双语对照的内容
106 3

假设我正在为CPU编写( 程序集) 代码,它的唯一的原子操作是无条件交换 --/sc,没有 compare-and-swap,只是普通交换。如果是这样的,那么可以使用交换操作执行原子增量/递减操作?

有一个相对简单的答案,即使用交换构建一个自旋锁,并用它提供一个普通的增量和减量。但这看起来很笨重,我知道如果,或者 min/sc可以用,可以以在没有锁的情况下完成。所以我想知道的是,如果没有使用锁的方式。

时间:原作者:0个回答

148 2

我不能想到另一种方法,只是因为你需要两个交换和比较来检测你是否允许进行。如果你没有compare-and-swap命令,则必须使用循环交换和比较来实现它:

; Emulate atomic add/sub with atomic swap.
; On entry:
; r0 contains address of variable
; r1 contains value to add or subtract.
mutex: defw 0 ; mutual exclusion semaphore (0=free, 1=busy).
chng: push r2 ; save variables.
 ld r2,1 ; claiming value.
spin: swap r2,(mutex) ; atomic swap (sounds like a good name for a band).
 bnz spin ; loop until you have it.
 add (r0),r1 ; emulated atomic change.
 swap r2,(mutex) ; free mutex for everyone else.
 pop r2 ; restore registers.
 ret

如果你在代码中的许多地方做它,它只是真正的klunky 。我经常发现,将'klunky'代码隔离到函数( 如上所述) 使得它更少 klunky,因为那些代码段看起来比较简单:

myvar: defw 0
 : : : : :
 ld r0,myvar
 ld r1,1 ; increment
 call chng

或者,如果你希望代码更简单,请提供单独的incrdecr 函数:

; Emulate atomic incr/decr with emulated atomic change.
; On entry:
; r0 contains address of variable
incr: push r1 ; save registers.
 ld r1,1 ; increment.
 call chng ; do it.
 pop r1 ; restore registers.
 ret
decr: push r1 ; save registers.
 ld r1,-1 ; decrement.
 call chng ; do it.
 pop r1 ; restore registers.
 ret

然后你的代码序列将变为:

 ld r0,myvar
 call incr

或者,如果你能做 MACROS,一个更简单的:

atincr: defm ; do this once to define macro
 ld r0,&1
 call incr
 endm
 atincr myvar ; do this in your code, as much as you like.
原作者:
136 3

如果你的CPU是单核比你使用这种方式,ocurse没有 swaping,但你必须小心。以下是simpe的案例:

//incrementing of variable
cli//disable interrupts if we aren't on high priviliegied code execution level
//perform non atomic increment of variable
sti//enable interrupts if we aren't on high priviliegied code execution level
//reading variable
cli//disable interrupts if we aren't on high priviliegied code execution level
//perform non atomic read operation
sti//enable interrupts if we aren't on high priviliegied code execution level

这种方法像锁一样工作,但它更聪明,更快。这种方法的唯一缺点是可以能的CPU中断延迟,但是如果在禁用中断的代码短于这里延迟 normaly 。

原作者:
...