No tak teraz sa omluvam ak sa spytam uplnu hlupost, ale nerozumiem, ako
suvisi zadanie tejto semestralnej prace s preferenciami a rozdelenim do
skupin.<br>
<br>
Vdaka,<br>
K.Cimova<br><br><div><span class="gmail_quote">On 10/17/05, <b class="gmail_sendername">Lubomír Bulej</b> <<a href="mailto:bulej@nenya.ms.mff.cuni.cz">bulej@nenya.ms.mff.cuni.cz</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Dobry den,<br><br>v priloze najdete zadani 1. semestralni prace. Testy k 1. semestralni praci<br>budou k dispozici behem pristiho tydne. Pripadne dotazy a pripominky smerujte<br>prosim do konference.<br><br><br>Lubomir Bulej
<br><br><br><br>Zadani 1. semestralni prace: -------------------------------------------------<br><br> Cilem 1. semestralni prace je naprogramovat zaklad jadra operacniho<br> systemu, ktery bude pouzit pro navazujici semestralni prace. Zadani
<br> ma formu rozhrani, ktere je nutno naimplementovat. K zajisteni rozumne<br> urovne funkcnosti pro navazujici skupiny je nutne, aby implementace<br> prosla sadou testu, ktere overuji jeji funkcnost.<br><br> Zakladem jadra je minen kod, ktery poskytuje zakladni prostredky pro
<br> ladeni a budouci rozsireni. Ukolem tedy bude naprogramovat:<br><br> * zakladni vstupne/vystupni operace<br> * zakladni ladici prostredky<br> * obsluhu preruseni a vyjimek<br> * jednoduchy alokator pameti
<br> * podporu pro vlakna<br> * jednoduchy planovac<br> * synchronizacni primitiva<br> * podporu pro casovace<br><br><br> Pri vypracovani muzete vychazet z vyukoveho jadra Kalisto a v jeho kodu<br> postupne nahrazovat pomerne jednoduche a omezene implementace nekterych
<br> z vyse uvedenych casti jadra.<br><br> Pokud zadani nespecifikuje nejaky detail, je zavazne chovani, ktere<br> ocekavaji testy. Pokud testy dane chovani netestuji, zadani si podle<br> uvazeni dodefinujte a sve rozhodnuti zdokumentujte.
<br><br><br> Poznamky k rozhranim<br> --------------------<br><br> V zadani naleznete primarne dva typy rozhrani k ruznym typum objektu<br> a datovych struktur. Rozhrani se lisi v mire skryvani implementacnich<br>
detailu spravovanych objektu.<br><br> * Prvni typ rozhrani skryva implementacni detaily mene a pracuje primo<br> s ukazateli na datove struktury. Entity spravovane timto rozhranim maji<br> vetsinou staticky charakter, takze jsou alokovany uzivatelem bud na
<br> zasobniku nebo jako staticke promenne. Rozhrani poskytuje funkce<br> xxx_init, ktere slouzi k inicializaci datovych struktur a xxx_destroy,<br> ktere slouzi k jejich "uklidu".<br><br> Je samozrejme mozne tyto entity alokovat i dynamicky, neni to ovsem
<br> prilis casty pripad a za alokaci a uvolneni pameti je zodpovedny<br> uzivatel.<br><br> Tento typ rozhrani rovnez typicky nevraci chybove kody pri predani<br> neplatneho ukazatele na spravovany objekt, nebot chyba takoveho
<br> charakteru je zpravidla fatalni (pro jadro). Pro ladici ucely je vhodne<br> do volani funkci tohoto typu pridat otestovani platnosti ukazatele<br> (non-NULL) a napr. otestovani integrity referencovane struktury. Casto
<br> se pro ladici ucely nekam do struktury objektu vklada atribut, ktery<br> musi mit nejakou konstatni preddefinovanou ("magic") hodnotu.<br><br> Uvedeny typ rozhrani je pouzit napriklad pro vsechna synchronizacni
<br> primitiva a casovace.<br><br> * Druhy typ rozhrani skryva implementacni detaily vice, tedy napriklad<br> to, ze pracuje s ukazateli. Uzivateli poskytuje obecny typ, ktery<br> slouzi k identifikaci objektu, at uz je implementaci rozhrani chapan
<br> jako ukazatel, nebo jako identifikator. Rozhrani poskytuje funkci<br> xxx_create, ktera slouzi k vytvareni a potazmo "aktivaci" novych<br> objektu. To zahrnuje alokaci pameti pro slozitejsi datove struktury,
<br> inicializaci a dalsi operace, jejich implementace ma byt pred<br> uzivatelem skryta.<br><br> Entity tohoto typu mivaji zpravidla dynamicky charakter, v ojedinelych<br> pripadech byvaji alokovany staticky, coz vsak byva pred uzivatelem
<br> skryto.<br><br> Tento typ rozhrani vraci chybove kody pri neplatne identifikaci<br> spravovaneho objektu, nebot chyba takoveho charakteru nebyva vetsinou<br> fatalni (pro jadro).<br><br> Uvedeny typ ma i rozhrani k vlaknum operacniho systemu, kde
<br> thread_create vedle alokace pameti pro ridici strukturu a zasobnik<br> vlakna a jeho inicializace zajistuje take zacleneni noveho vlakna<br> do struktur planovace.<br><br><br> Obecne pozadavky<br> ----------------
<br><br> * deklarace a pouzivani chybovych kodu<br><br> EOK = 0 "pseudo" chybovy kod, indikuje uspech<br> ENOMEM nedostatek
pameti pro provedeni operace<br> EINVAL nektery z argumentu je neplatny<br> EKILLED
vlakno, ktere bylo predmetem cekani, bylo zruseno<br> ETIMEDOUT vyprsel casovy limit pro provedeni operace<br> EWOULDBLOCK operace by zablokovala volajici vlakno<br><br> S vyjimkou EOK by chybovym kodum mela byt prirazena zaporna cisla.
<br><br> * definice typu<br><br> off_t long<br> size_t unsigned int<br> ssize_t int<br><br> uchar unsigned char<br> ushort unsigned short<br> uint unsigned int
<br> ulong unsigned long<br><br> Uvedene typy odpovidaji beznym zvyklostem a architekture procesoru<br> a mohou byt pouzity v testech a specifikaci zadani.<br><br> * podpora pro ladeni<br><br> Pri implementaci rozhrani synchronizacnich primitiv a casovacu
<br> vytvorte podporu pro kontrolu platnosti predanych ukazatelu, kterou<br> bude mozne aktivovat/deaktivovat definici nejakeho symbolu pri<br> prekladu jadra. Pouziti ladiciho mechanizmu zdokumentujte.<br>
<br> * zdrojove texty<br><br> Nasledujici doporuceni odrazi pozadavky na uroven zdrojovych textu,<br> ktere budou hodnoceny pri odevzdani prace.<br><br> - vyhybejte se pouzivani numerickych konstant<br> primo v kodu, nahradte je makry
<br> - pouzivejte prazdne radky a blokove<br> komentare k oddeleni logickych casti kodu<br> - vyhybejte se psani prilis dlouhych funkci<br> - vyhybejte se vytvareni zdrojovych souboru, ktere<br> obsahuji nesouvisejici funkce
<br> - pouzivejte makra ci inline funkce k nahrade slozitych<br> podminkovych vyrazu<br> - pouzivejte jednotny jazyk pro komentare<br> - pouzivejte jednotny jazyk pro identifikatory funkci<br> a promennych a pro nazvy souboru
<br> - pouzivejte systematicke identifikatory funkci a promennych<br> - komentujte obsah souboru, funkci a implementacni detaily; pro<br> inspiraci viz komentare ve stylu JavaDoc nebo Doxygen<br><br><br> Zakladni vstupne/vystupni operace
<br> ---------------------------------<br><br> * int putc (const char chr)<br><br> Funkce vypise znak na konzoli. Vraci pocet vypsanych znaku.<br><br> * int puts (const char * str)<br><br> Funkce vypise retezec na konzoli. Vraci pocet vypsanych znaku.
<br><br> * int printk (const char * format, ...)<br><br> Funkce vypise formatovany retezec na konzoli, stejne jako printf v<br> knihovne libc. Formatovaci kody by mely podporovat znaky (%c), retezce<br> (%s), cela cisla v desitkove (%d, %u, %i) a v sestnactkove (%x)
<br> soustave, ukazatele (%p) bez modifikatoru na zarovnavani a platne<br> cislice. Vraci pocet vypsanych znaku.<br><br> * int getc (void)<br><br> Funkce precte a vrati znak z klavesnice. Pokud neni ve vyrovnavaci
<br> pameti klavesnice zadny znak, zablokuje volajici vlakno a ceka na<br> stisk klavesy.<br><br> * int getc_try (void)<br><br> Funkce precte a vrati znak z klavesnice. Pokud neni ve vyrovnavaci<br> pameti klavesnice zadny znak, vrati EWOULDBLOCK.
<br><br> * int gets (char * str, size_t len)<br><br> Funkce precte nejvice len - 1 znaku z klavesnice do bufferu str. Cteni<br> je ukonceno pri precteni (a ulozeni) znaku '\n' nebo pri dosazeni<br> limitu. Prectene znaky jsou vzdy ukonceny znakem 0. Vraci EINVAL pokud
<br> len == 0, jinak pocet znaku ulozenych do bufferu bez ukoncovaci 0.<br><br><br> Zakladni ladici prostredky<br> --------------------------<br><br> * makro assert(EXPR)<br><br> Pokud neni definovan symbol NDEBUG, makro vyhodnoti vyraz EXPR a pokud
<br> je vysledek nulovy, zavola panic s informaci o nazvu funkce, souboru a<br> cisle radku, na kterem nebyl splnen predpoklad EXPR. Pokud je symbol<br> NDEBUG definovan, neudela nic.<br><br> * makro dprintk(ARGS...)
<br><br> Pokud neni definovan symbol NDEBUG, makro vypise na konzoli informaci<br> o nazvu funkce a cislo radku, na kterem bylo pouzito a formatovany<br> retezec ARGS. Pokud je symbol NDEBUG definovan, neudela nic.
<br><br> * void panic (const char * format, ...)<br><br> Funkce vypise formatovany retezec na konzoli (stejne jako printk),<br> vypise identifikator prave beziciho vlakna, obsah registru procesoru<br> a zablokuje jadro.
<br><br><br> Obsluha preruseni a vyjimek procesoru<br> -------------------------------------<br><br> Napiste obsluznou rutinu pro obsluhu nasledujicich vyjimek procesoru.<br> Kostru pro obsluhu vyjimek a predani rizeni do obsluzne rutiny v jazyce
<br> C naleznete ve vyukovem jadre Kalisto:<br><br> * interrupt (Int)<br><br> Zjistit zdroj preruseni a obslouzit ho.<br><br> * address error (AdEL, AdES)<br><br> Nastava pri cteni/zapisu z/na nezarovnanou adresu a pri pristupu
<br> do adresoveho prostoru jadra z uzivatelskeho rezimu. Panic.<br><br> * bus error (IBE, DBE)<br><br> Nastava pri pristupu na neplatnou fyzickou adresu. Panic.<br><br> * break point (BP)<br><br> Nastava pri vykonani instrukce BREAK. Ignorovat pokud neni instrukce
<br> v branch delay slotu, jinak panic.<br><br> * reference to WatchHi/WatchLo address (WATCH)<br><br> Nastava pri pristupu do rozmezi adres definovaneho registry CP0<br> WatchHi a WatchLo. Ignorovat.<br>
<br> * reserved instruction (RI)<br><br> Nastava pri neznamem operacnim kodu instrukce, v principu neznama<br> instrukce -- da se pouzit k emulaci nekterych instrukci. Panic.<br><br> * coprocessor unusable (CpU)
<br><br> Nastava pri pristupu na koprocesor, ktery neni neni oznacen jako<br> pristupny. Panic.<br><br> * trap exception (Tr)<br><br> Nastava pri provedeni podminenych instrukci Txx. Panic.<br><br> * arithmetic overflow (Ov)
<br><br> Nastava pri preteceni dvojkoveho doplnku pri celociselnych operacich<br> (prenosy z bitu 31 a 30 se lisi). Panic.<br><br><br> Rizeni preruseni<br> ----------------<br><br> * makro save_and_disable_interrupts (status)
<br><br> Makro ulozi soucasny obsah stavoveho registru CP0 do promenne a<br> globalne zakaze preruseni procesoru.<br><br> * makro restore_interrupts (status)<br><br> Makro obnovi obsah stavoveho registru CP0 z promenne, cimz obnovi
<br> globalni stav povoleni/zakazni preruseni, ktery predchazel pouziti<br> makra save_and_disable_interrupts ().<br><br> * makro/funkce void disable_interrupts (void)<br><br> Funkce globalne zakaze preruseni na procesoru.
<br><br> * makro/funkce void enable_interrupts (void)<br><br> Funkce globalne povoli preruseni na procesoru.<br><br><br> Jednoduchy alokator pameti<br> --------------------------<br><br> Pri behu operacniho systemu je casto nutne radu objektu alokovat
<br> dynamicky. Vyukove jadro Kalisto ma implementovan jednoduchy alokator<br> pameti, ktery poskytuje funkce malloc () a free (). Tyto funkce by melo<br> poskytovat i vase jadro, pricemz je mozne ponechat puvodni implementaci.
<br><br> Spravnost funkce alokatoru nebude testovana, rovnez inteligence<br> alokatoru nebude hodnocena.<br><br> * void * malloc (size_t size)<br><br> Funkce alokuje blok pameti pozadovane velikosti z heapu. Vraci NULL
<br> pokud nebylo mozne blok alokovat, jinak ukazatel na zacatek alokovaneho<br> bloku.<br><br> * void free (void * ptr)<br><br> Funkce uvolni blok pameti, na ktery ukazuje ptr.<br><br><br> Jednoduchy planovac
<br> -------------------<br><br> * preemptivni planovani vlaken k behu na procesoru<br> * strategie round-robin bez priorit<br><br><br> Rozhrani pro praci s vlakny<br> ---------------------------<br><br> * int thread_create (
<br> thread_t * thread_ptr, void (* thread_start) (void *), void * data)<br><br> Funkce vytvori nove (attached) vlakno. Vraci chybovy kod, pokud se<br> vlakno nepodari vytvorit, jinak EOK. Funkce<br> void thread_start (data) bude spustena v nove vytvorenem vlakne.
<br> Pocet vlaken v systemu je omezen pouze dostupnou pameti.<br><br> Za vytvorenim vlakna se skryva alokace a inicializace ridici datove<br> struktury obsahujici informace o vlaknu, alokace zasobniku pro vlakno,
<br> a zarazeni vlakna do struktur planovace. Z toho duvodu je vlakno<br> identifikovano pro uzivatele rozhrani "nepruhlednym" typem thread_t.<br><br> * thread_t thread_get_current (void)<br><br> Funkce vrati identifikaci prave beziciho vlakna.
<br><br> * int thread_join (thread_t thr)<br> * int thread_join_timeout (thread_t thr, uint usec)<br><br> Funkce ceka na dokonceni behu uvedeneho vlakna a iniciuje uvolneni<br> pameti obsahujici ridici strukturu jadra a zasobnik. Vraci EINVAL
<br> pokud je identifikace vlakna neplatna, pokud bylo vlakno odpojeno<br> pomoci thread_detach (), pokud jiz na vlakno ceka nekdo jiny, nebo<br> pokud vlakno vola funkci samo na sebe. Vraci EKILLED pokud bylo
<br> vlakno zruseno volanim funkce thread_kill ().<br><br> Varianta _timeout ceka na ukonceni vlakna nejdele usec mikrosekund,<br> pokud vlakno neni ukonceno do uplynuti teto doby, vraci ETIMEDOUT.<br><br> * int thread_detach (thread_t thr)
<br><br> Funkce odpoji zadane vlakno. Vraci EINVAL pokud je identifikace<br> vlakna neplatna, vlakno je jiz odpojene, vlakno jiz nebezi a ceka<br> na join nebo pokud na vlakno jiz nekdo ceka v thread_join ().
<br><br> Odpojene (detached) vlakno se od pripojeneho (attached) vlakna lisi<br> tim, ze neni mozne cekat na jeho ukonceni a pri skonceni jadro<br> automaticky uvolni pamet alokovanou pro ridici strukturu jadra a
<br> jeho zasobnik.<br><br> * void thread_sleep (uint sec)<br> * void thread_usleep (uint usec)<br><br> Funkce zablokuje prave bezici vlakno na zadanou dobu v sekundach<br> (resp. mikrosekundach). Vlakno nesmi byt zablokovano na kratsi dobu
<br> nez bylo zadano, rozumne zduvodnene prodlouzeni teto doby lze<br> tolerovat.<br><br> * void thread_yield (void)<br><br> Vlakno volajici thread_yield () se vzda rizeni dokud nebude<br> znovu naplanovano k behu.
<br><br> * void thread_suspend (void)<br><br> Vlakno volajici thread_suspend () se zablokuje, dokud jej jine<br> vlakno neodblokuje pomoci funkce thread_wakeup ().<br><br> * int thread_wakeup (thread_t thr)
<br><br> Funkce odblokuje zadane vlakno. Volajici vlakno pokracuje v behu,<br> neni v dusledku tohoto volani preplanovano. Funkce vraci EINVAL<br> pokud je identifikace vlakna neplatna, jinak EOK.<br><br> * int thread_kill (thread_t thr)
<br><br> Funkce zrusi zadane (bezici) vlakno. Vlakno, ktere ceka na ukonceni<br> ruseneho vlakna, je odblokovano. Funkce vraci EINVAL pokud je<br> identifikace vlakna neplatna, jinak EOK.<br><br><br> Podpora casovacu
<br> ----------------<br><br> Casovace slouzi k implementaci asynchronnich udalosti, pro ktere je<br> nevhodne (z duvodu moznosti selhani alokace pameti) vytvaret nove vlakno.<br> Obsluzne rutiny casovacu bezi na ukor vlakna, ktere bylo casovacem
<br> preruseno, nebo v kontextu systemoveho vlakna pro obsluhu casovacu.<br><br> * int timer_init (<br> struct timer * tmr, uint usec,<br> void (*) (struct timer *, void *) handler, void * data)<br>
<br> Funkce inicializuje strukturu casovace pro dobu usec mikrosekund.<br> Vraci EINVAL pokud je handler NULL, jinak OK. Casovac po inicializaci<br> neni aktivni, aktivace se provadi funkci timer_start ().<br>
<br> * void timer_start (struct timer * tmr)<br><br> Funkce aktivuje casovac a prida ho do seznamu aktivnich casovacu.<br> Pri vyprseni casoveho limitu je zavolana obsluzna rutina<br> void handler (struct timer * self, void * data), parametr self
<br> odkazuje na strukturu casovace, ktera vedla k jejimu vyvolani.<br> Obsluzna funkce bezi na ukor preruseneho vlakna.<br><br> Pri zavolani timer_start na jiz aktivni casovac dojde k jeho<br> restartovani.
<br><br> * void timer_destroy (struct timer * tmr)<br><br> Funkce deaktivuje casovac, odebere ho ze seznamu aktivnich casovacu a<br> provede uklid ridici struktury. Vykonavani obsluzne rutiny casovace<br> neni preruseno pokud jiz bezi.
<br><br> * int timer_pending (struct timer * tmr)<br><br> Funkce vraci nenulovou hodnotu pokud je casovac aktivni, jinak 0.<br><br><br> Synchronizacni primitiva<br> ------------------------<br><br> Pri implementaci predpokladejte, ze kod muze byt kdykoliv prerusen
<br> pokud nejsou zakazana preruseni. Neni nutne uvazovat viceprocesorove<br> konfigurace simulatoru (tj. zakazani preruseni staci k zajisteni<br> atomicity operaci).<br><br> - semafor (s casovym limitem)<br><br> * void sem_init (struct semaphore * sem, int value)
<br><br> Funkce inicializuje semafor a nastavi ho na zadanou hodnotu.<br><br> * void sem_destroy (struct semaphore * sem)<br><br> Funkce provede uklid ridici struktury semaforu. Pokud je rusen<br> semafor, na kterem jsou jeste zablokovany nejake thready, funkce
<br> vyvola panic.<br><br> * int sem_get_value (struct semaphore * sem)<br><br> Funkce vrati hodnotu semaforu >= 0.<br><br> * void sem_up (struct semaphore * sem)<br><br> Funkce inkrementuje hodnotu semaforu a pripadne odblokuje jedno z
<br> vlaken na nem zablokovanych.<br><br> * void sem_down (struct semaphore * sem)<br> * void sem_down_timeout (struct semaphore * sem, uint usec)<br><br> Funkce dekrementuje hodnotu semaforu pokud je to mozne, jinak
<br> vlakno na semaforu zablokuje.<br><br> Varianta _timeout ceka na dekrementovani hodnoty semaforu nejdele<br> usec mikrosekund. Pokud se behem teto doby podari semafor dekrementovat,<br> vraci EOK, jinak ETIMEDOUT. Pokud je casovy limit 0, k zablokovani
<br> vlakna nedochazi.<br><br> Semafory budou pouzivany nasledujicim zpusobem:<br><br> struct semaphore sem;<br> sem_init (&sem, 100);<br> ...<br> sem_destroy (&sem);<br><br><br> - mutex (binarni semafor)
<br><br> * void mutex_init (struct mutex * mtx)<br><br> Funkce inicializuje mutex do stavu odemceno.<br><br> * void mutex_destroy (struct mutex * mtx)<br><br> Funkce provede uklid ridici struktury mutexu. Pokud je rusen mutex,
<br> na kterem jsou jeste zablokovana nejaka vlakna, funkce vyvola panic.<br><br> * void mutex_lock (struct mutex * mtx)<br> * int mutex_lock_timeout (struct mutex * mtx, uint usec)<br><br> Funkce se pokusi zamknout mutex, pokud to neni mozne, zablokuje
<br> vlakno na mutexu.<br><br> Varianta _timeout ceka na zamknuti mutexu nejdele usec mikrosekund.<br> Pokud se behem teto doby podari mutex zamknout, vraci EOK, jinak<br> ETIMEDOUT. Pokud je casovy limit 0, k zablokovani vlakna nedochazi.
<br><br> * void mutex_unlock (struct mutex * mtx)<br><br> Funkce odemkne zadany mutex a vzbudi vlakna, ktera byla zablokovana<br> pri zamykani mutexu. Pokud je symbol DEBUG_MUTEX >= 1, bude<br> implementace mutexu hlidat, zda je odemykan vlaknem, ktere ho puvodne
<br> zamknulo. Pokud bude mutex odemykat jine vlakno, vyvola panic.<br><br><br> - r/w lock (rekurzivni)<br><br> * void rwlock_init (struct rwlock * rwl)<br><br> Funkce inicializuje ridici strukturu r/w zamku do stavu odemceno.
<br><br> * void rwlock_destroy(struct rwlock * rwl)<br><br> Funkce provede uklid ridici struktury zamku. Pokud je rusen zamek,<br> na kterem jsou jeste zablokovana nejaka vlakna, funkce vyvola panic.<br><br> * void rwlock_read_lock (struct rwlock * rwl)
<br> * void rwlock_write_lock (struct rwlock * rwl)<br> * int rwlock_read_lock_timeout (struct rwlock * rwl, uint usec)<br> * int rwlock_write_lock_timeout (struct rwlock * rwl, uint usec)<br><br> Funkce se pokusi zamknout zamek v pozadovanem rezimu, pokud to neni
<br> mozne, zablokuje volajici vlakno na zamku.<br><br> Varianta _timeout ceka na zamknuti zamku nejdele usec mikrosekund.<br> Pokud se behem teto doby podari zamek zamknout, vraci EOK, jinak<br> ETIMEDOUT. Pokud je casovy limit 0, k zablokovani vlakna nedochazi.
<br><br> * void rwlock_write_unlock (struct rwlock * rwl)<br> * void rwlock_read_unlock (struct rwlock * rwl)<br><br> Funkce odemkne zamek a odblokuje vlakna zablokovana na zamku.<br><br><br> - condition variable
<br><br> * void cond_init (struct cond * cvar)<br><br> Funkce inicializuje ridici strukturu condition variable.<br><br> * void cond_destroy (struct cond * cvar)<br><br> Funkce provede uklid struktury condition variable. Pokud je rusena
<br> condition variable, na ktere jsou jeste zablokovany nejake thready,<br> funkce vyvola panic.<br><br> * void cond_signal (struct cond * cvar)<br> * void cond_broadcast (struct cond * cvar)<br><br> Funkce odblokuje jedno resp. vsechna vlakna cekajici na
<br> condition variable.<br><br> * void cond_wait (struct cond * cvar, struct * mtx)<br> * int cond_wait_timeout (<br> struct cond * cvar, struct mutex * mtx, uint usec)<br><br> Funkce atomicky odemkne mutex a zablokuje volajici vlakno na
<br> condition variable. Po odblokovani opet zamkne mutex a vrati<br> rizeni volajicimu.<br><br> Varianta _timeout zablokuje vlakno nejdele na usec mikrosekund, resp.<br> na dobu odpovidajici limitu a dobu nutnou k opetovnemu zamceni mutexu.
<br> Pokud behem teto doby dojde k odblokovani vlakna, vraci EOK, jinak<br> ETIMEDOUT. Pokud je casovy limit 0, k zablokovani vlakna nedochazi,<br> ale pred opetovnym zamcenim mutexu se vlakno jednou vzda procesoru.
<br><br><br> Integrace s testy<br> -----------------<br><br> K integraci s testy vytvorite hlavickovy soubor assignment-1.h, ktery bude<br> obsahovat deklarace vsech vyse uvedenych funkci. Typicky bude obsahovat<br> #include direktivy, ktere zajisti vlozeni vasich hlavickovych souboru s
<br> prislusnymi deklaracemi.<br><br> Dale musi soubor obsahovat deklaraci funkce assignment_test (void),<br> kterou zavolate z vaseho jadra.<br><br>--<br>Posledni modifikace: 2005/10/17 10:21<br><br><br>_______________________________________________
<br>OSy mailing list<br><a href="mailto:OSy@nenya.ms.mff.cuni.cz">OSy@nenya.ms.mff.cuni.cz</a><br><a href="http://nenya.ms.mff.cuni.cz/mailman/listinfo/osy">http://nenya.ms.mff.cuni.cz/mailman/listinfo/osy</a><br><br><br>
</blockquote></div><br>