Be Book Kernel Kit Kernel Kit Indeks

Pojęcia obszarów

Obszar jest fragmentem pamięci wirtualnej. Jako taki, ma on wszystkie oczekiwane właściwości pamięci wirtualnej: ma on adres początkowy, rozmiar, adresy które zawiera są przylegające i mapowane do (prawdopodobnie nieciągłej) pamięci fizycznej. Cechy, które dostarcza obszar są takie, że ich nie dostaniesz używając "standardowej" pamięci:

Ponieważ obszary są wielkie - jedna strona, minimum - nie tworzysz ich dowolnie. Dwoma najbardziej nieodpartymi powodami do tworzenia obszaru są dwa pierwsze punkty opisane powyżej: by współdzielić dane pomiędzy różnymi aplikacjami i by zablokować pamięć wewnątrz RAM.

We wszystkich szczegółach traktujesz pamięć, którą daje Ci obszar dokładnie tak jak potraktowałbyś jakąkolwiek przydzieloną pamięć: Możesz czytać i zapisać ją przez manipulację wskaźnikiem albo przez standardowe funkcje takie jak memcpy() i strcpy(). Jedyną różnicą pomiędzy obszarami a pamięcią przydzieloną za pomocą funkcji malloc jest...

Identyfikatory (ID) obszaru i nazwy obszaru

Każdy obszar, który tworzysz jest oznaczony liczbą area_id:

Obszary mogą też być (luźno) identyfikowane przez nazwy:

Współdzielenie obszaru między aplikacjami

Dla wielorakich aplikacji aby współdzielić wspólny obszar, jedna z aplikacji musi utworzyć obszar, a inne aplikacje klon obszaru. Klonujesz obszar przez wywołanie funkcji clone_area(). . Funkcja bierze, jako jej ostatni argument area_id obszaru źródłowego i zwraca nową (unikalną) liczbę area_id. Wszystkie dalsze odniesienia do sklonowanego obszaru (w aplikacji klonującej) muszą być oparte na area_id który jest zwrócony przez clone_area().

Jak zatem aplikacja klonująca znajduje źródłowy area_id w pierwszym miejscu?

Zauważ, że nazwy obszaru nie są muszą by być unikalne, więc metoda z funkcją find_area() jest w sobie trochę niepewności. Ale może ona być zminimalizowana przez zręczne utworzenie nazwy.

Sklonowana pamięć

Pamięć fizyczna, która tkwi pod obszarem nigdy nie jest wprost kopiowana - na przykład, mechanizm obszaru nie wykonuje "kopii do zapisu". Jeżeli dwa obszary odnoszą się do tej samej pamięci z powodu klonowania, modyfikacja danych, która jest wprowadzona przez jeden obszar będzie widoczna w innym obszarze.

Blokowanie obszaru

Kiedy pracujesz z umiarkowanie dużymi ilościami danych, co jest tak częstym przypadkiem, że wolałbyś, aby dane pozostały w RAM, nawet jeżeli reszta twojej aplikacji musi być wymieniona na dysk. Argument do wywołania funkcji create_area() pozwala Ci deklarować schemat blokujący, który pragniesz zastosować do swojego obszaru, przez użycie jednej z następujących stałych:

Stała Znaczenie
B_FULL_LOCK Pamięć obszaru jest zablokowana wewnątrz RAM gdy obszar jest tworzony i nie będzie ona wymieniana na dysk.
B_CONTIGUOUS Nie tylko jest zablokowana pamięć obszaru w RAM, jest też zagwarantowane aby był on przyległym. Jest szczególnie - a być może wyłącznie - użyteczne dla projektantów pewnych typów sterowników urządzeń.
B_LAZY_LOCK Pozwala pojedynczym stronom pamięci aby były przeniesione do RAM w pierwotnej kolejności a następnie blokuje je.
B_NO_LOCK Strony nigdy nie sa blokowane, są one wymieniane na dysk lub z dysku wtedy gdy są potrzebne.
B_LOMEM Jest to specjalna stała, która jest używana dla obszarów, które potrzebują być zablokowane, przyległe i które leżą wewnątrz pierwszych 16MB pamięci fizycznej. Ludzie, którzy potrzebują tej stałej o co chodzi.

Zauważ, że blokowanie obszaru zasadniczo zmniejsza ilość RAM, która może być używana przez inne aplikacje a zatem powiększa prawdopodobieństwo wymiany. Tak więc nie powinieneś blokować jej po prostu dlatego, że jesteś chciwy. Ale jeżeli obszar, który blokujesz ma być współdzielony poomiędzy kilka innych aplikacji, albo jeżeli piszesz aplikację czasu rzeczywistego, która przetwarza wielkie porcje danych, wtedy to nadużycie blokowania może dać się uzasadnić.

Schemat blokowania jest ustawiany przez funkcję create_area() i jest potem niezmienny. Nie możesz ponownie zadeklarować zamka kiedy klonujesz obszar.

Informacja obszaru

Ostatecznie, używasz obszaru dla pamięci wirtualnej, którą on reprezentuje: Tworzysz obszar ponieważ chcesz trochę pamięci, do której możesz zapisać i z której możesz czytać dane. Te działania są wykonywane w zwykły sposób, przez odniesienia (referencje) do określonych adresów. Ustawianie wskaźnika na lokacji wewnątrz obszaru, i sprawdzanie, czy nie przekroczyłeś granic pamięci obszaru kiedy zwiększasz wskaźnik (podczas czytania albo zapisywania) jest realizowane na Twoją własną odpowiedzialność. Aby robić to właściwie, potrzebujesz znać adres początkowy obszaru i jego zasięg:

Ważnym punkt, co do area_info, jest to, że pole adresu address jest ważne tylko dla aplikacji, która tworzyła albo sklonowała obszar (innymi słowy, aplikacja, która utworzyła area_id, który z kolei był przekazany do get_area_info()). Chociaż pamięć, która leży pod obszarem jest globalna, adres, który dostajesz ze struktury area_info odnosi się do określonej przestrzeni adresowej.

Jeżeli jest tutaj jakieś pytanie czy określony area_id jest "miejscowy" albo "obcy," to możesz porównać pole area_info.team z zespołem twojego wątku.

Usuwanie obszaru

Kiedy twoja aplikacja kończy działanie, obszary (liczby area_id) które to utworzyła przez create_area() lub clone_area() są automatycznie unieważniane. Pamięć leżąca pod obszarem, jednak, nie jest koniecznie zwalniana. Pamięć obszaru jest zwalniana wtedy (i to od razu) gdy nie ma więcej obszarów, które odnoszą się do niej.

Możesz wymusić unieważnienie area_id przez przekazanie go do funkcji delete_area(). I znowu, leżąca pod spodem pamięć jest zwalniana tylko wtedy jeżeli twój obszar odnosi się do tej pamięc jako ostatni..

Usuwanie obszaru, czy to wprost przez delete_area(), czy dlatego, że Twoja aplikacja kończy działanie, nigdy nie dotyczy stanu innych obszarów, które były z niego klonowane.


Be Book Kernel Kit Kernel Kit Indeks

Be Book,
...w ślicznym HTML...
dla BeOS wydanie 5

Copyright © 2000 Be, Inc. Wszelkie prawa zastrzeżone.