thewrongchristian wrote:
I'm making a big presumption on how spin locks
should be implemented. Some of that is based on experience, I didn't have a reliable way of synchronising between a driver and its interrupt handlers, as my first spin lock implementation didn't disable interrupts and I'd deadlock when an interrupt handler tried to lock a spin lock already held by the interrupted code.
Looking through the forums, spin locks tend to be advised to be used with interrupts disabled.
But looking at the
Spinlock wiki page, no mention is made of interrupts.
Is this a hole in the wiki page?
You don't need to have interrups disabled all the time, but before attempting to take the spinlock you should disable interrupts, do the protected operation and then release the lock and enable interrupts. If taking the spinlock fails, it's ok to enable interrupts, execute a "yield" instruction and try again.
Generally, when programming for single core systems enable/disable interrupts is sufficient to protect & synchronize code with IRQs, but when there are multiple cores involved, every instance of enable/disable intterupts potentially needs to be replaced with spinlocks to be multicore safe.
Example of spinlock implementation for x86:
Code:
InitSpinlock MACRO spinlock
mov spinlock.sl_value,0
ENDM
RequestSpinlock MACRO spinlock
local rs_lock
local rs_get
local rs_done
local rs_pause
push ax
push cx
;
xor cx,cx
rs_lock:
mov ax,spinlock.sl_value
or ax,ax
je rs_get
;
sti
add cx,1
jnc rs_pause
;
CrashGate
rs_pause:
pause
jmp rs_lock
rs_get:
cli
inc ax
xchg ax,spinlock.sl_value
or ax,ax
je rs_done
;
jmp rs_lock
rs_done:
pop cx
pop ax
ENDM
ReleaseSpinlock MACRO spinlock
mov spinlock.sl_value,0
sti
ENDM