I read that on a system with 1 CPU and non preemtive linux kernel (2.6.x) a spin_lock call is equivalent to an empty call, and thus implemented that way.
I can't understand that: shouldn't it be equivalent to a sleep on a mutex? Even on non-preemtive kernels interrupt handlers may still be executed for example or I might call a function that would put the original thread to sleep. So it's not true that an empty spin_lock call is "safe" as it would be if it was implemented as a mutex.
Is there something I don't get?
Quoted from «Linux Device Drivers», by Jonathan Corbet, Alessandro Rubini and Greg Kroah-Hartman:
If a nonpreemptive uniprocessor system ever went into a spin on a lock, it would spin forever; no other thread would ever be able to obtain the CPU to release the lock (because it couldn't yield). Because of this, spinlock operations on uniprocessor systems without preemption enabled are optimized to do nothing, with the exception of the ones that change the IRQ masking status (in Linux, that would be
spin_lock_irqsave()
). Because of preemption, even if you never expect your code to run on an SMP system, you still need to implement proper locking.
If you're interested in a spinlock that can be taken by code running in interrupt context (hardware or software), you must use a form of spin_lock_*
that disables interrupts. Not doing so will deadlock the system as soon as an interrupt arrives while you have entered your critical section.