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:

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