Oryginalny algorytm szeregowania w Linuxie, oprócz podstawowych zalet, takich jak prosta implementacja i gwarancja, że proces nie zostanie zagłodzony, ma jedną poważną wadę, którą jest mała odporność na duże obciążenie systemu - w rzeczywistości algorytm SCHED_OTHER zachowuje się jak algorytm typu Round-Robin, gdzie wszystkie procesy dostają równy kwant czasu na działanie, bez względu na charakterystykę ich działania (jedyny wpływ jaki można mieć na szeregowanie, to możliwość modyfikacji wartości nice procesu). Linux równo traktuje procesy - procesy wykonujące dużo obliczeń (tzw. compute-bound tasks), które są wywłaszczane nie są w żaden sposób karane, a procesy interaktywne (tzw. transput-bound tasks) oddające dobrowolnie procesor, nie są za to nagradzane. Więcej o szeregowaniu w Linuxie można przeczytać tutaj.
Zadanie polega na zaimplementowaniu uproszczonego wariantu algorytmu szeregowania stosowanego w Systemie V Release 4 (w skrócie SVR4).
W jądrze Unixa SVR4 wprowadzono podział na klasy szeregowania (wg ważności): procesów czasu rzeczywistego, procesów systemowych, procesów standardowych (time-shared). Dzięki podziałowi na klasy, implementacja jądra pozwala na łatwą modyfikację i dodawanie nowych algorytmów szeregowania. Ponieważ implementacja takiego mechanizmu wymagałaby znacznego nakładu mało naukowej pracy, przedmiotem zadania jest implementacja algorytmu szeregownia procesów typu time-shared. Algorytm został znacznie przez autora zadania uproszczony - w oryginale istnieje podział na niezależne kolejki priorytetowe (w każdej z kolejek znajdują procesy o tym samym priorytecie), pominięto też kilka innych szczegółów. Zainteresowanych odsyłam do żródła [1].
1. Z każdym procesem związane są następujące wartości:
2. Z każdą wartością efektywnego priorytetu związane są następujące parametry.
Wymienione parametry znajdują się w tablicy schedparam indeksowanej
priorytetem zwanej dalej tablicą szeregowania.
Przykład standardowych wartości w SVR4:
effective_pri | quantum | expire_pri | wakeup_pri | maxwait | promote_pri |
0 | 100 | 0 | 10 | 5 | 10 |
1 | 100 | 0 | 11 | 5 | 11 |
.... | .... | .... | .... | .... | .... |
59 | 10 | 49 | 59 | 5 | 59 |
3. Schemat podstawowych funkcji algorytmu:
szeregowanie: if (kolejka procesów gotowych nie jest pusta) for (każdy proces w kolejce procesów gotowych) wybierz proces o największej wartości effective_pri; else wybierz proces wymiany (idle); if (wybrany proces różny od bieżącego) ustaw sched_time w strukturze procesu; wznów wybrany proces; aktualizacja: if (bieżący proces wykorzystał swój czas) { effective_pri = user_pri + schedparam[dynamic_pri].expire_pri; przeszereguj procesy; } if (od czasu ostatniej modyfikacji minęła sekunda) { for (każdy proces w kolejce procesów gotowych) if (proces różny od bieżącego && czeka dłużej niż maxwait) effective_pri = user_pri + schedparam[dynamic_pri].promote_pri; zapamiętaj czas modyfikacji; } budzenie: effective_pri = user_pri + wakeup_pri; dodaj proces do kolejki procesów gotowych;