ZADANIE 14 (12)





Zadanie



Oto zadanie poświęcone funkcji systemowej fork.

Wydawać by sie mogło, że nic się nie da tutaj wymyślić, gdyż
fork dobrze wykonuje swoją robotę. Można jednak usprawnić tą funkcję
w przypadku, gdy proces potomny wywołuje
jedną z funkcji z rodziny exec. W takim przypadku nie musi być kopiowana
żadna ze struktur vm_area_struct opisujaca pamieć wirtualną procesu. Odpowiada
to wywołaniu funkcji do_fork z ustawioną flagą CLONE_VM. Tak więc, chciałoby
się mieć nową funkcję, powiedzmy fork2, która wywoływałaby w ten sposób
do_fork, a którą byśmy używali w naszych programach testowych (zmiana funkcji
sys_fork w jądrze na pewno by zawiesiła system). Są na to dwie metody.

Sposób 1.

Stworzyć własną funkcję w standardowej bibliotece lib.c, ktora by korzystała
z funkcji systemowej sys_clone (sys_clone(0, SIGCLD | CLONE_VM)) Co prawda
dawniej istniała stadardowa funkcja C clone wywołująca sys_clone, ale zniknęła
z powodu złego działania.


Sposób 2.

Zmodyfikować istniejacą w źródłach jądra funkcję execve. Np. jeśli
jej pierwszym parametrem jest NULL wówczas dziala jak nasz fork2. Odpowiednia
zmiana funkcji w pliku process.c wygląda tak:

asmlinkage int sys_execve(struct pt_regs regs) {

int error;

char * filename;

/********************* poczatek dodanego kodu *****************/


if (!regs.ebx) {


return do_fork(SIGCHLD | CLONE_VM, regs.esp, regs);


}


/********************* koniec dodanego kodu ******************/


error = getname((char *) regs.ebx, &filename);

if (error) return error;

error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx,
regs);

putname(filename);

return error;


}

Osobiście polecam raczej drugi sposób, choć jest mniej elegancki. Kompilacja
biblioteki C jest równie czasochłonna jak jądra oraz przy tworzeniu wlasnej
funkcji wywołującej funkcję systemową trzeba stworzyć kilka plików bazujących
w dużej mierze na niezrozumiałych na pierwszy rzut oka makrach. Próbowałem
to uzyskać, ale się zniechęciłem - nie miałem pewności, czy będzie to działać.


Pozostaje ponownie skompilować jądro, a następnie zrobić jakiś eksperyment.
Np. porównać czasy wykonania programów zawierających fork i exec, dla normalnego
forka i fork2 (czyli dla naszego execve(NULL,NULL,NULL)).

Oczekiwane wyniki eksperymentu:

Skopiowanie listy i drzewa AVL struktur vm_area_strukt, ktore nam udało
się wyeliminować z tak wywołanej funkcji fork2, znacznie przyspieszy samą
operację tworzenia nowego procesu. Wydaje się jednak, że operacją dominującą
jest wywołanie funkcji exec. Mimo wszystko w sytuacji gdy proces-rodzic
jest dosyć duży, a sam plik uruchamiany w funkcji exec niewielki, możemy
uzyskać nawet niezłą poprawę szybkości takiego programu.

P.S. Wydawać by sie mogło, że to, co opisuję odpowiada w pewnym stopniu
istniejącej w unixowych systemach funkcji vfork. Otóż, nic takiego nie
ma miejsca, jak można przekonać się ze źródeł biblioteki libc.a funkcja
vfork dokładnie pokrywa sie z fork.

Autor: Michał Smoktunowicz





Wyszukiwarka

Podobne podstrony:
ZADANIE (12)
0000 Zadania 1 12
ZADANIE (12)
ZADANIE (12)
analiza finansowa przedsiebiorstw zadania (12 stron)
ZADANIE (12)
Zadania 12
ZADANIE (12)
Zadania?LKI 12
Zadania 01 12 2012
1696 przykladowe zadania na,rok 12
gm geograficzny szkolny zadania 2011 12
matura 12 odpowiedzi matematyka pp zadania zamkniete

więcej podobnych podstron