Procedura scheduler (interrupts i spinlock i bit busy)

Gdy się dobrze nad tym zastanowić, można dostrzec potrzebę, aby to funkcja switch_to zmieniała stan zadania (to z którego następuje przełączenie) dopiero po tym gdy jego stan zostanie zapisany w pamięci. Rzeczywiście tak jest wykonując funkcję switch_to (specjalną instrukcę ljmp powodującą przełączenie), mamy gwarancję, że w opisie zadanie z którego następuje przełączenie zostanie wyłączony pewien bit (bit busy) (natomiast w opisie zadania do którego następuje przełączenie bit busy zostanie włączony).

Zamieniając funkcję select_runnable na select_runnable_not_busy można zagwaranotować, że zadanie nie zostanie uruchomione na innym procesorze do momentu gdy faktycznie zostanie zatrzymane (bit busy wyłączony).

void scheduler()
{
 disable_interrupts();
 spinlock_lock(&scheduler_lock);
 struct task *new = select_runnable_not_busy_task(run_queue);
 current->state = RUNNABLE;
 new->state = RUNNING; /* zarezerwuj, aby inny procesor, nie wybral tego zadania */
 spinlock_unlock(&scheduler_lock);
 current = new;
 switch_to(new); 
 restore_interrupts();
}

To rozwiązanie jest poprawne.