osdev.labedz.org

Procedura szeregująca

Procedura szeregująca scheduler jest wywoływana przez przerwanie zegarowe co określony interwał czasu. Jej parametrem jest wskaźnik na strukturę PROCESS_CONTEXT aktualnie przerwanego zadania (struktura ta jednak nie jest pełna - zawiera jedynie wartości rejestrów). Informacje do tej struktury pobierane są ze stosu programowego - kolejność odkładania rejestrów na stos przy wejściu do procedury obsługi przerwania zegarowego odpowiada kolejności pól rejestrów w strukturze PROCESS_CONTEXT.

void scheduler(PROCESS_CONTEXT *old_process);

Jeżeli procedura szeregująca zostanie wywołana podczas wykonywania innej procedury na poziomie jądra systemowego, nie zostanie podjęte żadne działanie, a kontrola wróci ponownie do przerwanej procedury. Jeżeli przerwany proces będzie procesem aplikacji, procedura szeregująca zapamięta jego kontekst w tablicy procesów.

Następnym krokiem wykonanym przez procedurę szeregującą jest uruchomienie procedury obsługi procesów uśpionych. Procesy uśpione są kontrolowane przez procedurę check_sleepyhead. W zależności od ilości czasu, który upłynął od ostatniego wywołania procedury szeregującej (przeważnie 1ms), procedura check_sleepyhead zmniejsza wartości zmiennej msleep zawartej w kontekście procesu o odpowiednią wartość. Jeżeli zmienna ta osiągnie wartość zerową, proces taki zostaje usunięty z kolejki procesów uśpionych i dodany do kolejki procesów gotowych do uruchomienia.

Procedura szeregująca uruchamia procesy z kolejki procesów gotowych według algorytmu szeregowania rotacyjnego (ang. round-robin). Ponieważ kolejka procesów gotowych ma strukturę zapętloną, następne zadanie do wykonania będzie wskazywane przez wskaźnik next w strukturze PROCES_QUEUE odpowiadającej aktualnie uruchomionego procesu.

Ostatnim zadaniem wykonywanym przez procedurę szeregującą jest uruchomienie wybranego procesu procedurą run_task, której argumentem jest kontekst procesu gotowego do uruchomienia.

void run_task(PROCESS_CONTEXT *task);