5.3 Minimalizacja zmian w jądrze czyli integracja preempt_disable() ze spinlockami:
Kod spinlocka, pierwsza wersja (i obecna dla UP):
#define spin_lock(lock) \
do { \
preempt_disable(); \
_raw_spin_lock(); \
} while (0)
#define spin_unlock(lock) \
do { \
_raw_spin_unlock(lock); \
preempt_enable(); \
} while (0)
#define spin_trylock(lock) \
({preempt_disable(); _raw_spin_trylock(lock) ? \
1 : ({preempt_enable(); 0;});})
Kod spinlocka, poprawiona wersja dla SMP
#define spin_lock(lock) \
do { \
preempt_disable(); \
if (unlikely(!_raw_spin_trylock(lock))) \
__preempt_spin_lock(lock); \
} while (0)
void __preempt_spin_lock(spinlock_t *lock)
{
if (preempt_count() > 1) {
_raw_spin_lock(lock);
return;
}
do {
preempt_enable();
while (spin_is_locked(lock))
cpu_relax();
preempt_disable();
} while (!_raw_spin_trylock(lock));
}
Własna definicja __preempt_spin_lock() (z pętla) umożliwia wywłaszczenie procesu
oczekującego na spinlock