[ Pobierz całość w formacie PDF ]
.Przydzial pamieci dla jadra.Zgodnie z poczatkowymi zalozeniami UNIX'a dynamiczny przydzial pamiecidla jadra nie byl przewidziany.Jadra posiadalo zarezerwowane tablice ostalych rozmiarach, ktorych polami gospodarowalo w zaleznosci od potrzeb.Linux, ktory bazuje na UNIX'ie, posiada organizacje mieszana.Pozostalowiekszosc tablic np.tablica procesow, jednoczesnie czesc struktur jestalokowana dynamicznie, korzystajac z wolnej pamieci dostepnej dla systemu.Procedury obslugujace przydzial pamieci dla jadra znajduja sie w pliku'linux/mm/kmalloc.c'.Sa to:void *kmalloc( size_t size, /* rozmiar szukanej pamieci */int priority /* rodzaj pamieci (DMA lub dowolna) */void kfree( void *__ptr /* adres zwalnianego obszaru */ )Jest to specyficzny rodzaj przydzialu pamieci, pamiec zorganizowanaza pomoca stron o ustalonym rozmiarze jest dodatkowo dzielona na blokio wielkosciac odpowiadajacych potedze dwojki, tak ze kazda strona zawierajednorozmiarowe bloki.Zadanie przydzialu jest zaokraglane do minimalnegobloku, w ktorym sie miesci.Maksymalnie jadro moze jednorazowo zarzadacprzydzielenia dla siebie 5 (pieciu) stron o rozmiarach zazwyczaj 4 lub8 kB.Kazdy obszar (jedna lub wiecej stron, gdy blok nie miesci sie w stronie)dolanczany do jadra posiada pole (struct page_descriptor) identyfikujacego, znajdujace sie zawsze na poczatku takiego obszaru.Pole to zajmuje16 bajtow.Podobnie kazdy blok posiada pole identyfikacyjne (struct block_header),rowniez znajdujace sie na jego poczatku i zajmujace 8 bajtow.Dzieki takiejorganizacji jadro majac adres poczatku wolnego bufora pamieci moze szybkodotrzec do jego pol identyfikacyjnych.struct page_descriptor {struct page_descriptor *next;struct block_header *firstfree; /* pierwszy wolny blok */int order; /* liczba wymaganych stron na blok */int nfree; /* liczba wolnych blokow w stronie */};struct block_header {unsigned long bh_flags; /* flagi okreslajace m.in.czy zajety */union {unsigned long ubh_length; /* dlugosc bloku, gdy zajety */struct block_header *fbh_next; /* nastepny blok, gdy wolny */} vp;};Do przechowywania danych o wolnych buforach sluzy struktura size_descriptor.struct size_descriptor {struct page_descriptor *firstfree;/* strony zawierajace bloki dostepne dla jadra */struct page_descriptor *dmafree;/* j.w.tylko pamiec z dostepem DMA np.uzywana przez urzadzenia zewnetrzne */int nblocks;/* ilosc blokow w stronie */int nmallocs;int nfrees;/* ilosc wolnych blokow */int nbytesmalloced;int npages;unsigned long gfporder;/* liczba stron potrzebnych do stworzenia jednego bloku (gdy blok jest wiekszyod strony) */};Kazdemu rozmiarowi bloku odpowiada pole (w tablicy sizes[ ]) zawierajaceliste stron dostepnych dla blokow o danej wielkoscistruct size_descriptor sizes[ ]Kazda pozycja w p.w.tablicy oznacza bloki o rozmiarach kolejno (rozmiarwraz z deskryptorem) 32, 64, 128, 252(!), 508(!), itd.Algorytm kmalloc(size,priority);1.znajdz odpowiednia pozycje w tablicy sizes[ ] (tj.minimalnyrozmiar bloku wystarczajacy na przydzial pamieci rozmiaru size).2.jesli size zbyt duzy zakoncz bledem.3.jesli brak strony na liscie stron odpowiedniego pola idz 7(no_bucket_page)4.jesli brak wolnego bloku na stronie idz 11 (not_free_on_freelist)5.zmniejsz liczbe blokow na stronie, ewentualnie przejdz donastepnej strony na liscie (gdy brak wolnych blokow), zamarkuj blok.6.zwroc adres wolnej pamieci.7.(no_bucket_page) zaalokuj jedna lub odpowiednio wiecejstron z przestrzeni dostepnej dotychczas dla programow uzytkownika.8.jesli brak wolnych stron w pamieci idz 10 (no_free_page)9.dopisz strone z jej wolnymi blokami do odpowiedniej pozycjiw tablicy sizes[ ], idz 5.10.(no_free_page) przeszukaj bufor zwalnianych przezjadro stron w poszukiwaniu jakiejkolwiek (uwaga1.strona zwalniana przezjadro nie musi byc odrazu oddana do przestrzeni uzytkownika, ale moze bycnajpierw przekazywana do tablicy kmalloc_cache[MAX_CACHE_ORDER=3].Dopieropo zapelnieniu pamieci podrecznej kolejne strony sa oddawane dla uzytkownika),jezeli znaleziono odpowiednia liczbe stron idz 9, wpp.wyjdz z bledem.11.(not_free_on_freelist) zglos blad w tablicy sizes[] (niewytlumaczalny), wyjdz.Algorytm kfree(_ptr)1.jesli _ptr==NULL wyjdz z bledem.2.sprawdz czy istnieja pola identyfikacyjne bloku i strony dlatego obszaru pamieci oraz czy sa sensowne, jesli nie - wyjdz z bledem.3.dopisz wolny blok do odpowiadajecej mu strony (listy wolnychblokow danej strony).4.znajdz odpowiadajaca mu pozycje w tablicy sizes[ ].5.jezeli na stronie nie bylo wczesniej wolnych blokow oraz niejest jeszcze zupelnie pusta dopisz ja do listy wolnych stron (sizes[ ]->firstfree/dmafree),wyjdz z procedury.6.jezeli strona jest zupelnie pusta zwolnij ja (patrz uwaga1).7.wyjdz.autor: Grzegorz Zaprzalek
[ Pobierz całość w formacie PDF ]