Temat główny: ZARZĄDZANIE PAMIĘCIĄ
Podtematy: Zajmowanie bloków pamięci - get_free_pages, Zwalnianie bloków pamięci - free_pages
Autor: Robert Popławski, nr indeksu: 181287

1  get_free_pages() - przydzielanie spójnych obszarów pamięci

1.1  Algorytm bliźniaków

Aby zminimalizować fragmentację zewnętrzną Linuks implementuje algorytm bliźniaków (zwany również algorytmem "buddy"). Ten algorytm operuje jedynie blokami pamięci o rozmiarach będących potęgami 2, ponadto w systemie bliźniaków dla każdego takiego obszaru istnieje dokładnie jeden obszar o tym samym rozmiarze, zwany obszarem bliźniaczym. Jeśli przyjmiemy, że nasza pamięć to blok 2^i stron i zaczniemy ją dzielić na dwie równe części (i te części dalej dzielić w ten sam sposób - aż otrzymamy bloki o rozmiarze jednej strony) to za każdym razem dzieląc blok o rozmiarze 2^j stron będziemy otrzymywać dwa bloki o rozmiarze 2^(j-1) stron - te dwa bloki to właśnie bloki bliźniacze. Oto algorytm przydzielania pamięci:

Przydziel blok pamięci o rozmiarze 2 ^ ORDER:

1:  na liście wolnych bloków znajdź najmniejszy blok BLOK o rozmiarze nie mniejszym niż 2 ^ ORDER i usuń go z listy wolnych bloków
2:  while (rozmiar(BLOK) > 2 ^ ORDER) do
3:  {
4:     BLIZNIAK = pierwsza_połowa(BLOK);
5:     BLOK = druga_połowa(BLOK);
6:     dodaj BLIZNIAK do listy wolnych bloków
7:  }
8:  zwróć BLOK jako wynik

1.2  Specyfikacja funkcji i struktur pomocniczych

Oto nagłówek funkcji __get_free_pages() (mm/page_alloc.c):

  unsigned long __get_free_pages(int gfp_mask, unsigned long order)

Funkcja ta przyjmuje rozmiar bloku (2 ^ order) jaki ma przydzielić, oraz rodzaj bloku (gfp_mask). Jako wynik zwraca adres początku przydzielonego bloku lub 0 jeśli alokacja się nie powiodła. Ważniejsze wartości gfp_mask to: