[ Pobierz całość w formacie PDF ]
.Ostatnią, najprostszą fazą realizacji jest zmiana działaniainstrukcji read() i write().Definicja głównejczęści funkcjiwrite() dla systemu plików ext2 znajduje się w pliku"fs/ext2/file.c" (funkcja ext2_file_write()),zmiany najwygodniej jest wprowadzać właśnie tutaj.Funkcjaread()dla systemu plików ext2 nie została specjalnie zdefiniowana,struktura "file_operations" w polu określającym standardową funkcjęodczytu ma wartość "generic_file_read".Funkcja ta zdefiniowanajest w pliku "mm/filemap.c".Dobrym ćwiczeniem może byćzmiana tej wartości.W pliku "fs/ext2/file.c" znajdujesię definicja globalnej zmiennej "ext2_file_operations", będącejwersją struktury "file_operations" i definiującą operacjespecyficzne dla systemu plików ext2.Można zastąpić wartość"generic_file_read" przez "ext2_file_read" i poniżej zdefiniowaćwłasną wersję funkcji odczytującej.Powinna ona sprawdzać, czyplik jest szybkim plikiem konfiguracyjnym, i jeśli tak, realizowaćodpowiedni algorytm, a jeśli nie, wywoływać funkcję"generic_file_read" z odpowiednimi parametrami.Realizacja operacji read() i write()nie powinna sprawiaćwiększych trudności.Do kopiowania porcji danych pomiędzyobszarem użytkownika (bufor na argumenty i wynik) a jądrem(struktury utrzymywane przez jądro) można użyć funkcjimemcpy_tofs() oraz memcpy_fromfs() zdefiniowanych(inline) w pliku "include/asm-i386/segment.h".Testy, obserwacje i wnioskiPo zaimplementowaniu wyżej opisanego mechanizmu warto porównaćgo z innymi metodami synchronizacji procesów, np.z realizacjąna pamięci dzielonej i na plikach, badając czas, jaki zajmujezmiana i odczytanie wartości zmiennej przy tych trzech realizacjachopisanego problemu.W przypadku pamięci dzielonej należy wykorzystaćjeden proces i sprawdzić, jak duża jest strata na prędkościwynikająca z faktu, że musimy wywołać funkcję jądra.(Do razdołączonego bloku pamięci dzielonej można odwoływać siębezpośrednio, więc działanie powinno być tutaj szybsze).W przypadkuzwykłych plików porównywanie prędkości zapisu i odczytu przezjeden i ten sam proces nie ma oczywiście sensu, wynik tegoporównania jest z góry znany.Jednak w rzeczywistości procesyrealizujące dane zadanie nie zawsze działają jednocześnie.W najbardziej niekorzystnej z możliwych sytuacji, czasydziałania procesów są rozłączne i jądro za każdym razem,gdy jakiś proces zakończy działanie, niszczy struktury w pamięcii uaktualnia zawartość pliku konfiguracyjnego na dysku.Z tego punktu widzenia opisany mechanizm ma jednak pewne wadyw stosunku do zwykłych operacji na plikach, ponieważ wymagawielokrotnego budowania i niszczenia struktur w pamięci.Porównując prędkość działania opisanego mechanizmu ze zwykłymdziałaniem na plikach należy badać systemw takich właśnie warunkach.Opisaną sytuację można zasymulowac na jednym procesie, któryw pętli otwiera i zamyka plik konfiguracyjny.Z wyżej opisanych testów można wyciągnąć wnioskiodnośnie mocnych i słabych stron opisanego mechanizmu.Byćmoże godnym uwagi usprawnieniem byłaby modyfikacja jego działaniatak, aby po zamknięciu szybkiego pliku konfiguracyjnegojądro jeszcze przez pewien czas utrzymywało jego zawartośćw pamięci i dopiero wtedy, gdy przez ustalony odcinek czasunie ma do niego odwołań, zrzucało go na dysk.Implementacjatego usprawnienia i badanie jego skuteczności mogłabydostarczyć materiału do dalszych testów i być podstawą dodalszych wniosków.BibliografialPliki źródłowe Linuxa:lllinux/fs/read_write.clllinux/fs/ext2/file.clllinux/fs/ext2/buffer.clllinux/fs/fat/file.cllProjekt LabLinuxlAutor: Krzysztof Ostrowski
[ Pobierz całość w formacie PDF ]