Home‎ > ‎中文OS開發資源‎ > ‎

Locking: compare and swap

Locking: compare and swap

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

Comments