【发布时间】:2016-08-12 09:15:54
【问题描述】:
维基百科为使用 x86 XCHG 命令的自旋锁提供的示例实现是:
; Intel syntax
locked: ; The lock variable. 1 = locked, 0 = unlocked.
dd 0
spin_lock:
mov eax, 1 ; Set the EAX register to 1.
xchg eax, [locked] ; Atomically swap the EAX register with
; the lock variable.
; This will always store 1 to the lock, leaving
; the previous value in the EAX register.
test eax, eax ; Test EAX with itself. Among other things, this will
; set the processor's Zero Flag if EAX is 0.
; If EAX is 0, then the lock was unlocked and
; we just locked it.
; Otherwise, EAX is 1 and we didn't acquire the lock.
jnz spin_lock ; Jump back to the MOV instruction if the Zero Flag is
; not set; the lock was previously locked, and so
; we need to spin until it becomes unlocked.
ret ; The lock has been acquired, return to the calling
; function.
spin_unlock:
mov eax, 0 ; Set the EAX register to 0.
xchg eax, [locked] ; Atomically swap the EAX register with
; the lock variable.
ret ; The lock has been released.
从这里https://en.wikipedia.org/wiki/Spinlock#Example_implementation
我不明白为什么解锁需要是原子的。怎么了
spin_unlock:
mov [locked], 0
【问题讨论】:
-
我同意
mov应该可以工作,特别是考虑到变量中只使用了最低有效位。 -
我想使用 XCHG 进行解锁会给
spin_unlock一个返回值,1 表示成功,0 表示错误,因为没有锁定。 -
问题实际上不是原子性——普通对齐的 32 位存储在 x86 上总是原子的——而是 order。
locked atomics(包括隐含的lockedxchg)在 x86 上具有总顺序,而普通存储仅具有发布一致性。当然,释放语义对于自旋锁来说就足够了,只要获取是使用locked atomic 完成的。 -
@HansPassant 我在该问题中看不到任何内容,也没有看到支持这一可疑说法的答案。
-
在
xchg上旋转是否理想?使用计数锁更多最好仅在负载上旋转,并且仅在您看到锁已解锁时才尝试获取锁。在xchg上旋转可能会延迟解锁器的xchg发生。如果您在锁被锁定时根本不写入锁,那么拥有锁的核心在尝试解锁时仍将拥有缓存线,对吧?
标签: assembly x86 synchronization spinlock