Dalej...


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