Funkcja refill_freelist()
Nagłówek funkcji: void refill_freelist (int size);
gdzie size - rozmiar bufora, który chcemy pozyskać
Funkcja refill_freelist stanowi integralną część algorytmu getblk. Wywoływana jest ona w sytuacji, gdy szukany przez funkcję getblk bufor nie znajduje się w odpowiedniej kolejce mieszającej (hash_table) oraz kolejka wolnych buforów (free_list) odpowiedniego rozmiaru jest pusta.
Zadaniem funkcji refill_freelist jest pozyskanie buforów o rozmiarze size (podanym jako argument funkcji) i wstawienie ich do odpowiedniej kolejki wolnych buforów. Na tym działanie tej funkcji się kończy, a bufory są z kolejki pobierane przez funkcję getblk. Jednorazowe wywołanie funkcji refill_freelist nie pozyskuje jednego, lecz od razu większą ilość buforów (równą predefiniowanej stałej bdf.prm.b.un.refill). Dzieje się tak po to aby efektywność systemu nie zmniejszała się w sposób drastyczny. Gdyby funkcja pozyskiwała za każdym wywołaniem tylko po jednym buforze, to narzut związany z każdoraznowym wywołaniem byłby zbyt duży.
Funkcja działa według następującego algorytmu:
algorytm refill_freelist /* pozyskaj wolny blok */
WEJŚCIE: rozmiar bloku
WYJŚCIE: brak
{
while (jest wystarczająca ilość wolnej pamięci i nie stworzyliśmy jeszcze
wystarczającej liczby nowych buforów)
{
wywołujemy funkcję grow_buffers w celu pozyskania nowych buforów z wolnej
strony pamięci;
}
while (nie stworzyliśmy wystarczającej liczby nowych buforów)
{
wyznaczamy z kazdej kolejki lru kandydata - bufor, który był ostatnio najdawniej
używany spośród buforów, które nie są specjalnego typu (np. zaznaczone
do zapisu opóźnionego);
spośród kandydatów wyłaniamy zwycięzcę - bufor, który najdłużej pozostawał
nieużywany;
if (udało się wyłonić kandydata)
{
zwalniamy bufor zajmowany przez kandydata i dołączamy go do listy wolnych
buforów;
continue; /* powrót do pętli while */
}
if (jest o kilka stron wolnej pamięci więcej niż dopuszczalna minimalna ilość)
{
wywołujemy funkcję grow_buffers;
continue; /* powrót do pętli while */
}
if (procedura nie została wywołana przez proces bdflush i jest wystarczająca ilość brudnych buforów)
{
wywołujemy proces bdflush zapisujący brudne bufory na dysk;
continue; /* powrót do pętli while */
}
if (stworzyliśmy co najmniej jeden nowy bufor)
return; /* kończymy działanie funkcji - w celu ochrony zasobów systemowych */
próbujemy stworzyć nowe bufory wywołując grow_buffers z wyższym
priorytetem; zmniejszamy liczbę buforów, które chcemy stworzyć
}
} /* refill_freelist*/
Skomentowane źródła funkcji refill_freelist i jej pokrewnych