980 likes | 1.46k Vues
Operativni sistemi. Niti i procesi. Prostori kernela i korisnika. Kernel operativnog sistema mora da se nalazi u delu memorije u koji korisni č ki programi nemaju direktnog pristupa – u prostoru kernela .
E N D
Operativni sistemi Niti i procesi
Prostori kernela i korisnika • Kernel operativnog sistema mora da se nalazi u delu memorije u koji korisnički programi nemaju direktnog pristupa – u prostoru kernela. • Ukoliko postoji hardverska podrška za ovo, to se rešava višom privilegijom izvršavanja kôda u prostoru kernela, u odnosu na prostor korisnika. Zbog toga se često izvršavanje sa visokom privilegijom poistovećuje sa prostorm kernela, ali to nije uvek slučaj. • Ako nema hardverske podrške, tada se sistem oslanja na “lepo ponašanje” korisničkih programa, nadajući se da oni nikada neće direktno adresirati prostor kernela.
Sistemski pozivi • Bilo da postoji ili ne postoji podrška hardvera (mikroprocesora) koja štiti prostor kernela, programi iz prostora korisnika mu pristupaju isključivo upotrebom sistemskih poziva. • Obrnuto ne važi – program iz prostora kernela nikada nema potrebe da pristupa korisničkom programu, sem u nekim, vrlo specifičnim, situacijama. • Kernel je skup rezidentnih biblioteka koje pružaju svoje usluge korisničkim programima (aplikacijama). • Jedne kernel funkcije mogu da pozivaju druge kernel funkcije, ali nikada funkcije iz aplikacija.
Program • Program* se nalazi u sklopu izvršne datoteke • Izvršna datoteka dobija se nakon procesa prevođenja izvornog programa • Program se sastoji od instrukcija i podataka • Podaci mogu dabudu konstante i promenljive • Pomenljive mogu da budu perzistentne i tranzijentne • Instrukcije mogu da budu privatne ili deljene *Za definiciju programa pogledati meterijal iz predmeta Uvod u programiranje.
Program u memoriji (task) Program na disku (EXE) Task Deljene instrukcije i podaci Runtime library Privatni podaci (tranzijentni) SP stack SS Globalni podaci zaglavlje heap Metapodaci na disku Neinicijalizovani podaci RPT BSS Inicijalizovani podaci Dobija se nakon prevođenja data BP data DS Programski kôd text IP text CS Deo konteksta
Multitasking • Sve ovo smo imali i kod MS-DOS-a. • Ono što nismo imali je da se proizvoljan broj taskova izvršava u isto vreme – multitasking. • Ali, tvrdnja da neki operativni sistem izvršava više taskova istovremeno nije uvek tačna, čak i kada je u pitanju sistem sa više procesora (jezgara). • Multitasking je samo naša percepcija istovremenog izvršavanja svih taskova.
Kako radi multitasking • U stvarnosti, operativni sistem učitava program u memoriju (kada on postaje task), predaje mu kontrolu nad procesorom, tj. dozvoljava mu izvršavanje neko vreme, a zatim prekida njegovo izvršavanje. • U tom trenutku, operativni sistem pravi „snimak“ trenutnog stanja procesora (konteksta), tj. zamrzava vrednost svih njegovih registara (segmentnih registara, registara opšte namene, programskog brojača, stek pointera, flags ...) i stavlja ih na sigurno mesto. • Zatim dozvoljava nekom drugom tasku izvršavanje izvesno vreme, prekida njegovo izvršavanje, itd. • Sve ovo ponavlja se vrlo brzo, tako da korisnik ima utisak da se taskovi izvršavaju istovremeno.
Task (definicija) • Iz ugla programera, termin “task” je često nejasan. • On se izjednačava sa pojmovima kao što su proces, laki proces, korisnička nit, kernel nit, fiber, itd. • Definicija: Task čine programski kôd i podaci koji poseduju sopstveni kontekst i sopstveni stek.
Gde se čuva kontekst • Najšešće na steku • Može i neki drugi deo memorije (u zaštićenom režimu rada za ovo imamo i pomoć hardvera) • Ovako se čuvaju registri na tekućem steku: pushf push ax push bx push cx . . . pop es ; Nakon zamene stekova, izvrsavaju se pop ; instrukcije obrnutim redosledom • Svaki task mora da ima svoj stek. • Stek se inicijalizuje adresom početka taska.
Zamena konteksta • Sva task ima inicijalizovan stek pointer na vrednost poslednjeg smeštenog registra. • Vrednost stek pointera svakog taska čuva se u delu memorije koji se često zove TCB (Task Control Block). • TCB može da sadrži i druge informacije vezane za task. • Zamena konteksta: • Određuje se koji seledeći task treba da se izvršava. • Iz TCB tog taska uzima se vrednost stek pointera i stavlja u SS/SP registre mikroprocesora. • Nastavlja se sa izvršavanjem pop instrukcija, sada sa novog steka (na taj način se registri postavljaju na vrednosti tog taska). • Poslednja instrukcija RET učitava adresu novog taska u CS/IP.
Stanja taska • Task može da se nalazi u jednom od dva osnovna stanja: • Stanje izvršenja • Stanje neizvršenja • Na jednom procesoru (jezgru) samo jedan task može da bude u stanju izvršenja. • Ne treba mešati stanje taska i stanje procesora (kontekst). Start task Proizvoljan broj taskova Samo jedan task neizvršenje izvršenje Startovan je neki drugi task Dijagram stanja konačnog automata
Prinudni prekid izvršavanja • Prinudni prekid izvršavanja nekog taska nastaje kada se ne čeka da on dobrovoljno prepusti procesor nekom drugom tasku, već mu se procesor oduzme “na silu” • Mi ćemo to zvati istiskivanje (engl. Preemption) • Preempt– istisni • Preemptive – sa istiskivanjem
Raspoređivanje • Task nije u stanju izvršenja kada: • Nema šta da radi * • Ima šta da radi, ali mu operativni sistem ne dozvoljava prelazak u stanje izvršenja • Dobrovoljno je prepustio stanje izvršenja nekom drugom tasku • Prinudno je prepustio stanje izvršenja nekom drugom tasku (posledica istiskivanja) • Kako se određuje kada će neki task da se startuje (da bude u stanju izvršenja)? • Tu funkciju obavlja raspoređivač (scheduler). * Kada se program “vrti” u praznoj petlji, on ipak nešto radi (možda nešto čeka), ali je to beskorisnozauzimanje procesora. Primer: JMP $
Primer task1: mov dx, zeleno mov al, _ON out dx, al mov dx, crveno mov al, _OFF out dx, al jmp task1 task2: mov dx, zeleno mov al, _OFF out dx, al mov dx, crveno mov al, _ON out dx, al jmp task2 • Nijedan task ne vodi računa o čuvanju registara koje koristi (DX i AL). • Nema ni potrebe, jer o tome vodi računa mehanizam zamene konteksta. • Pravljenje programa je identično kao da je jedini u sistemu. • Ipak, potrebno je voditi računa da možda postoji još taskova kojikoriste iste resurse (memoriju, ulaz/izlaz) i koji mogu da ih menjaju. • U ovom primeru task 1 pali zeleno, a gasi crveno svetlo. Task 2 radi obrnuto - gasi zeleno, a pali crveno svetlo.
Raspoređivač kao ISR • Pretpostavimo da task nema nameru da startuje drugi task i da mu na taj način dobrovoljno prepusti procesor. • U tom slučaju njega može da prekine samo prekid (interrupt). On najčešće potiče od sistemskog časovnika. • Prekidna rutina sadrži algoritam koji određuje koji sledeći task će biti startovan i ona bi trebalo da taj task i startuje – jednom rečju, da radi kao raspoređivač. • Ali, kako će ona to da uradi? • Ako na svom kraju izvrši instrukciju IRET, vratiće se u task koji je prekinut, a ne u novi task koji treba startovati. • Prethodno će izvršiti zamenu stekova. IRET sada uzima povratnu adresu sa novog steka.
Primer: kružno raspoređivanje • Pretpostavimo da Task 1 i Task 2 izvršavamo po algoritmu kružnog raspoređivanja (Round Robin): malo se izvršava jedan, malo drugi, pa opet prvi i tako u krug. • Izvršavanje svakog taska određeno je intervalima prekida sistemskog časovnika (kvantumom) i isto je za oba taska. • Ovakvo raspoređivanje koristi se u tzv. Time-sharing sistemima, gde svaki task ima dodeljen isti vremenski interval (Time Slice) za svoje izvršavanje. Periodični prekidi sistemskog časovnika task1 ISR task2 ISR task1 ISR task2 itd ... vreme
Komunikacija između taskova • Da bi taskovi mogli međusobno da komuniciraju, potrebno je da poseduju neki deo memorije koji je zajednički. • S druge strane, poželjno je što više izolovati taskove, da ne bi na bilo koji način uticali jedni na druge. • Taskovi mogu međusobno da budu izolovani u različitom obimu: • potpuno izolovani (nemaju zajednički ni najmanji deo memorije) • neizolovani (zajednička im je cela memorija) • delimično izolovani (postoji neki deo memorije koji je zajednički)
Razdvojen adresni prostor • Nema deljenog koda ni podataka • Jedan task nikako ne može da utiče na drugi task • Taskovi ne mogu da komuniciraju Task 1 Task 2
Zajednički adresni prostor • Kompletan kodni prostor i prostor podataka su zajednički • Jedan task može da utiče na drugi • Taskovi mogu da razmenjuju informacije Task 1 Task 2
Preklopljen adresni prostor • Pojedini delovi koda i podataka su zajednički • Jedan task može da utiče na drugi • Taskovi mogu da razmenjuju informacije Task 1 Task 2
Taskovi i njihovi atributi • Samo jedan task može da bude u stanju izvršenja na jednom procesorskom jezgru. • Taskovi se nalaze u stanju neizvršenja iz različitih razloga. • Razvrstavanje taskova prema tim razlozima vrši se upotrebom atributa koji dodatno opisuju zašto task nije u stanju izvršenja i kada bi trebalo u njega da pređe. Start task Proizvoljan broj taskova Samo jedan task neizvršenje izvršenje Startovan je neki drugi task
Niti i procesi • Na osnovu atributa, stanje neizvršenja taskova deli se na više (pod)stanja. • Atribute formira i održava operativni sistem i oni nisu u sastavu taska. • Taskovi sa zajedničkim adresnim prostorom i sa pridruženim atributima zovu se niti (threads). • Skup niti (sa dodatnim atributima*) zove se proces. • Različiti procesi imaju međusobno potpuno razdvojene ili delimično preklopljene adresne prostore. • Proces mora da ima najmanje jednu nit. • * Biće objašnjeno kasnije
Stanja niti • Zavisno od realizacije, niti mogu da imaju različita stanja, ali sledeća stanja prisutna su kod svih operativnih sistema : • Stanje nespremnosti za izvršenje. To je stanje čekanja na neki događaj. Često se zove i blokirano stanje (Blocked), spavanje (Sleep), čekanje (Wait), itd. • Stanje spremnosti za izvršenje • Stanje izvršenja • Na svakom procesorskom jezgru mora da postoji jedna i samo jedna nit koja je u stanju izvršenja.
Atributi niti • Atributi niti zavise od operativnog sistema, ali u osnovi se sastoje od sledećih informacija: • Identifikator niti (Thread ID) • Kontekst • Stanje u kome se nalazi nit • Prioritet • Afinitet • Klasa raspoređivanja • Događaj na koji čeka • Preostalo vreme za izvršavanje u okviru kvantuma * • Povratna vrednost po završetku • … * Biće objašnjeno kasnije Jedinstveno za svaku nit
Kako se čuvaju atributi • Prilikom kreiranja, kernel svakoj niti dodeljuje memorijsku strukturu koja sadrži atribute. • Ove strukture se obično povezuju kao jednostruko ulančane liste. Operacije nad listom su: “stavi na kraj” i “ukloni sa početka”, a izuzetno i “stavina početak”. • Ovakva lista naziva se red čekanja – Queue • U sastav reda ulaze strukture koje imaju neke zajedničke atribute. Npr., jedan red čine strukture koje imaju istu vrednost atributa “Prioritet”, drugi red čine strukture koje imaju istu vrednost atributa “Događaj na koji čeka”, itd. • Radi kraćeg izražavanja, kaže se da se nit nalazi u nekom redu čekanja.
Stanje spremnosti TID=567 TID=123 TID=456 TID=789 spremna spremna spremna spremna prioritet=6 prioritet=6 prioritet=6 prioritet=6 next next next NULL • Onoliko redova koliko ima prioriteta • Nazivaju se Ready Queues ili Run Queues • Obično se prvo prazni red višeg prioriteta, zatim nižeg, itd. • Ako u red stalno dolaze nove niti višeg prioriteta, niti nižeg proriteta će čekati dugo – izgladnjivanje (starvation). TID=091 TID=234 spremna spremna prioritet=1 prioritet=1 next NULL • Svako procesorsko jezgro ima svoje redove spremnosti (između ostalog i na osnovu atributa “Afinitet”)
Stanje spremnosti • Prioriteti se nitima dodeljuju na osnovu različitih kriterijuma. To npr. može da bude nit koja zahteva više procesorskog vremena, koja je više orijentisana na ulazno-izlazne operacije, ili se od nje zahteva odgovor u realnom vremenu. • Ukoliko je potrebno dinamički menjati prioritete (dok je nit u redu čekanja), mogu se koristiti prioritetni redovi (Priority Queues). • Ukoliko se pojavi nit višeg prioriteta, raspoređivač istiskuje nit nižeg proriteta i stavlja je na čelo reda njenog proriteta. • Ukoliko je isteklo vreme za izvršavanje niti, raspoređivač je stavlja na začelje njenog reda proriteta. • U svakom slučaju, niti se šalju na izvršenje prema prioritetu, a ne prema njihovoj privilegiji. • Zaključak: Nit može da bude istisnuta i u prostoru korisnika i u prostoru kernela.
Blokirano stanje TID=135 TID=222 TID=333 TID=246 blokirana blokirana blokirana blokirana disk tajmer tajmer konzola next NULL NULL NULL • Onoliko redova koliko ima događaja na koje se čeka • Nisu vezani za neko procesorsko jezgro TID=980 TID=357 TID=469 blokirana blokirana blokirana semafor A semafor A semafor A next next NULL
Blokirano stanje • Operacija WAIT • Nit eksplicitno poziva ovu operaciju. • Nit zatim menja svoje stanje iz izvršenja u blokirano stanje i stavlja se u red čekanja blokiranih niti za odgovarajuću događaj. Ova operacija mora da bude atomična. • Nit zatim eksplicitno startuje raspoređivač. • Raspoređivač određuje koja nit ide u koji red spremnih niti, a zatim startuje nit sa početka reda najvišeg prioriteta.
Blokirano stanje • Blokirajući sistemski poziv * • Nakon sistemskog poziva, nit ulazi u prostor kernela. • Ako je sistemski poziv nije blokirajući, RETF na kraju funkcije vraća nit u korisnički prostor. • Ako je sistemski pozivblokirajući, a funkcija naiđe na deo koji zavisi od nekog događaja koji se još nije desio (npr. raspoloživost nekog resursa), ona će pozvati operaciju WAIT. • Zaključak: Nit može da ide u blokirano stanje samo kada je u prostoru kernela. • Sistemski pozivi se koriste kada je iz korisničkog prostora potrebno pozvati funkciju kernela. Iz prostora kernela, kernel funkcije se pozivaju na običan način. Iz kernel prostora ne pozivaju se funkcije korisničkog prostora.
Izlaz iz blokiranog stanja • Nit koja se nalazi u blokiranom stanju ne može sama sebe da probudi jer se ne izvršava na procesoru . • Nju može da probudi samo raspoređivač. • On se startuje periodično ili na zahtev, ali svaki put proverava da li je ispunjen uslov zbog koga je nit blokrana. Ako jeste, on briše nit iz reda blokiranih i stavlja je u red spremnih. • Ali, kako raspoređivač zna da je ispunjen uslov? • To mu javlja neka druga nit ili servisna rutina nekog prekida.
Solaris niti (LWP) IDL PINNED thread_create() intr() switch() syscall() RUN ONPROC SLEEP preempt() wakeup() pstop() exit() prun() reap() STOP ZOMBIE FREE Stanje kada su resursi koje zauzima task oslobođeni, ali je struktura sa atributima još u upotrebi. Potpuno oslobađanje
Linux niti (tasks) signal CREATE STOP ZOMBIE fork() signal switch() exec() exit() READY RUNNING preempt() wake_up() wait() WAIT uninterruptible interruptible
Windows XP (threads) switch Init Standby pick preempt, quantum end preempt initialize switch Ready Running resursi su raspoloživi terminate unblock resursi raspoloživi Transition Terminated unblock resursi nisu raspoloživi ali će uskoro biti Waiting
Vista, Server 2008, Windows 7 Ready switch Init Standby pick preempt, quantum end preempt initialize Deferred Ready switch Running resursi su raspoloživi terminate unblock resursi raspoloživi Transition unblock resursi nisu raspoloživi ali će uskoro biti Terminated Waiting, Gate Waiting
Konkurentno izvršavanje Primer:Pretpostavimo da je početna vrednost globalne deljene celobrojne promenljive x= 0 Nit 1 Nit 2 Nit 3Raspoređivanje sa istiskivanjem. (1) x = 1 (2) x = 2 (3) y = xMogu da se izvršavaju konkurentno na jednom ili više procesora. Konačna vrednost promenljive y je nepredvidljiva, ali se očekuje da bude 0, 1, ili 2. Evo nekih mogućih preplitanja prethodna tri iskaza: (3), (1), (2) konačna vrednosty je 0 (2), (1), (3) konačna vrednosty je 1 (1), (2), (3) konačna vrednosty je 2
Nedeterministričko ponašanje U slučaju konkurentnog izvršavanja, nedeterminističko ponašanje mogu izazvati jedna ili više sledećih situacija: • Nepredvidljiva brzina napredovanja niti koje se izvršavaju na jednom jezgru procesora (zbog prebacivanja konteksta između niti) • Nepredvidljiva brzina napredovanja niti koje se izvršavaju narazličitim jezgrima ili različitim procesorima (zbog razlike u brzini jezgara ili procesora) • Upotreba nedeterminističkih programskih konstrukcija, koje dozvoljavaju nepredvidljivi izbor između više mogućih akcija
Konkurentnost • Posmatrajmo dva nepreklapajuća događaja A i B koji se izvršavaju konkurentno. Činjenica da su A i B konkurentniznači da oni mogu da nastupe u bilo kom redosledu. Znači, njihova konkurentnost može da se modeluje kao nedeterministički izbor između dva prepletena događaja: (A iza koga sledi B) ili (B iza koga sledi A). • Ovaj model konkurentnosti se koristi u nekim tehnikama za testiranje i verifikaciju ponašanja programa. Međutim, treba imati u vidu da broj ovakvih permutacija enormno raste sa porastom broja niti, tako da je potpuna kontrola, čak i malih programa, veoma teška. • Sinhronizacija: • Uzajamno isključivanje: Događaji A i B ne smeju da se dese u isto vreme. • Serijalizacija: Događaj A mora da se desi pre događaja B.
Debagovanje • Programeri se oslanjaju na ponovljivo, determinističko izvršavanje kako bi pronašli i otklonili greške u programu. • Kada posmatramo grešku u jednonitnom programu, mi očekujemo da će se ona pod istim uslovima ponoviti i u budućnosti, tako damožemo da je lociramo i otklonimo. • Ukoliko grešku ne možemo da reprodukujemo, to nam ukazuje na problem, s obzirom da samo neke greške u sekvencijalnim programima (npr. promenljive koje nisu inicijalizovane) proizvode nedeterminističke greške. • Konkurentni programi su inherentno nedeterministički. Jedna od najvećih “glavobolja” programera ovakvih sistema je otkrivanje i otklanjanje grešaka.
Dve niti, jedan brojač • Posmatrajmo jedan web server koji koristi višenitnu obradu pristiglih zahteva. • Svaka nit inkrementira deljenu promenljivu - brojač, da bi pratila dnevni broj pristupa (pogodaka – hits) web sajta: … hits = hits + 1; … • Šta se događa kada dve niti izvrše ovaj kôd konkurentno? • Prvo ćemo inicijalizovati deljenu promenljivu hits xor eax,eax mov dword [hits],eax ;hits=0
Dve niti, jedan brojač Uspostavljena konekcija 1 ; Pocetak niti #1 mov dword eax,[hits] ;hits=0 add eax,1 mov dword [hits],eax ;hits=1 iret Uspostavljena konekcija 2 ; Pocetak niti #2 mov dword eax,[hits] ;hits=1 add eax,1 mov dword [hits],eax ;hits=2 iret vreme
Stanje trke Uspostavljena konekcija 1 ; Pocetak niti #1 mov dword eax,[hits] ;hits=0 add eax,1 mov dword [hits],eax ;hits=1 iret Uspostavljena konekcija 2 ; Pocetak niti #2 mov dword eax,[hits] ;hits=0 add eax,1 mov dword [hits],eax ;hits=1 iret Trebalo bi da bude hits=2 Stanje trke je vremenski zavisna greška. Da li će se javiti ili ne, zavisi od raspoređivanja. vreme
Kritična sekcija • Atomična operacija: sekvenca instrukcija koje se garantovano izvršavaju nedeljivo. • Drugi naziv za ovo je kritična sekcija (Critical Section). • Ako dve niti izvršavaju istu atomičnu operaciju u isto vreme, jedna nit će izvršiti celu sekvencu pre nego što druga počne – serijalizacija. • “U isto vreme” znači paralelno kod sistema kod kojih svaka nit ima “svoje” procesorsko jezgro, a prepleteno ukoliko ima više niti nego procesorskih jezgara. • Upotreba kritične sekcije jedan je od načina realizacije uzajamnog isključivanja (Mutual Exclusion).
Uslovi za kritičnu sekciju • Samo jedna nit može da se izvršava unutar svoje kritične sekcije (uzajamno isključivanje). • Kod više istovremenih zahteva za ulazak u kritičnu sekciju, jedan (i samo jedan) zahtev mora da bude zadovoljen. • Svaka nit čeka na ulazak u svoju kritičnu sekciju konačno dugo (nema izgladnjivanja). • Niti moraju da napreduju u svom izvršavanju tokom vremena (nema uzajamnog blokiranja). • Broj procesora i njihova pojedinačna brzina ne smeju da imaju nikakvog uticaja. • Nit ne sme da bude istisnuta (blokirana) dok se izvršava u svojoj kritičnoj sekciji. • Da li nit u svojoj kritičnoj sekciji sme da bude prekinuta ? • Da, ukoliko nijedna druga nit ne ulazi u istu kritičnu sekciju.
Zabrana prekida Uspostavljena konekcija 1 ; Pocetak niti #1 cli mov dword eax,[hits] ;hits=0 add eax,1 mov dword [hits],eax ;hits=1 sti iret Prekid se tretira kao nastupajući (pending) Uspostavljena konekcija 2 ; Pocetak niti #2 cli mov dword eax,[hits] ;hits=1 add eax,1 mov dword [hits],eax ;hits=2 sti iret Kritična sekcija cli i stisu IOPL osetljive instrukcije. Mora da bude CPL ≤ IOPL (polje koje se nalazi u EFLAGS). Često nije ispunjeno pa se cli i stiizvršavaju upotrebom sistemskih poziva. vreme
Problem Uspostavljena konekcija 1 ; Pocetak niti #1 cli jmp $ Prekid se tretira kao nastupajući (pending) ali se nikada ne izvršava Uspostavljena konekcija 2 “Zamrzavanje” programa na jednom procesorskom jezgru Kod višeprocesorskog sistema zabrana prekida ne obezbeđuje uzajamno isključivanje, jer se ona odnosi samo na tekući procesor. vreme
Rešenje • Ključ (lock ili mutex) • Kada nit uđe u kritičnu sekciju, ona je zaključava tako da ne može da uđe ni jedna druga nit. Kada izlazi, ona je otključava i vraća ključ. • Koristi se deljena promenljiva tipa mutex nad kojom se, upotrebom sistemskih poziva, mogu izvršavati dve operacije: • “uzimanje ključa” (acquire ili lock): nit ekskluzivno uzima ključ, a ako ga je neko drugi već uzeo, čeka u blokiranom stanju. • “oslobađanje ključa” (release ili unlock): nit vraća ključ. • Kako koristiti? Ograditi kritičnu sekciju odgovarajućim ključem: mutex hit_lock; ... acquire(hit_lock); hits = hits + 1; release(hit_lock); kritična sekcija
Sistemski poziv • acquire(hit_lock) sistemski poziv • Stavljanje broja sistemskog poziva u registar • Softverski prekid za sistemski poziv (ili Fast Call) • Skok na odgovarajuću funkciju kernela • Verifikacija ispravnosti pointera na mutex promenljivu (prethodno je deklasirana - registrovana kod kernela) • Spin N puta čekajući da mutex brzo bude otključan • Ako je mutex zaključan, blokirati nit i staviti je u red čekanja za taj mutex • U suprotnom, zaključati mutex • Izvršavanje instrukcije hits = hits+1; • release(hit_lock) sistemski poziv • Koliki je broj N? Ovo je zamena konteksta (skupa operacija) Zato se nadamo da do nje neće doći (čest slučaj)
Broj okretaja u spinu (N) • Maksimalni broj okretaja Nmax odgovara vremenu potrebnom za zamenu konteksta (blokiranje). Više od toga se ne isplati. • Ne treba ići na maksimalan broj okretaja, jer bismo onda mogli i da blokiramo nit bez dodatnog troška. • Umesto toga treba ići na N< Nmax • Koristimo verovatnoću, npr. Random Walk: • Krenemo od neke početne vrednosti (npr. Nmax/2) • Dekrementiramo N ukoliko je poslednji pozivacquire() blokirao nit • Inkrementiramo N ukoliko poslednji pozivacquire() nije blokirao nit
Mutex u korisničkom prostoru • Neki operativni sistemi dozvoljavaju pokušaj dobijanja mutex-a u korisničkom prostoru, pa tek ako nije na raspolaganju, upotrebom sistemskog poziva ulazi se u kernel. • Primer: Windows API funkcija EnterCriticalSection(). • Za pristup mutex promenljivoj kod IA32, koriste se atomične instrukcije koje se formiraju upotrebom prefiksa lock. • Atomične instrukcije mogu da budu: ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD iXCHG. • Ukoliko se XCHG koristi sa memorijskim operandom (što kod nas jeste slučaj), automatski se primenjuje protokol zaključavanja, bez obzira na prisustvo prefiksa lock i trenutne vrednosti IOPL. • Počev od Intel Pentium Pro arhitekture, protokol zaključavanja se više ne odnosi na memorijske magistrale, već se zaključava programski kôd u L2 kešu.