Locking: compare and swap
Locking: compare and swap
; 來源: http://en.wikipedia.org/wiki/Spinlock
lock: ; The lock variable. 1 = locked, 0 = unlocked.
dd 0
spin_lock:
mov eax, 1
xchg eax, [lock] ; Atomically swap EAX register with lock variable.
test eax, eax
jnz spin_lock
ret
spin_unlock:
mov eax, 0 ; Set the EAX register to 0.
xchg eax, [lock] ; Atomically swap EAX register with lock variable.
ret ; The lock has been released.
Dennis: 要用cmpxchg 取代 xchg
Wayling:
- wiki的spin lock有問題是哪裡有問題呢?
- 參考資料:
Ben:
> 問題應該出在沒檢查目前的lock是不是已鎖定(lock=true) 再設定 lock,
> 因需同時比較lock值且設定它.
> (比較與資料交換若非保證在同一指令, 還是會有race condition 發生的可能)
> 這裡看到一個實作方式使用 gcc builtins 的函式
> http://stackoverflow.com/questions/6935442/x86-spinlock-using-cmpxchg
> Note that GCC has atomic builtins, so you don't actually need to use inline
> asm to accomplish this:
Jserv: 在 gcc-4.5 之後,對於 atomic builtins 有了較多的硬體架構支援,如 ARMv6+
(ldrex/strex),Android library 原本有若干 atomics macro,在新版 (應該在下個 AOSP 版本)
也改用 gcc builtins
> void spin_lock(int *p)
> {
> while(!__sync_bool_compare_and_swap(p, 0, 1));
> }
>
> void spin_unlock(int volatile *p)
> {
> asm volatile (""); // acts as a memory barrier.
> *p = 0;
> }
Jserv: memory barrier 還得考慮到 SMP,有對應的硬體指令。
Conversation: https://groups.google.com/d/topic/juluosdev/F73aSJnAB5I/discussion