[OSy] Zadani 5. tematu semestralni ulohy

Martin Decky decky at d3s.mff.cuni.cz
Mon Jan 4 00:11:48 CET 2016


Vazeni kolegove,

v priloze tohoto emailu naleznete rozsirene zadani 5. semestralni ulohy 
z predmetu Operacni systemy. Prosim, venujte tomuto zadani pozornost i v 
tom pripade, ze mate v planu prijit na nejblizsi cviceni a resit 
prezencni ulohu -- zadani 5. prezencni ulohy se bude take tykat tematu 
systemovych volani a bude vyzadovat znalost latky z prednasky (pripadne 
z doporucene literatury, ktera je uvedena na konci rozsireneho zadani).

Specialne upozornuji, ze kod Kalista byl na mnohych mistech netrivialne 
upraven, aby mohl podporovat (byt velmi rudimentalne) spousteni 
uzivatelskych procesu. Neni mozna od veci, pokud si v nejakem vhodnem 
nastroji porovnate rozdily mezi zdrojovym stromem verze 0.9.5 a 0.9.6.

Pokud se rozhodnete implementovat rozsirene zadani 5. semestralni ulohy, 
tak sva reseni muzete odevzdavat az do 18. 1. 2016 (vcetne). Odevzdani 
provadejte opet tak, ze svou modifikaci Kalista (tj. vse, co je potreba 
ke spusteni, otestovani a ohodnoceni Vaseho reseni) zabalite do archivu 
(ZIP, TAR.BZ2 apod.) a poslete jako prilohu na emailovou adresu

     nswi004 at d3s.mff.cuni.cz

Opet DURAZNE APELUJEME, abyste vypracovani reseni nenechavali na 
posledni chvili a meli tak pripadne realnou moznost reagovat na nasi 
zpetnou vazbu k Vasemu reseni, Podrobneji viz zadani 1. ulohy [1].

V pripade libovolnych dotazu k zadani nebo k formalnim zalezitostem 
nevahejte vyuzit tento mailing list.


[1] https://d3s.mff.cuni.cz/pipermail/osy/2015-October/002164.html


S pozdravem

Martin Decky
-------------- next part --------------
========================================================================
                      Semestralni uloha z predmetu
                            Operacni systemy

                       Tema 5.: Systemova volani
                            Rozsirene zadani
========================================================================
Datum zverejneni zadani:  4. 1. 2016
Datum odevzdani reseni:  18. 1. 2016
------------------------------------------------------------------------

  Cilem 5. tematu semestralni ulohy je rozsirit jadro Kalisto o podporu
  behu uzivatelskych procesu. To zahrnuje predevsim infrastrukturu pro
  vytvareni a beh uzivatelskych procesu a pro systemova volani, ktera
  zpristupnuji relevantni funkce jadra uzivatelskym procesum. Zadani ma
  formu rozhrani, ktere je nutno naimplementovat, a je doplneno sadou
  jednotkovych testu, jimiz musi implementace uspesne projit.

  Pri vypracovani vychazejte z vyukoveho jadra Kalisto ve verzi 0.9.6,
  do ktereho doplnte chybejici funkcionalitu. Kalisto ve verzi 0.9.6 je
  k dispozici ke stazeni z URL:

    http://d3s.mff.cuni.cz/osy/download/kalisto-0.9.6.tar.bz2

  Pokud zadani nespecifikuje nejaky detail, je zavazne chovani, ktere
  ocekavaji testy. Pokud testy dane chovani netestuji, zadani si podle
  uvazeni dodefinujte a sve rozhodnuti zdokumentujte pomoci vhodnych
  komentaru ve zdrojovem kodu reseni.


Rozhrani systemovych volani --------------------------------------------

  Mechanismus systemovych volani umoznuje volat na strane uzivatelskeho
  prostoru sluzby jadra a predavat jim argumenty a na strane jadra psat
  obsluzne rutiny techto sluzeb.

  Pri implementaci tohoto mechanismu je obvykle kladen duraz na rozumnou
  efektivitu a rozumnou budouci rozsiritelnost o nove sluzby a jejich
  obsluzne rutiny. Za timto ucelem se pouzivaji ruzne programatorske
  abstrakce, ktere umoznuji snadno integrovat nove typy systemovych
  volani a jejich argumenty. Verejne uzivatelske funkce tedy nejsou
  primo systemovymi volanimi, ale pouze v ramci sve implementace
  pouzivaji jedno nebo vice systemovych volani. Podobne na strane jadra
  neni obsluha systemovych volani "zadratovana" primo do tela obsluzne
  rutiny vyjimky, ale pouziva se neprima vazba pomoci vhodne datove
  struktury (tabulky systemovych volani).

  Jde o chybu navrhu, pokud se systemova volani pouzivaji na takove
  sluzby a funkce, ktere mohou byt implementovany snadno primo
  v uzivatelskem prostoru. Pripadne chyby v jadernem kodu mohou totiz
  mit mnohem horsi nasledky nez chyby v uzivatelskem kodu a proto neni
  vhodne chapat jadro jako "sdilenou knihovnu", na kterou by mely
  uzivatelske procesy delegovat sve bezne funkce.

  Kvuli ochrane jadra pred chybami v uzitelskem kodu je take dulezite
  dusledne testovani spravnosti a konzistence argumentu systemovych
  volani predavanych z uzivatelskeho prostoru. Predevsim je nutne
  overovat, ze ukazatele na datove struktury ukazuji na korektne
  namapovanou pamet v ramci adresoveho prostoru volajiciho procesu (tj.
  pri manipulaci s touto pameti v jadre nemuze dojit k vyjimce,
  nemuze dojit k pristupu k pameti jineho procesu a nemuze dojit
  k nedovolenemu pristupu k pameti jadra). Je nutne kontrolovat
  i konzistenci vsech ostatnich argumentu a jejich chybne hodnoty
  indikovat chybovym navratovym kodem systemoveho volani, pripadne
  ukoncenim chybujiciho procesu.

  Cilem techto ochran je, aby chyba uzivatelskych procesu nemohla
  ohrozit stabilitu jadra a operacniho systemu jako takoveho.


Obecne pozadavky -------------------------------------------------------

  Nasledujici doporuceni odrazi pozadavky na uroven zdrojovych textu,
  ktere budou hodnoceny pri odevzdani reseni ulohy.

  - Vyhybejte se pouzivani numerickych konstant primo v kodu, nahradte
    je makry.

  - Pouzivejte prazdne radky a blokove komentare k oddeleni logickych
    casti kodu.

  - Pouzivejte vhodnym zpusobem mezery pro zprehledneni a usnadneni
    porozumeni kodu. Snazte se, aby styl vaseho kodu pokud mozno
    odpovidal stylu jiz existujiciho kodu.

  - Vyhybejte se psani prilis dlouhych funkci nebo funkci s prilis
    velkou urovni vnorenych bloku.

  - Vyhybejte se vytvareni zdrojovych souboru, ktere obsahuji
    nesouvisejici funkce, pripadne umistovani zdrojovych souboru do
    nevhodnych adresaru.

  - Pouzivejte makra ci inline funkce k nahrade slozitych podminkovych
    vyrazu.

  - Pouzivejte jednotny jazyk pro komentare.

  - Pouzivejte jednotny jazyk pro identifikatory funkci a promennych
    a pro nazvy souboru.

  - Pouzivejte systematicke identifikatory funkci a promennych.


Zadani ulohy -----------------------------------------------------------

  Po uspesne inicializaci jadra Kalisto 0.9.6 dojde ke spusteni jedineho
  uzivatelskeho procesu, jehoz binarni obraz je nahran spolecne
  s kernelem a dalsimi potrebnymi daty primo do pameti simulatoru. Tento
  uzivatelsky proces vyuziva uzivatelskou behovou infrastrukturu
  staticky linkovane knihovny librt.a.

  Start uzivatelskeho procesu vypada tak, ze jadro zacne provadet kod
  procesu od adresy, kde se nachazi vstupni bod behoveho prostredi
  knihovny librt.a, ktery provede nezbytnou inicializaci a zavola funkci
  main() uzivatelskeho procesu. Po navratu z funkce main() pak behove
  prostredi proces ukonci.

  V ramci knihovny librt.a naimplementujte nebo doplnte implementaci
  nasledujicich funkci. Uvedomte si, u kterych funkci je vhodne, aby
  jejich primarni logika byla implementovana pomoci systemoveho volani
  (napr. putc()), a u kterych funkci to naopak vhodne neni (napr.
  printf(), gets(), malloc(), free()). V pripade nekterych funkci (napr.
  puts()) neni tato volba jednoznacna -- existuji argumenty pro jednu
  i pro druhou moznost.

  V pripade, ze systemova volani predavaji jadru ukazatele na
  uzivatelskou pamet, tak je nutne overovat, ze tyto ukazatele miri na
  korektne namapovanou pamet v ramci adresoveho prostoru volajiciho
  procesu (tj. pri manipulaci s touto pameti v jadre nedojde k vyjimce,
  nedojde k pristupu k pameti jineho procesu a nedojde k nedovolenemu
  pristupu k pameti jadra). Je nutne kontrolovat i konzistenci vsech
  ostatnich argumentu a jejich chybne hodnoty indikovat chybovym
  navratovym kodem systemoveho volani, pripadne ukoncenim chybujiciho
  procesu.

  * size_t putc(const char chr)

    Funkce vypise znak na konzoli. Vraci pocet vypsanych znaku.

  * size_t puts(const char *str)

    Funkce vypise retezec na konzoli. Vraci pocet vypsanych znaku.

  * size_t printf(const char *format, ...)

    Funkce vypise formatovany retezec na konzoli, stejne jako v knihovne
    libc. Formatovaci kody by mely podporovat znaky (%c), retezce (%s),
    cela cisla v desitkove (%d, %u, %i) a v sestnactkove (%x) soustave,
    ukazatele (%p). Neni nutne implementovat modifikatory pro
    zarovnavani a platne cislice. Funkce vraci pocet vypsanych znaku.

  * char getc(void)

    Funkce precte a vrati znak z klavesnice. Pokud neni ve vyrovnavaci
    pameti klavesnice zadny znak, zablokuje volajici vlakno a ceka na
    stisk klavesy. Cekani na znak by melo byt pasivni, aktivni polling
    je velmi nevhodne reseni.

  * ssize_t gets(char *str, const size_t len)

    Funkce precte nejvice @len - 1 znaku z klavesnice do bufferu @str.
    Cteni je ukonceno pri precteni (a ulozeni) znaku '\n' nebo pri
    dosazeni limitu. Prectene znaky jsou vzdy ukonceny znakem 0. Vraci
    EINVAL, pokud @len == 0, jinak pocet znaku ulozenych do bufferu bez
    ukoncovaci 0. Cekani na jednotlive znaky by opet melo byt reseno
    pasivne.

  * void exit(int retval)

    Funkce ukonci provadeni hlavniho vlakna aktualniho procesu, tedy
    efektivne ukonci cely proces. Pri ukoncovani nesmi dojit
    k deadlocku. Veskere prostredky procesu jsou uvolneny. Pokud
    v jadre jiz nebezi zadny uzivatelsky proces, ukonci se beh celeho
    jadra.

  * makro assert(EXPR)

    Pokud neni definovano makro NDEBUG, makro assert() vyhodnoti vyraz
    EXPR a pokud je vysledek nulovy, vypise informaci o nazvu funkce,
    souboru a cisle radku, na kterem nebyl splnen predpoklad EXPR,
    a zavola exit(). Pokud je makro NDEBUG definovano, neudela makro
    assert() nic.

  * makro dprintf(ARGS...)

    Pokud neni definovano makro NDEBUG, makro dprintf() vypise na
    konzoli informaci o nazvu funkce a cislo radku, na kterem bylo
    pouzito, a formatovany retezec ARGS. Pokud je makro NDEBUG
    definovano, neudela makro dprintf() nic.

  Nasledujici funkce umoznuji uzivatelskemu procesu dynamicky alokovat
  a uvolnovat pamet. Spravce uzivatelske pameti typicky pracuje s jednou
  oblasti virtualni pameti, jejiz velikost je dana aktualnimi pametovymi
  naroky procesu (alokator uzivatelske pameti dynamicky zada jadro
  o jeji zvetseni ci zmenseni).

  Vzhledem k omezenym moznostem jadra Kalisto muzete alokator
  uzivatelske pameti implementovat za pomoci oblasti virtualni pameti
  fixni velikosti, o ktere budete zadat jadro.

  Implementace samotneho algoritmu alokatoru uzivatelske pameti muze byt
  velmi jednoducha, muzete napr. prevzit a upravit puvodni alokator
  kernelove haldy z Kalista. Je vsak nutne, aby alokator haldy
  v uzivatelskem procesu a alokator kernelove haldy byly na sobe
  nezavisle.

  * void *malloc(const size_t size)

    Funkce alokuje blok pameti pozadovane velikosti. Vraci NULL, pokud
    nebylo mozne blok alokovat, jinak ukazatel na zacatek alokovaneho
    bloku.

  * void free(const void *ptr)

    Funkce uvolni blok pameti, na ktery ukazuje @ptr a ktery byl predtim
    naalokovan funkci malloc().


Jednotkove testy -------------------------------------------------------

  K overeni spravne funkcnosti implementace slouzi testy ulozene
  v podstrome user/tests/basic zdrojoveho stromu Kalista 0.9.6.
  Infrastruktura pro spousteni a vyhodnoceni techto jednotkovych testu
  je implementovana pomoci skriptu tests-user.sh. Pro splneni zadani je
  potreba, aby reseni uspesne proslo vsemi dodanymi jednotkovymi testy,
  pricemz neni dovoleno modifikovat logiku testu.

  K integraci s jednotkovymi testy pridejte do hlavickoveho souboru
  librt.h vhodne #include direktivy, ktere zajisti vlozeni hlavickovych
  souboru s potrebnymi deklaracemi.


Doporucena literatura --------------------------------------------------

[1] Studijni text k predmetu Operacni systemy, kapitola Process
    Management, http://d3s.mff.cuni.cz/~ceres/sch/osy/text/ch02.html
[2] Wikipedia: User space,
    https://en.wikipedia.org/wiki/User_space


More information about the NSWI004 mailing list