Opis funkcji wyszukujących strony w buforze stron

Do szybkiego rozsyłania oraz wyszukiwania danych w kubełkach tablicy mieszającej służy specjalna funkcja mieszająca: page_hash(). Funkcja ta jest zaimplementowana w postaci makra, które wraz z ,,wywoływaną'' w nim funkcją, wyznaczającą przesunięcie w tablicy mieszającej, przedstawiają się tak:

inline unsigned long 
_page_hashfn(struct address_space * mapping, unsigned long index)
{
#define i (((unsigned long) mapping)/  \
           (sizeof(struct inode) & ~ (sizeof(struct inode) - 1)))
#define s(x) ((x)+((x)>>PAGE_HASH_BITS)) \
        return s(i+index) & (PAGE_HASH_SIZE-1);

#undef i
#undef s
}

#define page_hash(mapping,index) \
                  (page_hash_table+_page_hashfn(mapping,index))

Zagmatwane, czyż nie?! Jednak, jeśli przyjąć, że wartością wyrażenia:
(sizeof(struct inode) &  (sizeof(struct inode) - 1))
jest pewna stała (nazwijmy ją: stała), to treść powyższych makr, możnaby zapisać w natępującym pseudokodzie:

page_hash(mapping, index) {
long wsk; /* wskaźnik na kubełek odpowiadający parze: (mapping, index) */
wsk = (mapping/stała + index);
wsk = wsk + (wsk div (ilość elementów w tablicy mieszającej));
wsk = wsk mod (ilość elementów w tablicy mieszającej);
wsk = page_hash_table + wsk;
return wsk;
}

Jak widać funkcja mieszająca operuje na trzech zmiennych, których znaczenie jest następujące:

mapping - jest wskaźnikiem na strukturę opisującą przestrzeń adresową pliku5. Ponieważ z każdym plikiem jest związana jedna taka struktura, więc dla danego pliku wskaźnik mapping będzie go jednoznacznie identyfikował.
index - jest przesunięciem (offsetem) w pliku pokazywanym przez mapping.
page_hash_table - tu używane jako adres początku tablicy mieszającej.

Teraz gdy już wiemy jak wygląda funkcja mieszająca, to możemy zająć się opisem wyszukiwania stron w buforze. Przebiega ono zgodnie z poniższym algorytmem:

  1. Wyznacz wartość funkcji mieszającej, czyli wskaźnik na odpowiedni kubełek.
  2. Mając mappingindex, sprawdź czy w wyznaczonym kubełku jest zamapowana szukana strona. Strona jest zamapowana, gdy na liście kubełka jest ramka, w nagłówku której odpowiednie pola są równe:
    (page->mapping == mapping)
    (page->index == index)
  3. Gdy znalazłeś szukaną ramkę, to zwróć do niej wskaźnik, w przeciwnym przypadku zwróć NULL.

Funkcja mieszająca jest zdefiniowana w pliku pagemap.h. Funkcje realizujące wyszukiwanie strony w buforze stron są zdefiniowane w pliku filemap.c. W szczególności warto zwrócić uwagę na:
__find_page_nolock - szuka strony w kubełku
__find_page_simple - uproszczone szukanie strony w kubełku (bez ustawiania bitu odniesienia do strony)


Tomasz Szymko 25 listopada 2001