diff -ru --exclude='*.o' ./inc/machine/interrupt.cc ./nachos/machine/interrupt.cc --- ./inc/machine/interrupt.cc Wed Mar 2 00:25:58 1994 +++ ./nachos/machine/interrupt.cc Sun Nov 11 17:17:37 2001 @@ -228,7 +228,7 @@ // is not reached. Instead, the halt must be invoked by the user program. DEBUG('i', "Machine idle. No interrupts to do.\n"); - printf("No threads ready or runnable, and no pending interrupts.\n"); + printf("\nNo threads ready or runnable, and no pending interrupts.\n"); printf("Assuming the program completed.\n"); Halt(); } diff -ru --exclude='*.o' ./inc/test/halt.c ./nachos/test/halt.c --- ./inc/test/halt.c Sun Nov 21 06:30:13 1993 +++ ./nachos/test/halt.c Thu Nov 29 15:00:01 2001 @@ -15,6 +15,6 @@ int main() { - Halt(); +// Halt(); /* not reached */ } diff -ru --exclude='*.o' ./inc/threads/synch.cc ./nachos/threads/synch.cc --- ./inc/threads/synch.cc Thu Jan 20 19:26:27 1994 +++ ./nachos/threads/synch.cc Tue Nov 13 18:21:41 2001 @@ -39,17 +39,29 @@ value = initialValue; queue = new List; } + +//<*** //---------------------------------------------------------------------- // Semaphore::Semaphore -// De-allocate semaphore, when no longer needed. Assume no one -// is still waiting on the semaphore! +// De-allocate semaphore, when no longer needed. +// Pokud na semaforu nekdo ceka -> chyba kernelu +// Je nutne zakazat preruseni, aby se nepreplanovalo v nevhodnou +// chvili (fronta je prazdna, zrusim frontu, ale mezitim se +// preplanuje). //---------------------------------------------------------------------- Semaphore::~Semaphore() { + IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts + ASSERT(queue->IsEmpty()); // pokud neni fronta prazdna -> chyba + // a ukonci jadro delete queue; + queue=NULL; + (void) interrupt->SetLevel(oldLevel); // re-enable interrupts } + +//***> //---------------------------------------------------------------------- // Semaphore::P @@ -66,16 +78,41 @@ { IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts - while (value == 0) { // semaphore not available + while ((value == 0) && (queue)) { // semaphore not available queue->Append((void *)currentThread); // so go to sleep currentThread->Sleep(); } - value--; // semaphore available, + if (value) + value--; // semaphore available, // consume its value (void) interrupt->SetLevel(oldLevel); // re-enable interrupts } +//<*** +//---------------------------------------------------------------------- +// Semaphore::P(int val) +// Podobna metoda jako predesla, ale semafor se snizuje o hodnotu +// val. Je tedy nutne cekat nez bude hodnota citace semaforu +// dostatecne velka. +//---------------------------------------------------------------------- + +void Semaphore::P(int val) +{ + IntStatus old; + old = interrupt->SetLevel(IntOff); + + while ((value < val) && (queue)) { // neni mozne pokracovat + queue->Append((void *)currentThread); // usni + currentThread->Sleep(); + } + value-=val; // je mozne pokracovat, dekrement + + (void) interrupt->SetLevel(old); // re-enable interrupts +} + +//***> + //---------------------------------------------------------------------- // Semaphore::V // Increment semaphore value, waking up a waiter if necessary. @@ -90,6 +127,8 @@ Thread *thread; IntStatus oldLevel = interrupt->SetLevel(IntOff); + ASSERT(queue); + thread = (Thread *)queue->Remove(); if (thread != NULL) // make thread ready, consuming the V immediately scheduler->ReadyToRun(thread); @@ -97,16 +136,687 @@ (void) interrupt->SetLevel(oldLevel); } -// Dummy functions -- so we can compile our later assignments -// Note -- without a correct implementation of Condition::Wait(), -// the test case in the network assignment won't work! -Lock::Lock(char* debugName) {} -Lock::~Lock() {} -void Lock::Acquire() {} -void Lock::Release() {} - -Condition::Condition(char* debugName) { } -Condition::~Condition() { } -void Condition::Wait(Lock* conditionLock) { ASSERT(FALSE); } -void Condition::Signal(Lock* conditionLock) { } -void Condition::Broadcast(Lock* conditionLock) { } + +//<*** +//---------------------------------------------------------------------- +// Semaphore::V(int val) +// Podobna metoda jako predesla, ale semafor se zvysuje o hodnotu +// val. +//---------------------------------------------------------------------- + +void Semaphore::V(int val) +{ + Thread *thread; + IntStatus old; + old = interrupt->SetLevel(IntOff); + + ASSERT(queue); + + thread = (Thread *)queue->Remove(); + if (thread != NULL) + scheduler->ReadyToRun(thread); + value+=val; + (void) interrupt->SetLevel(old); +} + +//---------------------------------------------------------------------- +// ZAMKY - implementace pomoci fronty +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// Lock::Lock +// Konstruktor. Inicializuje zamek. +// +// "debugName" - jmeno zamku. Urcene pro testovani. +// "ownerRelease" - pokud je TRUE (defaultni hodnota), muze zamek +// odemknout jen vlastnik zamku, tedy thread, ktery je uvnitr +// kriticke sekce +//---------------------------------------------------------------------- + +Lock::Lock(char* debugName, bool ownerRelease = TRUE) +{ + name=debugName; + locked=FALSE; + queue=new List; + useOwner = ownerRelease; +} + +//---------------------------------------------------------------------- +// Lock::~Lock +// Destruktor zamku. Pokud je zamek uzamcen nebo jeste nekdo ceka +// ve fronte na uvolneni zamku -> chyba. +// Podobne jako u semaforu je nutne zakazat preruseni. +//---------------------------------------------------------------------- + +Lock::~Lock() +{ + IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts + ASSERT(!locked); // zamek je uzamcen -> chyba + ASSERT(queue->IsEmpty()); // fronta neni prazdna -> chyba + delete queue; // zrus frontu + queue=NULL; + (void) interrupt->SetLevel(oldLevel); // re-enable interrupts +} + +//---------------------------------------------------------------------- +// Lock::Acquire +// Vyzada si zamek. Pokud je zamek uzamcen (vlastnen jinym threadem), +// tak se aktualni thread uspi a ceka az bude probuzen a eventuelne +// zamek odemcen. Jelikoz operace musi byt atomicka, je treba +// zakazat preruseni. +//---------------------------------------------------------------------- + +void Lock::Acquire() +{ + IntStatus old; + + old=interrupt->SetLevel(IntOff); // zakaz preruseni + + ASSERT(queue); // fronta neni inicializovana + // -> chyba + + while (locked) { + queue->Append((void *)currentThread); // zamek je uzamcen -> usni + currentThread->Sleep(); + } + // zamek se uvolnil + locked=TRUE; // zamkni ho + owner=currentThread; // a oznac se za vlastnika + interrupt->SetLevel(old); // povol preruseni +} + +//---------------------------------------------------------------------- +// Lock::Release +// Uvolni zamek pro cekajici thready. Pokud je useOwner TRUE (zamek +// muze uvolnit jen vlastnik) a thread volajici metodu neni vlastnik, +// nastala chyba -> vrat -1. +// Pokud neni fronta prazdna, naplanuje se dalsi cekajici thread a +// uvolni se pro nej zamek. +// Operace musi byt atomicka, je tedy treba zakazat preruseni. +//---------------------------------------------------------------------- + +int Lock::Release() +{ + Thread *thread; + IntStatus old; + + if ((useOwner == TRUE) && (!isHeldByCurrentThread())) + return -1; // kdyz zamek neni zamykaciho procesu + // a hraje se na to, tak ho neodemkne + + old = interrupt->SetLevel(IntOff); // zakaz preruseni + + ASSERT(queue); + // kdyz se preplanuje v destruktoru tesne + // za povolenim preruseni, mohl by nekdo + // zavolat Release na neplatny zamek + // (fronta uz neexistuje) -> chyba + + thread = (Thread *)queue->Remove(); // vyber z fronty jeden thread + if (thread != NULL) + scheduler->ReadyToRun(thread); // naplanuj thread, ktery byl + // vybran (pokud takovy je) + locked=FALSE; // odemkni zamek + owner=NULL; + interrupt->SetLevel(old); // povol preruseni + return 0; +} + +//---------------------------------------------------------------------- +// Lock::isHeldByCurrentThread +// Metoda vrati TRUE, pokud je vlastnikem zamku aktualni thread. +// Jinak vrati FALSE. +//---------------------------------------------------------------------- + +bool Lock::isHeldByCurrentThread() +{ + return (owner == currentThread)?TRUE:FALSE; +} + +//---------------------------------------------------------------------- +// Lock::canUnlock +// Metoda vrati TRUE, pokud aktualni thread muze odemknout zamek. +// Tzn. ze bud muze zamek odemknout kdokoli nebo je thread vlastnikem +// zamku. +//---------------------------------------------------------------------- + +bool Lock::canUnlock() +{ + return ((useOwner == FALSE) || (owner == currentThread))?TRUE:FALSE; +} + + +//---------------------------------------------------------------------- +// ZAMKY - implementace pomoci semaforu +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// SLock::SLock +// Konstruktor zamku. Inicializuje se semafor, ktery bude zamek +// reprezentovat. +// +// "debugName" - jmeno zamku. Urceno pro testovani. +// "ownerRelease" - pokud je TRUE (defaultni hodnota), muze zamek +// odemknout jen vlastnik zamku, tedy thread, ktery je uvnitr +// kriticke sekce +//---------------------------------------------------------------------- + +SLock::SLock(char* debugName, bool ownerRelease = TRUE) +{ + name=debugName; + locked=FALSE; + lock_sem=new Semaphore("Lock_Sem",1); // semafor reprezentujici zamek + // implicitne odemceny pri vzniku + useOwner = ownerRelease; +} + +//---------------------------------------------------------------------- +// SLock::~SLock +// Destruktor zamku. Pokud je zamek uzamcen nebo neni semafor +// inicializovan -> chyba, konec. +// Opet je treba zakazat preruseni. +//---------------------------------------------------------------------- + +SLock::~SLock() +{ + IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts + ASSERT(lock_sem); // semafor neni platny -> chyba + ASSERT(!locked); + delete lock_sem; // zrus semafor + lock_sem=NULL; + (void) interrupt->SetLevel(oldLevel); // re-enable interrupts +} + +//---------------------------------------------------------------------- +// SLock::Acquire +// Vyzada si zamek pomoci semaforu. Pokusi se tedy snizit hodnotu +// semaforu. Samotnou funkcnost jiz zajisti semafor. +//---------------------------------------------------------------------- + +void SLock::Acquire() +{ + IntStatus old= interrupt->SetLevel(IntOff); // zakaz preruseni + ASSERT(lock_sem); // semafor neni inic. -> chyba + lock_sem->P(); // sniz hodnotu semaforu + locked=TRUE; // uzamkni zamek + owner=currentThread; // zamknul jsem zamek -> jsem vlastnik + interrupt->SetLevel(old); // povol preruseni +} + +//---------------------------------------------------------------------- +// SLock::Release +// Uvolni zamek pomoci semaforu. Tzn. zvysi se hodnota semaforu. +// Vse se provede, jen pokud je odemceni zamku pro dany thread +// povoleno. +// Metoda vraci 0 v pripade uspechu, -1 v pripade chyby +//---------------------------------------------------------------------- + +int SLock::Release() +{ + IntStatus old= interrupt->SetLevel(IntOff); // zakaz preruseni + if ((useOwner == TRUE) && (!isHeldByCurrentThread())) return -1; + //jen vlastnik muze odemknout zamek + ASSERT(lock_sem); // semafor neni inic. + if(!locked) return -1; // aby se nestalo, ze opetovnym zavolanim Release se "hodne" odemkne ;) + locked=FALSE; // odemkni zamek + lock_sem->V(); // zvys hodnotu semaforu + owner=NULL; // jiz nejsem vlastnikem + interrupt->SetLevel(old); // povol preruseni + return 0; +} + +//---------------------------------------------------------------------- +// SLock::isHeldByCurrentThread +// Metoda vrati TRUE, pokud je vlastnikem zamku aktualni thread. +// Jinak vrati FALSE. +//---------------------------------------------------------------------- + +bool SLock::isHeldByCurrentThread() +{ + return (owner == currentThread)?TRUE:FALSE; +} + +//---------------------------------------------------------------------- +// SLock::canUnlock +// Metoda vrati TRUE, pokud aktualni thread muze odemknout zamek. +// Tzn. ze bud muze zamek odemknout kdokoli nebo je thread vlastnikem +// zamku. +//---------------------------------------------------------------------- + +bool SLock::canUnlock() +{ + return ((useOwner == FALSE) || (owner == currentThread))?TRUE:FALSE; +} + + +//---------------------------------------------------------------------- +// CONDITION VARIABLES - implementace pomoci fronty +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// Condition::Condition +// Konstruktor. Inicializuje frontu pro cekajici thready. +// +// "debugName" - jmeno. Urceno pro testovani. +//---------------------------------------------------------------------- + +Condition::Condition(char* debugName) +{ + name = debugName; + queue = new List; +} + +//---------------------------------------------------------------------- +// Condition::~Condition +// Destruktor. Pokud neni fronta cekajicich threadu prazdna -> chyba. +// Opet je treba zakazat preruseni. +//---------------------------------------------------------------------- + +Condition::~Condition() +{ + IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts + ASSERT(queue->IsEmpty()); // fronta neni prazdna -> chyba + delete queue; // zrus frontu + queue=NULL; + (void) interrupt->SetLevel(oldLevel); // re-enable interrupts +} + +//---------------------------------------------------------------------- +// Condition::Wait +// Odemkne zamek a uspi thread, nez bude probuzen metodou Signal() +// nebo Broadcast(). Po probuzeni se zamek opet uzamkne. +// Je nutne zamek implementovat, aby se neztratil nejaky signal. +// Zaroven je nutne v teto metode pred uspanim zamek odemknout, +// aby mohl byt dale vyuzivan. Pote se opet uzamkne. +//---------------------------------------------------------------------- + +void Condition::Wait(Lock* conditionLock) +{ + IntStatus old; + + old=interrupt->SetLevel(IntOff); // zakazat interrupty - aby mezi + // odemcenim zamku a uspanim procesu + // nedoslo k preplanovani, jiny proces + // neposlal Signal() nebo Broadcast() - + // ten by se totiz ztratil + ASSERT(queue); // fronta neni inic. -> chyba + + conditionLock->Release(); // odemkneme zamek, aby mohl tu promennou nekdo zmenit + queue->Append((void *)currentThread); // pridej se do fronty cekajicich + currentThread->Sleep(); // a usni + conditionLock->Acquire(); // a zase zamkneme, abychom ji mohli bezpecne testovat + (void) interrupt->SetLevel(old); // povol preruseni +} + +//---------------------------------------------------------------------- +// Condition::Signal +// Pokud existuje thread, ktery ceka ve fronte, tak se probudi. +// Tuto operaci je mozne provest jenom pri zamcenem zamku, nebot +// je nutne zajistit, aby se provadela vzdy jen jedna operace +// na jedne condition variable (aby se neztracely signaly). +//---------------------------------------------------------------------- + +void Condition::Signal(Lock* conditionLock) +{ + Thread *thread; + + IntStatus old=interrupt->SetLevel(IntOff); // zakaz preruseni + ASSERT(queue); // fronta neni inic. -> chyba + if(!conditionLock->isHeldByCurrentThread()) return; + + if ((thread = (Thread *)queue->Remove())) // vyzvedneme jeden thread z fronty + scheduler->ReadyToRun(thread); // pokud existuje, pripravi se na + // spusteni + interrupt->SetLevel(old); // povol preruseni +} + +//---------------------------------------------------------------------- +// Condition::Broadcast +// Podobne jako metoda Signal, ale probudi se vsechny cekajici +// thready. +//---------------------------------------------------------------------- + +void Condition::Broadcast(Lock* conditionLock) +{ + Thread *thread; + + IntStatus old=interrupt->SetLevel(IntOff); // zakaz preruseni + ASSERT(queue); // fronta neni inic. -> chyba + if(!conditionLock->isHeldByCurrentThread()) return; + + while ((thread = (Thread *)queue->Remove())) + scheduler->ReadyToRun(thread); + // vyzvedneme vsechny thready, ktere cekaji na dane + // cond. var., a pridaji se do fronty ke spusteni + + interrupt->SetLevel(old); // povol preruseni +} + + +//---------------------------------------------------------------------- +// CONDITION VARIABLES - implementace pomoci semaforu +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// SCondition::SCondition +// Konstruktor. Inicializuje frontu, do ktere se pro kazdy cekajici +// thread vytvori semafor, ne kterem dany thread bude cekat. +// +// "debugName" - jmeno semaforu. Urcene pro testovani. +//---------------------------------------------------------------------- + +SCondition::SCondition(char *debugName) +{ + name = debugName; + queue=new List; +} + +//---------------------------------------------------------------------- +// SCondition::~SCondition +// Destruktor. Pokud nekdo ceka na cond. var. nebo je fronta +// neinic. -> chyba +//---------------------------------------------------------------------- + +SCondition::~SCondition() +{ + IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts + ASSERT(queue); + delete queue; + queue=NULL; + (void) interrupt->SetLevel(oldLevel); // re-enable interrupts +} + +//---------------------------------------------------------------------- +// SCondition::Wait +// Podobna metod jako u cond. var. implementovanych pomoci fronty. +// Opet se pouziva jeden zamek. Rozdilem je, ze thread se neuspi +// a neprida do fronty sam, ale pro kazdy thread se vytvori novy +// semafor s hodnotou nula. Tento semafor se prida do fronty a +// snizi se mu hodnota -> thread ceka na danem semaforu. +//---------------------------------------------------------------------- + +void SCondition::Wait(Lock* conditionLock) +{ + Semaphore *cond_sem; + + IntStatus old=interrupt->SetLevel(IntOff); // zakazeme preruseni + conditionLock->Release(); // odemkneme promennou, aby k ni mohli ostatni + cond_sem = new Semaphore("cond_sem",0); // vytvorime si docasny semafor + queue->Append(cond_sem); // pridame ho do fronty cekajicich + cond_sem->P(); // a tady pockame, az nas nekdo pusti dal + conditionLock->Acquire(); // znovu si tu promennou zamkneme, abychom ji mohli bezpecne cist + delete cond_sem; // zrusime docasny semafor + interrupt->SetLevel(old); // a povolime interrupty + +} + +//---------------------------------------------------------------------- +// SCondition::Signal +// Podobne jako u implementace pomoci fronty, ale s tim rozdilem, +// ze se z fronty nevyzvedne thread, ale vyzvedne se semafor, ktery +// toto zvednuti provede. Vse se ale vykona pouze v pripade, ze +// existuje cekajici thread. +//---------------------------------------------------------------------- + +void SCondition::Signal(Lock* conditionLock) +{ + Semaphore *cond_sem; + IntStatus old=interrupt->SetLevel(IntOff); // zakaz preruseni + ASSERT(queue); // fronta neni inic. -> chyba + if(!conditionLock->isHeldByCurrentThread()) return; + if (!(queue->IsEmpty())){ // zvedneme prvni z cekajicich semaforu + cond_sem=(Semaphore *)queue->Remove(); + cond_sem->V(); + } + interrupt->SetLevel(old); // povol preruseni + +} + +//---------------------------------------------------------------------- +// SCondition:Broadcast +// Podobne jako predchozi metoda, ale vytahnu vsechny semafory +// z fronty a vsem zvednu hodnotu. +//---------------------------------------------------------------------- + +void SCondition::Broadcast(Lock* conditionLock) +{ + Semaphore *cond_sem; + + IntStatus old=interrupt->SetLevel(IntOff); // zakaz preruseni + ASSERT(queue); // fronta neni inic. -> chyba + if(!conditionLock->isHeldByCurrentThread()) return; + while (!(queue->IsEmpty())){ // zvedneme vsechny cekajici semafory + cond_sem=(Semaphore *)queue->Remove(); + cond_sem->V(); + } + interrupt->SetLevel(old); // povol preruseni +} + + +//---------------------------------------------------------------------- +// READ/WRITE ZAMKY - implementace pomoci semaforu +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// SRWLock::SRWLock +// Konstruktor zamku. Inicializuje semafor, ktery bude reprezentovat +// zamek s vychozi hodnotou rovnou maximalnimu poctu ctenaru. +// +// "debugName" - jmeno zamku. Urceno pro testovani. +//---------------------------------------------------------------------- + +SRWLock::SRWLock(char *debugName) +{ + name = debugName; + SRWLock_sem = new Semaphore("RWLock_sem",MAXREADERS); +} + +//---------------------------------------------------------------------- +// SRWLock::~SRWLock +// Destruktor zamku. +//---------------------------------------------------------------------- + +SRWLock::~SRWLock() +{ + IntStatus old = interrupt->SetLevel(IntOff); + ASSERT(SRWLock_sem); + delete SRWLock_sem; // zrus semafor + interrupt->SetLevel(old); +} + +//---------------------------------------------------------------------- +// SRWLock::Acquire_Read +// Vyzada si zamek pro cteni -> snizi se hodnota semaforu o 1, nebot +// je povoleno paralelni cteni. +//---------------------------------------------------------------------- + +void SRWLock::Acquire_Read() +{ + SRWLock_sem->P(); +} + +//---------------------------------------------------------------------- +// SRWLock::Release_Read +// Uvolni na zamku jedno misto pro ctenare. Hodnota semaforu se +// zvysi o 1. +//---------------------------------------------------------------------- + +void SRWLock::Release_Read() +{ + SRWLock_sem->V(); +} + +//---------------------------------------------------------------------- +// SRWLock::Acquire_Write +// Vyzada si zamek pro zapis -> snizi se hodnota semaforu o MAXREADERS, +// nebot je povolen pouze exkluzivni zapis. +//---------------------------------------------------------------------- + +void SRWLock::Acquire_Write() +{ + SRWLock_sem->P(MAXREADERS); +} + +//---------------------------------------------------------------------- +// SRWLock::Release_Write +// Uvolni zamek pro dalsi zapis nebo pro ctenare. Hodnota semaforu +// se zvysi o MAXREADERS +//---------------------------------------------------------------------- + +void SRWLock::Release_Write() +{ + SRWLock_sem->V(MAXREADERS); +} + + +//---------------------------------------------------------------------- +// READ/WRITE ZAMKY - implementace pomoci fronty cekajicich threadu +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// RWLock::RWLock +// Konstruktor zamku. Inicializuje jak frontu cekajicich ctenaru, +// tak frontu threadu cekajicich na zapis. Na pocatku je 0 ctenaru. +// +// "debugName" - jmeno zamku. Urceno pro testovani. +//---------------------------------------------------------------------- + +RWLock::RWLock(char *debugName) +{ + name = debugName; + readers = 0; + queue_read = new List; + queue_write = new List; +} + +//---------------------------------------------------------------------- +// RWLock::~RWLock +// Destruktor zamku. Pokud jeste nekdo ceka na prideleni zamku +// -> chyba. +//---------------------------------------------------------------------- + +RWLock::~RWLock() +{ + IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts + ASSERT((queue_read->IsEmpty()) && (queue_write->IsEmpty()) && (!readers)); + // pokud nejsou fronty cekajicich threadu prazdne + // nebo je nejaky ctenar (zapisovatel) -> chyba + delete queue_read; + delete queue_write; // zrus fronty + queue_read=NULL; + queue_write=NULL; + (void) interrupt->SetLevel(oldLevel); // re-enable interrupts +} + +//---------------------------------------------------------------------- +// RWLock::Acquire_Read +// Vyzada si zamek pro cteni. Pokud je ctenaru mnoho nebo nejaky +// thread zapisuje, bezici thread se uspi a ceka az mu bude mozne +// zamek pridelit. +//---------------------------------------------------------------------- + +void RWLock::Acquire_Read() +{ + IntStatus old; + + old = interrupt->SetLevel(IntOff); // zakaz preruseni + ASSERT(queue_read); // fronta neni inic. -> chyba + while (readers >= MAXREADERS) { // dokud je "ctoucich" mnoho, + queue_read->Append((void *)currentThread); // nebo nekdo pise, proces spi + currentThread->Sleep(); + } + readers++; // zvys aktualni pocet ctenaru na zamku + interrupt->SetLevel(old); // povol preruseni +} + +//---------------------------------------------------------------------- +// RWLock::Release_Read +// Uvolni jedno misto pro ctenare, pokud zadny thread na cteni neceka, +// vybere se z fronty threadu cekajicich na zapis jeden a ten se +// probudi, pokud takovy thread existuje. +// Zaroven se snizi pocet ctenaru na zamku. Pokud zadny nebyl -> chyba +// a vrati se -1. +//---------------------------------------------------------------------- + +int RWLock::Release_Read() +{ + IntStatus old; + Thread *thread; // kazdy ctouci proces za sebe vybere "nahradu" v pripade, + // ze nejaky dalsi proces ceka kvuli prilis mnoha ctoucim + // procesum ve fronte + + old = interrupt->SetLevel(IntOff); + + // pokud nekdo cekal na cteni, dostane (stejne jako pri implementaci + // pres semafory) prednost pred tim, kdo cekal na psani. + // pokud nikdo necekal na cteni, je v pripade existence procesu, + // ktery ceka na psani, ten pridan do ready queue + ASSERT(queue_read); + thread = (Thread *)queue_read->Remove(); + if (thread != NULL) + scheduler->ReadyToRun(thread); + if (!thread) + { + thread = (Thread *)queue_write->Remove(); + if (thread != NULL) scheduler->ReadyToRun(thread); + } + if(readers) readers--; else {interrupt->SetLevel(old);return -1;} + interrupt->SetLevel(old); + return 0; +} + +//---------------------------------------------------------------------- +// RWLock::Acquire_Write +// Vyzada si zamek pro zapis. Dokud bude pocet ctenaru na zamku vyssi +// nez 0, musi se pockat nez budou vsichni pryc. +// Pote se nastavi pocet ctenaru na MAXREADERS+1, aby do zamku jiz +// nikdo nemohl. +//---------------------------------------------------------------------- + +void RWLock::Acquire_Write() +{ + IntStatus old; + + old = interrupt->SetLevel(IntOff); // zakaz preruseni + while (readers){ // pokud je kdokoliv v kriticke sekci, + ASSERT(queue_read); // tak do ni nemuzeme + queue_write->Append((void *)currentThread); + currentThread->Sleep(); + } + readers = MAXREADERS+1; // nikoho tam nepustime + interrupt->SetLevel(old); // povol preruseni +} + +//---------------------------------------------------------------------- +// RWLock::Release_Write +// Uvolni zamek pro potencialni ctenare, resp. pro zapis. Podobne +// jako u Release_Read. +//---------------------------------------------------------------------- + +int RWLock::Release_Write() +{ + IntStatus old; + Thread *thread; + + old = interrupt->SetLevel(IntOff); // zakaz preruseni + + // pokud nekdo cekal na cteni, dostane (stejne jako pri implementaci + // pres semafory) prednost pred tim, kdo cekal na psani. + // pokud nikdo necekal na cteni, je v pripade existence procesu, + // ktery ceka na psani, ten pridan do ready queue + ASSERT(queue_read); + thread = (Thread *)queue_read->Remove(); + if (thread != NULL) + scheduler->ReadyToRun(thread); + if (!thread) + { + thread = (Thread *) queue_write->Remove(); + if (thread != NULL) + scheduler->ReadyToRun(thread); + } + if(!readers) {interrupt->SetLevel(old);return -1;} else readers=0; // umoznime vstup ostatnim + interrupt->SetLevel(old); // povol preruseni + return 0; +} + +//***> diff -ru --exclude='*.o' ./inc/threads/synch.h ./nachos/threads/synch.h --- ./inc/threads/synch.h Thu Jan 20 19:26:27 1994 +++ ./nachos/threads/synch.h Tue Nov 13 15:55:33 2001 @@ -40,11 +40,16 @@ public: Semaphore(char* debugName, int initialValue); // set initial value ~Semaphore(); // de-allocate semaphore - char* getName() { return name;} // debugging assist - - void P(); // these are the only operations on a semaphore - void V(); // they are both *atomic* + char* getName() { return name; } // debugging assist + void P(); // atomicke operace na semaforu + void V(); + +//<*** + void P(int val); // stejne jako metody P() a V(), ale citac semaforu + void V(int val); // se zvysuje respektive snizuje o hodnotu val +//***> + private: char* name; // useful for debugging int value; // semaphore value, always >= 0 @@ -65,22 +70,64 @@ class Lock { public: - Lock(char* debugName); // initialize lock to be FREE + Lock(char* debugName, bool ownerRelease = TRUE); // initialize lock to be FREE ~Lock(); // deallocate lock char* getName() { return name; } // debugging assist void Acquire(); // these are the only operations on a lock - void Release(); // they are both *atomic* + int Release(); // they are both *atomic* - bool isHeldByCurrentThread(); // true if the current thread + bool isHeldByCurrentThread(); // true if the current thread // holds this lock. Useful for // checking in Release, and in // Condition variable ops below. + +//<*** + bool canUnlock(); // Can current thread unlock this lock? +//***> + + private: + char* name; // for debugging + +//<*** + bool locked; // indikuje soucasny stav zamku (zamceno/odemceno) + Thread *owner; // thread, ktery ma zamek prave uzamcen (vlastnik zamku) + List *queue; // fronta cekajicich threadu + bool useOwner; // indikuje, zda smi zamek odemknout jen vlastnik zamku +//***> + +}; + +//<*** + +// Nasledujici trida implementuje zamky pomoci semaforu. +// K dispozici jsou stejne metody jako u predchozi tridy zamku implementovaneho +// pomoci fronty cekajicich threadu. + +class SLock { + public: + SLock(char* debugName, bool ownerRelease = TRUE); // initialize lock to be FREE + ~SLock(); // deallocate lock + char* getName() { return name; } // debugging assist + + void Acquire(); // these are the only operations on a lock + int Release(); // they are both *atomic* + + bool isHeldByCurrentThread(); // true if the current thread + // holds this lock. Useful for + // checking in Release, and in + // Condition variable ops below. + bool canUnlock(); // Can current thread unlock this lock? private: - char* name; // for debugging - // plus some other stuff you'll need to define + char* name; // for debugging + Thread *owner; // thread, ktery ma zamek prave uzamcen (vlastnik zamku) + bool locked; // indikuje soucasny stav zamku (zamceno/odemceno) + Semaphore *lock_sem; // semafor uzity pro implemenataci zamku + bool useOwner; // indikuje, zda smi zamek odemknout jen vlastnik zamku }; +//***> + // The following class defines a "condition variable". A condition // variable does not have a value, but threads may be queued, waiting @@ -121,7 +168,7 @@ ~Condition(); // deallocate the condition char* getName() { return (name); } - void Wait(Lock *conditionLock); // these are the 3 operations on + void Wait(Lock *conditionLock); // these are the 3 operations on // condition variables; releasing the // lock and going to sleep are // *atomic* in Wait() @@ -131,6 +178,91 @@ private: char* name; - // plus some other stuff you'll need to define + List *queue; // fronta cekajicich threadu +}; + +//<*** + +// Trida, ktera implementuje condition variables pomoci semaforu. +// Jsou dostupne vsechny metody jako v predchozi tride. + +class SCondition +{ + public: + SCondition(char* debugName); // initialize condition to + // "no one waiting" + ~SCondition(); // deallocate the condition + char* getName() { return (name); } + + void Wait(Lock *conditionLock); // these are the 3 operations on + // condition variables; releasing the + // lock and going to sleep are + // *atomic* in Wait() + void Signal(Lock *conditionLock); // conditionLock must be held by + void Broadcast(Lock *conditionLock);// the currentThread for all of + + private: + char* name; + List *queue; }; + + +// Nasledujici trida implementuje read/write zamky, ktere umoznuji paralelni +// cteni, ale pouze exkluzivni zapis. +// K implementaci je pouzita fronta cekajicich threadu +// K dispozici jsou nasledujici metody: +// Acquire_Read() - vyzada si zamek pro cteni. Pokud neni ctenaru vice jak +// MAXREADERS, tak je cteni povoleno. Jinak se thread uspi a ceka +// na uvolneni. +// Acquire_Write() - vyzada si zamek pro zapis. Ten je umoznen pouze v pripade, +// ze neni zadny ctenar. Jinak se thread uspi a ceka na uvolneni zamku. +// Release_Read() - uvolni jedno misto pro cteni, pokud jiz neni zadny thread cekajici +// na cteni, probudi thread cekajici na zapis. Pokud vsak jeste existuji +// nejaci ctenari, tento zapisujici thread se opet uspi a ceka na uvolneni +// zamku +// Release_Write() - uvolni zamek pro dalsi thready + +#define MAXREADERS 1000000 + // definuje, kolik maximalne readeru muze mit jede RW zamek + +class RWLock +{ + public: + RWLock(char *debugName); + ~RWLock(); + void Acquire_Read(); + void Acquire_Write(); + int Release_Read(); + int Release_Write(); + char *getName(){return name;}; + + private: + char *name; + int readers; // pocet ctenaru na zamku + List *queue_read,*queue_write; // fronty threadu cekajicich na cteni resp. zapis + +}; + + +// Nasledujici trida implementuje read/write zamky pomoci semaforu. + +class SRWLock +{ + public: + SRWLock(char *debugName); + ~SRWLock(); + void Acquire_Read(); + void Acquire_Write(); + void Release_Read(); + void Release_Write(); + char *getName(){return name;}; + + private: + char *name; + Semaphore *SRWLock_sem; // semafor, ktery bude read/write zamek reprezentovat + +}; + +//***> + #endif // SYNCH_H diff -ru --exclude='*.o' ./inc/threads/threadtest.cc ./nachos/threads/threadtest.cc --- ./inc/threads/threadtest.cc Thu Jan 20 19:29:54 1994 +++ ./nachos/threads/threadtest.cc Tue Nov 13 18:40:20 2001 @@ -12,40 +12,586 @@ #include "copyright.h" #include "system.h" +#include "synch.h" +#include +#include +#include + //---------------------------------------------------------------------- -// SimpleThread -// Loop 5 times, yielding the CPU to another ready thread -// each iteration. -// -// "which" is simply a number identifying the thread, for debugging -// purposes. +// pokud chceme provadet test, je potreba nadefinovat prislusne makro +// !! DEMO() neni vhodne provadet dohromady s jinymi testy - vypis by byl velice +// neprehledny - je-li nadefinovano makro DEMO, ma toto prednost pred ostatnimi testy //---------------------------------------------------------------------- +//#define SEMTEST +//#define LOCKTEST +//#define SLOCKTEST +//#define RWLOCKTEST +//#define SRWLOCKTEST +//#define CONDTEST +//#define SCONDTEST +#define DEMO -void -SimpleThread(int which) + +#ifdef LOCKTEST +Lock *lock1; +#endif + +#ifdef SEMTEST +Semaphore *sem1; +#endif + +#ifdef SLOCKTEST +SLock *lock2; +#endif + +#ifdef RWLOCKTEST +RWLock *rwlock1; +#endif + +#ifdef SRWLOCKTEST +SRWLock *rwlock2; +#endif + +#ifdef CONDTEST +Condition *cond1; +#endif + +#ifdef SCONDTEST +SCondition *cond2; +#endif + + +//---------------------------------------------------------------------- +// I +// funkce, ktera se s pravdepodobnosti 1/2 zpusobi, ze se proces +// vzda procesoru +//---------------------------------------------------------------------- + +void I() +{ + if(random()>(RAND_MAX/2)) currentThread->Yield(); +} + +//---------------------------------------------------------------------- +// TESTOVACI FUNKCE +// parametr which u kazde fce znamena cislo threadu. +//---------------------------------------------------------------------- + +#ifdef LOCKTEST +//---------------------------------------------------------------------- +// LockTest +// testovaci vypis zamku +// Lt - pokus o zamknuti +// LO - zamknuto +// lt - pokus o odemceni +// lO - odemceno +//---------------------------------------------------------------------- + +void LockTest(int which) { int num; + int sleep_time; - for (num = 0; num < 5; num++) { - printf("*** thread %d looped %d times\n", which, num); - currentThread->Yield(); + I();for (num = 0; num < 3; num++) { // pocet iteraci v zivotne procesu + + I();printf("%dLt,",which);lock1->Acquire(); + printf("%dLO,",which); + I();sleep_time=random()/100000; + I();usleep(sleep_time); + I();printf("%dlt,",which);if(lock1->Release()==0) + printf("%dlO,",which); + I();currentThread->Yield(); + } +} +#endif + + +#ifdef SLOCKTEST +//---------------------------------------------------------------------- +// SLockTest +// testovaci vypis zamku implementovanych pomoci semaforu +// Kt - pokus o zamknuti +// KO - zamknuto +// kt - pokus o odemceni +// kO - odemceno +//---------------------------------------------------------------------- + +void SLockTest(int which) +{ + int num; + int sleep_time; + + I();for (num = 0; num < 3; num++) { // pocet iteraci v zivotne procesu + I();printf("%dKt,",which);lock2->Acquire(); + printf("%dKO,",which); + I();sleep_time=random()/100000; + I();usleep(sleep_time); + I();printf("%dkt,",which);if(lock2->Release()==0); + printf("%dkO,",which); + I();currentThread->Yield(); + } + // +} +#endif + + +#ifdef SEMTEST +//---------------------------------------------------------------------- +// SemTest +// testovaci vypis semaforu +// St - pokus o sundani semaforu +// SO - ziskana +// st - pokus o zvednuti semaforu +// sO - zvednuto +//---------------------------------------------------------------------- + +void SemTest (int which) +{ + int num; + int sleep_time; + I();for (num = 0; num < 3; num++) { // pocet iteraci v zivotne procesu + I();printf("%dSt,",which);sem1->P(); + printf("%dSO,",which); + I();sleep_time=random()/100000; + I();usleep(sleep_time); + I();printf("%dst,",which);sem1->V(); + printf("%dsO,",which); + I();currentThread->Yield(); + } +} +#endif + + +#ifdef CONDTEST +//---------------------------------------------------------------------- +// CondTest +// testovaci vypis condition variables +// pulka procesu bude cekat, a druha pulka bude signal/broadcastovat +// CW - wait +// Cw - dostal jsem signal +// CS - signal +// CB - broadcast +//---------------------------------------------------------------------- + +void CondTest (int which) +{ + int num; + int sleep_time; + Lock *condlock; + condlock = new Lock("condlock"); + I();for (num = 0; num < 3; num++) { // pocet iteraci v zivotne procesu + I();if(random()>RAND_MAX/2) { + I(); + condlock->Acquire(); + printf("%dCW,",which); + cond1->Wait(condlock); + printf("%dCw,",which); + condlock->Release(); + I(); + } + else { + if(random()>RAND_MAX/2) {I();condlock->Acquire();printf("%dCS,",which);cond1->Signal(condlock);condlock->Release();I();} + else {I();condlock->Acquire();printf("%dCB,",which);cond1->Broadcast(condlock);condlock->Release();I();} + } + I();currentThread->Yield(); } } +#endif + + +#ifdef SCONDTEST +//---------------------------------------------------------------------- +// SCondTest +// testovaci vypis condition variables +// pulka procesu bude cekat, a druha pulka bude signal/broadcastovat +// XW - wait +// XS - signal +// XB - broadcast +//---------------------------------------------------------------------- + +void SCondTest (int which) +{ + int num; + int sleep_time; + Lock *condlock; + condlock = new Lock("condlock"); + I();for (num = 0; num < 3; num++) { // pocet iteraci v zivotne procesu + I();if(random()>RAND_MAX/2) { + condlock->Acquire(); + printf("%dXW,",which); + cond2->Wait(condlock); + printf("%dXw,",which); + condlock->Release(); + } + else { + if(random()>RAND_MAX/2) {I();condlock->Acquire();printf("%dXS,",which);cond2->Signal(condlock);condlock->Release();I();} + else {I();condlock->Acquire();printf("%dXB,",which);cond2->Broadcast(condlock);condlock->Release();I();} + } + I();currentThread->Yield(); + } +} +#endif + + +#ifdef RWLOCKTEST +//---------------------------------------------------------------------- +// RWLockTest +// testovani read/write zamku +// zamek se zamyka na zapis s pravdepodobnosti 1/6 +// Rt - pokus o zamknuti pro cteni +// RO - zamceno pro cteni +// Wt - pokus o zamknuti pro zapis +// WO - zamceno pro zapis +// rt - pokus o odemceni zamku zamceneho pro cteni +// rO - zamek zamceny pro cteni odemcen +// wt - pokus o odemceni zamku zamceneho pro zapis +// wO - zamek zamceny pro zapis odemcen +//---------------------------------------------------------------------- + +void RWLockTest(int which) +{ + int num; + int sleep_time; + char locktype; // w - write, r - read + + I();for (num = 0; num < 3; num++) { // pocet iteraci v zivotne procesu + + if(random()<(RAND_MAX/6)) {I();printf("%dWt,",which);locktype='W';rwlock1->Acquire_Write();} + else {I();printf("%dRt,",which);locktype='R';rwlock1->Acquire_Read();} + printf("%d%cO,",which,locktype); + I();sleep_time=random()/100000; + I();usleep(sleep_time); + if(locktype == 'R'){ + I();printf("%drt,",which);if(rwlock1->Release_Read()==0) + printf("%drO,",which); + I(); + } + else{ + I();printf("%dwt,",which);if(rwlock1->Release_Write()==0) + printf("%dwO,",which); + I(); + } + I();currentThread->Yield(); + } +} +#endif + +#ifdef SRWLOCKTEST +//---------------------------------------------------------------------- +// SRWLockTest +// zamek se zamyka na zapis s pravdepodobnosti 1/6 +// Et - pokus o zamknuti pro cteni +// EO - zamceno pro cteni +// Qt - pokus o zamknuti pro zapis +// QO - zamceno pro zapis +// et - pokus o odemceni zamku zamceneho pro cteni +// eO - zamek zamceny pro cteni odemcen +// qt - pokus o odemceni zamku zamceneho pro zapis +// qO - zamek zamceny pro zapis odemcen +//---------------------------------------------------------------------- + +void SRWLockTest(int which) +{ + int num; + int sleep_time; + char locktype; // q - write, e - read + + I();for (num = 0; num < 3; num++) { // pocet iteraci v zivotne procesu + + if(random()<(RAND_MAX/6)) {I();printf("%dQt,",which);locktype='Q';rwlock2->Acquire_Write();} + else {I();printf("%dEt,",which);locktype='E';rwlock2->Acquire_Read();} + printf("%d%cO,",which,locktype); + I();sleep_time=random()/100000; + I();usleep(sleep_time); + if(locktype == 'E'){ + I();printf("%det,",which);rwlock2->Release_Read(); + printf("%deO,",which); + I(); + } + else{ + I();printf("%dqt,",which);rwlock2->Release_Write(); + printf("%dqO,",which); + I(); + } + I();currentThread->Yield(); + } +} +#endif + + +//---------------------------------------------------------------------- +// DEMONSTRACNI PROGRAM +// Demonstruje vsechny druhy synchronizacnich primitiv na prikladu +// celnice (viz dokumentace). +//---------------------------------------------------------------------- + +#ifdef DEMO + +#define NUM_CAR 5 +// celkovy pocet aut, ktera maji projet pres celnici +#define KAPACITA 3 +// kolik osobnich aut se vejde na celnici + +#define LORRY_SIZE 2 +// kolik osobnich aut zabere jedno nakladni + +#define OSOBNI 0 +// normalni auto + +#define NAKLADNI 1 +// smi byt odbavovanou jako jedine na cele celnici + +#define OSOB_SPD 10000 +// priblizna rychlost odbaveni osobniho automobilu +// predstavuje zlomek + +#define NAKL_SPD 5000 +// priblizna rychlost odbaveni nakladniho automobilu +// predstavuje zlomek + + +SCondition *cond=new SCondition("Terminating CVar"); // oznamuje konec threadu +RWLock *rwl=new RWLock("Krizovatka"); // read/write lock na celnici +Semaphore *kriz=new Semaphore("Krizovatka",KAPACITA); // povoluje prijezd k celnici nekolika autum +Lock *ntl=new Lock("NThread"); // zamek na pocet threadu +int nthr=0; // pocet aktualne bezicich threadu (aut) +Lock *stl=new Lock("Stats"); // lock na statistiky +Condition *CVstat=new Condition("Statistics"); // CV na statistiky +int nakl=0, osob=0; // Pocet odbavenych osobnich a nakladnich automobilu + +void Stats(int n); + +//---------------------------------------------------------------------- +// Osobni +// Obstarava cinnost jednoho osobniho automobilu na celnici. +// Tzn. prijezd, odbaveni, odjezd apod. +//---------------------------------------------------------------------- + +void Osobni(int num) +{ + int sleep_time; + I(); + printf("K celnici prijizdi osobni automobil s cislem %d\n",num); + kriz->P(); // pokusi se vjet na celnici, pokud tam neni moc aut + I(); + printf("Osobni Auto cislo %d se dostalo k celnici a ceka na odbaveni\n", num); + rwl->Acquire_Read(); // cekam na odbaveni + I(); + printf("Osobni Auto cislo %d je odbavovano\n", num); + sleep_time=random()/OSOB_SPD; // jak dlouho se auto bude odbavovat + usleep(sleep_time); + I(); + printf("Osobni Auto cislo %d bylo odbaveno\n", num); + rwl->Release_Read(); // jsem odbaven -> uvolnim zamek + I(); + printf("Osobni Auto cislo %d opousti celnici\n", num); + kriz->V(); // uvolnuji misto na odbavisti + I(); + printf("Osobni Auto cislo %d odjizdi\n",num); + osob++; // zvysim pocet odbavenych osobnich aut + Stats(0); // vypis statistiku + +// dam vedet hlavnimu threadu, ze muj thread skoncil (odjelo osob. auto) + ntl->Acquire(); + I(); + nthr--; + cond->Broadcast(ntl); + I(); + ntl->Release(); + I(); +} + +//---------------------------------------------------------------------- +// Nakladni +// Obstarava cinnost jednoho nakladniho automobilu na celnici. +// Tzn. prijezd, odbaveni, odjezd apod. +//---------------------------------------------------------------------- + +void Nakladni(int num) +{ + int sleep_time; + + I(); + printf("K celnici prijizdi nakladni automobil s cislem %d\n",num); + kriz->P(LORRY_SIZE); // pokusi se vjet do krizovatky, pokud tam neni moc aut + I(); + printf("Nakladni Auto cislo %d se dostalo k celnici a ceka na odbaveni\n", num); + rwl->Acquire_Write(); // cekam na odbaveni + I(); + printf("Nakladni Auto cislo %d je odbavovano\n", num); + sleep_time=random()/NAKL_SPD; // jak dlouho se bude auto odbavovat + I(); + usleep(sleep_time); + I(); + printf("Nakladni Auto cislo %d bylo odbaveno\n", num); + rwl->Release_Write(); // byl jsem odbaven, uvolnim misto + I(); + printf("Nakladni Auto cislo %d opousti celnici\n", num); + kriz->V(LORRY_SIZE); // opustim celnici + I(); + printf("Nakladni Auto cislo %d odjizdi\n",num); + nakl++; // zvysim pocet odbavenych nakladnich automobilu + Stats(0); // vypisu statistiku + +// dam vedet hlavnimu threadu, ze muj thread skoncil (odjelo nakl. auto) + ntl->Acquire(); + I(); + nthr--; + cond->Broadcast(ntl); + I(); + ntl->Release(); + I(); +} + +//---------------------------------------------------------------------- +// Stat +// Vypise na obrazovku statistiku o poctu odbavenych osobnich +// a nakladnich aut +//---------------------------------------------------------------------- + +void Stats(int n) +{ + printf("===============================\n"); + printf(" Odbaveno :\n\n"); + printf(" %d OSOBNICH\n", nakl); + printf(" %d NAKLADNICH\n", osob); + printf("------------------------\n"); + printf(" %d CELKEM, %d ZBYVA\n", nakl+osob, NUM_CAR-(nakl+osob)); + printf("===============================\n"); +} + +//---------------------------------------------------------------------- +// Demo +// Hlavni thread. Vytvori nahodne osobni resp. nakladni auto +// a to pusti k celnici. Potom se chovani aut ridi podle prislusnych +// funkci Osobni resp. Nakladni. +// Celkovy pocet aut je dan konstantou NUM_CAR. +// Pote co se vytvori vsechny thread, tak tato funkce ceka az +// vsechny skonci (tj. odbavi se a odjedou vsechna auta). +//---------------------------------------------------------------------- + +void Demo() +{ + Thread *t; + + ntl->Acquire(); // tady si to zamknu - thready mi neskonci driv, nez vytvorim vsechny + + for (int i=1;i<=NUM_CAR;i++) + { + I(); + switch (random()/(RAND_MAX/2-1)) + { + case OSOBNI: // vytvorim osobni auto + I(); + nthr++; + I(); + t=new Thread("Osobni auto"); + t->Fork(Osobni, i); + break; + case NAKLADNI: // vytvorim nakladni auto + I(); + nthr++; + I(); + t=new Thread("Nakladni auto"); + t->Fork(Nakladni, i); + break; + default:printf("Mas chybu v random()!\n"); + } + } + I(); + ntl->Release(); + I(); + printf("Ceka se na projeti vsech automobilu\n"); + ntl->Acquire(); + I(); + while (nthr) // cekam, dokud neskonci vsechny thready + { + I(); + cond->Wait(ntl); // ve Wait()u se zamek odemkne, takze na nem muze cekat vic threadu a pak se zase zamkne, takze mi + // tam nikdo nepoleze + I(); + } + I(); + ntl->Release(); + printf("Celnice uz dnes odbavila stanoveny pocet automobilu a zavira se.\n"); + I(); +} +#endif //---------------------------------------------------------------------- // ThreadTest // Set up a ping-pong between two threads, by forking a thread // to call SimpleThread, and then calling SimpleThread ourselves. +// V pripade spousteni nektereho testu (pripadne dema) se +// vytvori potrebne promenne (v nasem pripade thready). //---------------------------------------------------------------------- void ThreadTest() { + DEBUG('t', "Entering SimpleTest"); +#ifndef DEMO + Thread *t[5]; +#endif + srandom(time(0)); - Thread *t = new Thread("forked thread"); +#ifdef DEMO + Demo(); +#endif - t->Fork(SimpleThread, 1); - SimpleThread(0); -} +#ifndef DEMO +#ifdef SEMTEST + sem1 = new Semaphore("semaphore1",1); + for(int i=1;i<=4;i++){ + t[i]=new Thread("forked thread"); + t[i]->Fork(SemTest, i); + } +#endif +#ifdef LOCKTEST + lock1 = new Lock("lock1"); + for(int i=1;i<=4;i++){ + t[i]=new Thread("forked thread"); + t[i]->Fork(LockTest, i); + } +#endif +#ifdef SLOCKTEST + lock2 = new SLock("lock2"); + for(int i=1;i<=4;i++){ + t[i]=new Thread("forked thread"); + t[i]->Fork(SLockTest, i); + } + +#endif +#ifdef CONDTEST + cond1 = new Condition("condition var 1"); + for(int i=1;i<=4;i++){ + t[i]=new Thread("forked thread"); + t[i]->Fork(CondTest, i); + } +#endif +#ifdef SCONDTEST + cond2 = new SCondition("condition var 1"); + for(int i=1;i<=4;i++){ + t[i]=new Thread("forked thread"); + t[i]->Fork(SCondTest, i); + } +#endif +#ifdef RWLOCKTEST + rwlock1 = new RWLock("rwlock1"); + for(int i=1;i<=4;i++){ + t[i]=new Thread("forked thread"); + t[i]->Fork(RWLockTest, i); + } +#endif +#ifdef SRWLOCKTEST + rwlock2 = new SRWLock("rwlock2"); + for(int i=1;i<=4;i++){ + t[i]=new Thread("forked thread"); + t[i]->Fork(SRWLockTest, i); + } +#endif +#endif + +} diff -ru --exclude='*.o' ./inc/userprog/syscall.h ./nachos/userprog/syscall.h --- ./inc/userprog/syscall.h Sun Nov 21 06:54:22 1993 +++ ./nachos/userprog/syscall.h Thu Nov 29 15:08:56 2001 @@ -32,6 +32,8 @@ #ifndef IN_ASM +#warning WRN - BEZ HLAVICKY + /* The system call interface. These are the operations the Nachos * kernel needs to support, to be able to run user programs. * diff -ru --exclude='*.o' ./inc/vm/Makefile ./nachos/vm/Makefile --- ./inc/vm/Makefile Tue Sep 28 06:35:18 1999 +++ ./nachos/vm/Makefile Fri Dec 7 19:42:36 2001 @@ -31,274 +31,315 @@ # DO NOT DELETE THIS LINE -- make depend uses it # DEPENDENCIES MUST END AT END OF FILE main.o: ../threads/main.cc ../threads/copyright.h ../threads/utility.h \ - ../machine/sysdep.h /usr/include/stdio.h /usr/include/features.h \ - /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../threads/system.h ../threads/thread.h \ - ../machine/machine.h ../machine/translate.h ../machine/disk.h \ - ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ - ../threads/scheduler.h ../threads/list.h ../machine/interrupt.h \ - ../machine/stats.h ../machine/timer.h + ../machine/sysdep.h /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../threads/system.h \ + ../threads/thread.h ../machine/machine.h ../machine/translate.h \ + ../machine/disk.h ../userprog/addrspace.h ../filesys/filesys.h \ + ../filesys/openfile.h ../threads/scheduler.h ../threads/list.h \ + ../machine/interrupt.h ../machine/stats.h ../machine/timer.h list.o: ../threads/list.cc ../threads/copyright.h ../threads/list.h \ - ../threads/utility.h ../machine/sysdep.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h + ../threads/utility.h ../machine/sysdep.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h scheduler.o: ../threads/scheduler.cc ../threads/copyright.h \ - ../threads/scheduler.h ../threads/list.h ../threads/utility.h \ - ../machine/sysdep.h /usr/include/stdio.h /usr/include/features.h \ - /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../threads/thread.h ../machine/machine.h \ - ../machine/translate.h ../machine/disk.h ../userprog/addrspace.h \ - ../filesys/filesys.h ../filesys/openfile.h ../threads/system.h \ - ../machine/interrupt.h ../machine/stats.h ../machine/timer.h + ../threads/scheduler.h ../threads/list.h ../threads/utility.h \ + ../machine/sysdep.h /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../threads/thread.h \ + ../machine/machine.h ../machine/translate.h ../machine/disk.h \ + ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ + ../threads/system.h ../machine/interrupt.h ../machine/stats.h \ + ../machine/timer.h synch.o: ../threads/synch.cc ../threads/copyright.h ../threads/synch.h \ - ../threads/thread.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../machine/machine.h ../machine/translate.h \ - ../machine/disk.h ../userprog/addrspace.h ../filesys/filesys.h \ - ../filesys/openfile.h ../threads/list.h ../threads/system.h \ - ../threads/scheduler.h ../machine/interrupt.h ../machine/stats.h \ - ../machine/timer.h + ../threads/thread.h ../threads/utility.h ../machine/sysdep.h \ + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h \ + ../machine/machine.h ../machine/translate.h ../machine/disk.h \ + ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ + ../threads/list.h ../threads/system.h ../threads/scheduler.h \ + ../machine/interrupt.h ../machine/stats.h ../machine/timer.h synchlist.o: ../threads/synchlist.cc ../threads/copyright.h \ - ../threads/synchlist.h ../threads/list.h ../threads/utility.h \ - ../machine/sysdep.h /usr/include/stdio.h /usr/include/features.h \ - /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../threads/synch.h ../threads/thread.h \ - ../machine/machine.h ../machine/translate.h ../machine/disk.h \ - ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h -system.o: ../threads/system.cc ../threads/copyright.h \ - ../threads/system.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../threads/thread.h ../machine/machine.h \ - ../machine/translate.h ../machine/disk.h ../userprog/addrspace.h \ - ../filesys/filesys.h ../filesys/openfile.h ../threads/scheduler.h \ - ../threads/list.h ../machine/interrupt.h ../machine/stats.h \ - ../machine/timer.h -thread.o: ../threads/thread.cc ../threads/copyright.h \ - ../threads/thread.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../machine/machine.h ../machine/translate.h \ - ../machine/disk.h ../userprog/addrspace.h ../filesys/filesys.h \ - ../filesys/openfile.h ../threads/switch.h ../threads/synch.h \ - ../threads/list.h ../threads/system.h ../threads/scheduler.h \ - ../machine/interrupt.h ../machine/stats.h ../machine/timer.h + ../threads/synchlist.h ../threads/list.h ../threads/utility.h \ + ../machine/sysdep.h /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../threads/synch.h \ + ../threads/thread.h ../machine/machine.h ../machine/translate.h \ + ../machine/disk.h ../userprog/addrspace.h ../filesys/filesys.h \ + ../filesys/openfile.h +system.o: ../threads/system.cc ../threads/copyright.h ../threads/system.h \ + ../threads/utility.h ../machine/sysdep.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../threads/thread.h \ + ../machine/machine.h ../machine/translate.h ../machine/disk.h \ + ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ + ../threads/scheduler.h ../threads/list.h ../machine/interrupt.h \ + ../machine/stats.h ../machine/timer.h +thread.o: ../threads/thread.cc ../threads/copyright.h ../threads/thread.h \ + ../threads/utility.h ../machine/sysdep.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h \ + ../machine/machine.h ../machine/translate.h ../machine/disk.h \ + ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ + ../threads/switch.h ../threads/synch.h ../threads/list.h \ + ../threads/system.h ../threads/scheduler.h ../machine/interrupt.h \ + ../machine/stats.h ../machine/timer.h utility.o: ../threads/utility.cc ../threads/copyright.h \ - ../threads/utility.h ../machine/sysdep.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h + ../threads/utility.h ../machine/sysdep.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h threadtest.o: ../threads/threadtest.cc ../threads/copyright.h \ - ../threads/system.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../threads/thread.h ../machine/machine.h \ - ../machine/translate.h ../machine/disk.h ../userprog/addrspace.h \ - ../filesys/filesys.h ../filesys/openfile.h ../threads/scheduler.h \ - ../threads/list.h ../machine/interrupt.h ../machine/stats.h \ - ../machine/timer.h + ../threads/system.h ../threads/utility.h ../machine/sysdep.h \ + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../threads/thread.h \ + ../machine/machine.h ../machine/translate.h ../machine/disk.h \ + ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ + ../threads/scheduler.h ../threads/list.h ../machine/interrupt.h \ + ../machine/stats.h ../machine/timer.h ../threads/synch.h \ + /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \ + /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/bits/time.h \ + /usr/include/sys/sysmacros.h /usr/include/alloca.h \ + /usr/include/unistd.h /usr/include/bits/posix_opt.h \ + /usr/include/bits/confname.h /usr/include/getopt.h interrupt.o: ../machine/interrupt.cc ../threads/copyright.h \ - ../machine/interrupt.h ../threads/list.h ../threads/utility.h \ - ../machine/sysdep.h /usr/include/stdio.h /usr/include/features.h \ - /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../threads/system.h ../threads/thread.h \ - ../machine/machine.h ../machine/translate.h ../machine/disk.h \ - ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ - ../threads/scheduler.h ../machine/stats.h ../machine/timer.h + ../machine/interrupt.h ../threads/list.h ../threads/utility.h \ + ../machine/sysdep.h /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../threads/system.h \ + ../threads/thread.h ../machine/machine.h ../machine/translate.h \ + ../machine/disk.h ../userprog/addrspace.h ../filesys/filesys.h \ + ../filesys/openfile.h ../threads/scheduler.h ../machine/stats.h \ + ../machine/timer.h sysdep.o: ../machine/sysdep.cc ../threads/copyright.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h /usr/include/signal.h \ - /usr/include/bits/sigset.h /usr/include/bits/signum.h \ - /usr/include/time.h /usr/include/bits/siginfo.h \ - /usr/include/bits/sigaction.h /usr/include/bits/sigcontext.h \ - /usr/include/asm/sigcontext.h /usr/include/bits/sigstack.h \ - /usr/include/sys/types.h /usr/include/endian.h \ - /usr/include/bits/endian.h /usr/include/sys/select.h \ - /usr/include/bits/select.h /usr/include/sys/sysmacros.h \ - /usr/include/sys/time.h /usr/include/bits/time.h \ - /usr/include/sys/socket.h /usr/include/bits/socket.h \ - /usr/include/bits/sockaddr.h /usr/include/asm/socket.h \ - /usr/include/asm/sockios.h /usr/include/sys/file.h \ - /usr/include/fcntl.h /usr/include/bits/fcntl.h /usr/include/sys/un.h \ - /usr/include/sys/mman.h /usr/include/bits/mman.h \ - ../machine/interrupt.h ../threads/list.h ../threads/utility.h \ - ../machine/sysdep.h ../threads/system.h ../threads/thread.h \ - ../machine/machine.h ../machine/translate.h ../machine/disk.h \ - ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ - ../threads/scheduler.h ../machine/stats.h ../machine/timer.h \ - /usr/include/unistd.h /usr/include/bits/posix_opt.h \ - /usr/include/bits/confname.h /usr/include/getopt.h -stats.o: ../machine/stats.cc ../threads/copyright.h \ - ../threads/utility.h ../machine/sysdep.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../machine/stats.h + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h \ + /usr/include/signal.h /usr/include/bits/sigset.h \ + /usr/include/bits/signum.h /usr/include/time.h \ + /usr/include/bits/siginfo.h /usr/include/bits/wordsize.h \ + /usr/include/bits/sigaction.h /usr/include/bits/sigcontext.h \ + /usr/include/asm/sigcontext.h /usr/include/bits/sigstack.h \ + /usr/include/bits/sigthread.h /usr/include/sys/types.h \ + /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/time.h /usr/include/sys/sysmacros.h \ + /usr/include/sys/time.h /usr/include/sys/socket.h \ + /usr/include/sys/uio.h /usr/include/bits/uio.h \ + /usr/include/bits/socket.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/bits/sockaddr.h \ + /usr/include/asm/socket.h /usr/include/asm/sockios.h \ + /usr/include/sys/file.h /usr/include/fcntl.h /usr/include/bits/fcntl.h \ + /usr/include/sys/un.h /usr/include/sys/mman.h /usr/include/bits/mman.h \ + ../machine/interrupt.h ../threads/list.h ../threads/utility.h \ + ../machine/sysdep.h ../threads/system.h ../threads/thread.h \ + ../machine/machine.h ../machine/translate.h ../machine/disk.h \ + ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ + ../threads/scheduler.h ../machine/stats.h ../machine/timer.h \ + /usr/include/unistd.h /usr/include/bits/posix_opt.h \ + /usr/include/bits/confname.h /usr/include/getopt.h +stats.o: ../machine/stats.cc ../threads/copyright.h ../threads/utility.h \ + ../machine/sysdep.h /usr/include/stdio.h /usr/include/features.h \ + /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../machine/stats.h timer.o: ../machine/timer.cc ../threads/copyright.h ../machine/timer.h \ - ../threads/utility.h ../machine/sysdep.h /usr/include/stdio.h \ - /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../threads/system.h ../threads/thread.h \ - ../machine/machine.h ../machine/translate.h ../machine/disk.h \ - ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ - ../threads/scheduler.h ../threads/list.h ../machine/interrupt.h \ - ../machine/stats.h + ../threads/utility.h ../machine/sysdep.h /usr/include/stdio.h \ + /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../threads/system.h \ + ../threads/thread.h ../machine/machine.h ../machine/translate.h \ + ../machine/disk.h ../userprog/addrspace.h ../filesys/filesys.h \ + ../filesys/openfile.h ../threads/scheduler.h ../threads/list.h \ + ../machine/interrupt.h ../machine/stats.h addrspace.o: ../userprog/addrspace.cc ../threads/copyright.h \ - ../threads/system.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../threads/thread.h ../machine/machine.h \ - ../machine/translate.h ../machine/disk.h ../userprog/addrspace.h \ - ../filesys/filesys.h ../filesys/openfile.h ../threads/scheduler.h \ - ../threads/list.h ../machine/interrupt.h ../machine/stats.h \ - ../machine/timer.h ../bin/noff.h + ../threads/system.h ../threads/utility.h ../machine/sysdep.h \ + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../threads/thread.h \ + ../machine/machine.h ../machine/translate.h ../machine/disk.h \ + ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ + ../threads/scheduler.h ../threads/list.h ../machine/interrupt.h \ + ../machine/stats.h ../machine/timer.h ../bin/noff.h bitmap.o: ../userprog/bitmap.cc ../threads/copyright.h \ - ../userprog/bitmap.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../filesys/openfile.h + ../userprog/bitmap.h ../threads/utility.h ../machine/sysdep.h \ + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h \ + ../filesys/openfile.h exception.o: ../userprog/exception.cc ../threads/copyright.h \ - ../threads/system.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../threads/thread.h ../machine/machine.h \ - ../machine/translate.h ../machine/disk.h ../userprog/addrspace.h \ - ../filesys/filesys.h ../filesys/openfile.h ../threads/scheduler.h \ - ../threads/list.h ../machine/interrupt.h ../machine/stats.h \ - ../machine/timer.h ../userprog/syscall.h + ../threads/system.h ../threads/utility.h ../machine/sysdep.h \ + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../threads/thread.h \ + ../machine/machine.h ../machine/translate.h ../machine/disk.h \ + ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ + ../threads/scheduler.h ../threads/list.h ../machine/interrupt.h \ + ../machine/stats.h ../machine/timer.h ../userprog/syscall.h progtest.o: ../userprog/progtest.cc ../threads/copyright.h \ - ../threads/system.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../threads/thread.h ../machine/machine.h \ - ../machine/translate.h ../machine/disk.h ../userprog/addrspace.h \ - ../filesys/filesys.h ../filesys/openfile.h ../threads/scheduler.h \ - ../threads/list.h ../machine/interrupt.h ../machine/stats.h \ - ../machine/timer.h ../machine/console.h ../threads/synch.h + ../threads/system.h ../threads/utility.h ../machine/sysdep.h \ + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../threads/thread.h \ + ../machine/machine.h ../machine/translate.h ../machine/disk.h \ + ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ + ../threads/scheduler.h ../threads/list.h ../machine/interrupt.h \ + ../machine/stats.h ../machine/timer.h ../machine/console.h \ + ../threads/synch.h console.o: ../machine/console.cc ../threads/copyright.h \ - ../machine/console.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../threads/system.h ../threads/thread.h \ - ../machine/machine.h ../machine/translate.h ../machine/disk.h \ - ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ - ../threads/scheduler.h ../threads/list.h ../machine/interrupt.h \ - ../machine/stats.h ../machine/timer.h + ../machine/console.h ../threads/utility.h ../machine/sysdep.h \ + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h ../threads/system.h \ + ../threads/thread.h ../machine/machine.h ../machine/translate.h \ + ../machine/disk.h ../userprog/addrspace.h ../filesys/filesys.h \ + ../filesys/openfile.h ../threads/scheduler.h ../threads/list.h \ + ../machine/interrupt.h ../machine/stats.h ../machine/timer.h machine.o: ../machine/machine.cc ../threads/copyright.h \ - ../machine/machine.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../machine/translate.h ../machine/disk.h \ - ../threads/system.h ../threads/thread.h ../userprog/addrspace.h \ - ../filesys/filesys.h ../filesys/openfile.h ../threads/scheduler.h \ - ../threads/list.h ../machine/interrupt.h ../machine/stats.h \ - ../machine/timer.h /usr/include/unistd.h \ - /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \ - /usr/include/getopt.h + ../machine/machine.h ../threads/utility.h ../machine/sysdep.h \ + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h \ + ../machine/translate.h ../machine/disk.h ../threads/system.h \ + ../threads/thread.h ../userprog/addrspace.h ../filesys/filesys.h \ + ../filesys/openfile.h ../threads/scheduler.h ../threads/list.h \ + ../machine/interrupt.h ../machine/stats.h ../machine/timer.h \ + /usr/include/unistd.h /usr/include/bits/posix_opt.h \ + /usr/include/bits/confname.h /usr/include/getopt.h mipssim.o: ../machine/mipssim.cc ../threads/copyright.h \ - ../machine/machine.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../machine/translate.h ../machine/disk.h \ - ../machine/mipssim.h ../threads/system.h ../threads/thread.h \ - ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ - ../threads/scheduler.h ../threads/list.h ../machine/interrupt.h \ - ../machine/stats.h ../machine/timer.h + ../machine/machine.h ../threads/utility.h ../machine/sysdep.h \ + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h \ + ../machine/translate.h ../machine/disk.h ../machine/mipssim.h \ + ../threads/system.h ../threads/thread.h ../userprog/addrspace.h \ + ../filesys/filesys.h ../filesys/openfile.h ../threads/scheduler.h \ + ../threads/list.h ../machine/interrupt.h ../machine/stats.h \ + ../machine/timer.h translate.o: ../machine/translate.cc ../threads/copyright.h \ - ../machine/machine.h ../threads/utility.h ../machine/sysdep.h \ - /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ - /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h \ - /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h \ - /usr/include/bits/types.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/bits/stdio_lim.h \ - /usr/include/string.h ../machine/translate.h ../machine/disk.h \ - ../userprog/addrspace.h ../filesys/filesys.h ../filesys/openfile.h \ - ../threads/system.h ../threads/thread.h ../threads/scheduler.h \ - ../threads/list.h ../machine/interrupt.h ../machine/stats.h \ - ../machine/timer.h + ../machine/machine.h ../threads/utility.h ../machine/sysdep.h \ + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ + /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \ + /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/string.h \ + ../machine/translate.h ../machine/disk.h ../userprog/addrspace.h \ + ../filesys/filesys.h ../filesys/openfile.h ../threads/system.h \ + ../threads/thread.h ../threads/scheduler.h ../threads/list.h \ + ../machine/interrupt.h ../machine/stats.h ../machine/timer.h # DEPENDENCIES MUST END AT END OF FILE # IF YOU PUT STUFF HERE IT WILL GO AWAY # see make depend above Only in ./nachos/vm: nachos Only in ./nachos/vm: swtch.s