Avoid (one) spinlock deadlock
Avoid (one) spinlock deadlock
Posted Dec 8, 2005 21:08 UTC (Thu) by mingo (guest, #31122)In reply to: Avoid (one) spinlock deadlock by gottlieb
Parent article: FOSS.IN: A report
Linux kernel spinlocks have a couple of other twists as well.
The relevant code from include/asm-i386/spinlock.h is:
#define __raw_spin_lock_string \
"\n1:\t" \
"lock ; decb %0\n\t" \
"jns 3f\n" \
"2:\t" \
"rep;nop\n\t" \
"cmpb $0,%0\n\t" \
"jle 2b\n\t" \
"jmp 1b\n" \
"3:\n\t"
or:
repeat:
decrease by 1
if we reached 0, we got the lock
else keep looping until value <= 0
if value is 1 again then repeat
first we decrement, then we test until the counter has been - if we didnt succeed we keep polling the value without decreasing the value. Note we do not inrease the value back, we just poll the value until the counter goes 1 again. The owner of the lock writes 1 to the lock indiscriminately, thus undoing multiple decrease-by-1 effects, and signalling all waiters to try again. Furthermore, the 'rep;nop' is a 'take it easy' instruction on newer CPUs (it's a NOP on older CPUs) - this saves power and reduces the likelyhood of livelocks too.