Nachos 2
Nachos 2
January,2008
Md TanvirAlAmin
Nachos is an instructional operating system designed by Thomas Anderson at University of California, Berkeley. Originally written in
C++for MIPS, Nachos runs as a userprocess on a hostOS. Here, in this report we have discussed our work about adding multiprogrammingfacilityandconsolesupportinnachos3.4
[Nachos]Multiprogramming,Processmanagementandconsole
1[Nachos]Multiprogramming, Processmanagementandconsole
WHENNACHOSREALLYLOOKSLIKEANOPERATINGSYSTEM
We can do meaningful operations with Nachos at kernel level, without even thinking of any user. Thats exactly what we did for Threading and Synchronization assignment. Nachos was acting just as a thread packageScheduling,RunningandSwitchingbetweennonpreemptivekernelthreads. But, by definition, an operation system is to be a system organizer on behalf of the user, running in supervisormode,directlycommunicatingwithhardwareandpresentingsomelevelofabstraction[1][2].
1.1SOMEBACKGROUND
User Program and Its difference with Kernel
An user program is a sequence of instructions for a specific machine, which it can directly execute by loading in memory. Full instruction set of an architecture isnt available for a user program. To ensure safety, security and consistency of kernel data structures, certain memory locations and instructions are availabletothekernelonly,i.e.theyareavailableonlyinsupervisormode. Kernel runs in supervisor mode (or kernel mode) and as a manager for all resources available, it works on behalfoftheuser.Kernelloadsoneormanyofthoseuserprogramsinmemory,allocatesanddeallocates memory,registersandfreesupresources. There are two extreme ends in OS design. One is monolithic approach, and the another is microkernel based. In monolithic design, entire kernel is loaded as a single big program in single address space. Each partofitcanaccessotherpartsorvariablesandcancallanyfunctionresidingintheaddressspace.Ifthere is fatal bug in a single portion, the entire kernel is hooked up and we need to restart the machine. Monolithickernelisfast,andifwellwrittenandbugfreeisbestsuitedforperformance. On the other end is Microkernel. Just most necessary functions are part of kernel hence the name microkernel. And rest of the operations are written as services. Servers operate in user mode and one servercancommunicatewithanotherviamessagepassing.Thegoodpointisthatifanymodulesfail,the systemdoesnthangandjustrestartingthatserviceusuallysolvestheproblem.ThebadpointisthatThe good point comes only after a penalty paid in performance. Windows NT initially was designed with
Page1
[Nachos]Multiprogramming,Processmanagementandconsole
microkernel approach. Though it resulted in maintainable modular code, they eventually had to move mostofthepartstokerneltomakeitasuccessfulbusinessproduct. So we can understand, Kernel is what runs in supervisor mode, and all other is user programs [1]. Compilers, window managers, and utility programs packaged with a typical operating system are actually userprogramsthoughtheyarepartofsystemsoftware.SoalltheLinuxdistributionsarebasicallysame.If wedontalterthekernelcode,theydifferonlyinprovidedutilityprograms.
1.2USINGUSERPROGRAMSINDEFAULTIMPLEMENTATIONINNACHOS
Nachosstartsupexecutionatmain()functioninthreads/main.cc.ThereareblocksforTHREADS, USER_PROGRAM,NETWORK,FILE_SYSTEMtests.Herewewillworkwithuserprogramtests.The defaultnachosimplementationcanjustrunasingleuserprogramspecifiedincommandline. Totestuserprogramswewillrunthehaltprogram.Itisintestdirectory.Wehavetoenteruserprog directoryandrunnachoslike cd userprog ./nachos x ../test/halt Thehalt.cprogramiswrittenas:
#include "syscall.h" int main() { Halt(); /* not reached */ }
Page2
[Nachos]Multiprogramming,Processmanagementandconsole
Commandsforcompilingthisuserprogramwhennachosiscompiledisincludedintestdirectorys Makefile,as
halt.o: halt.c $(CC) $(CFLAGS) -c halt.c halt: halt.o start.o $(LD) $(LDFLAGS) start.o halt.o -o halt.coff ../bin/coff2noff halt.coff halt
Note : The test directory contains many user programs. But with default implementation, only halt.c will work and the others will signal illegal operations, because those programs contains system calls and console writes which are not yet implemented. Only SC_Halt is implemented in userprog/exeception.cc
Page3
[Nachos]Multiprogramming,Processmanagementandconsole
1.3HOWNACHOSWORKSINUSERPROGRAMMODE
Ifxisspecified,main()functionin/threads/main.cclooksforauserprogramincommandline.Ifoneis foundStartProcess(.)iscalledtoexecutethatfile.Ifcisfoundconsoletestdemoruns. StartProcessisinuserprog/progtest.cc This function opens the executable file, creates an address space for it, attaches the address space with current Thread, initializes registers for the new user process and calls machine>Run() in machine/mipssim.cc.Creatingtheaddressspacemeansallocatingmemory,specifyingtest,dataandstack segments, loading instruction text in the text segment from NOFF format executable (NOFF = Nachos ObjectFileFormat).Formoredetailschecktheuserprog/addrspace.ccfile. Foreaseofchecking,importantlinesareshowninredboldinfollowingcodeblocks.Debugandroutine taskcodelinesaregrayed.
void StartProcess(char *filename) { OpenFile *executable = fileSystem->Open(filename); AddrSpace *space; if (executable == NULL) { printf("Unable to open file %s\n", filename); return; } space = new AddrSpace(executable); currentThread->space = space; delete executable; space->InitRegisters(); space->RestoreState(); machine->Run(); ASSERT(FALSE); } // close file // set the initial register values // load page table register // jump to the user progam // machine->Run never returns; // the address space exits // by doing the syscall "exit"
[Nachos]Multiprogramming,Processmanagementandconsole
if(DebugIsEnabled('m')) printf("Starting thread \"%s\" at time %d\n", currentThread->getName(), stats->totalTicks); interrupt->setStatus(UserMode); for (;;) { OneInstruction(instr); interrupt->OneTick(); if (singleStep && (runUntilTime <= stats->totalTicks)) Debugger(); } }
void Interrupt::OneTick() { MachineStatus old = status; // advance simulated time if (status == SystemMode) { stats->totalTicks += SystemTick; stats->systemTicks += SystemTick; } else { // USER_PROGRAM stats->totalTicks += UserTick; stats->userTicks += UserTick; } DEBUG('i', "\n== Tick %d ==\n", stats->totalTicks); // check any pending interrupts are now ready to fire ChangeLevel(IntOn, IntOff); // first, turn off interrupts // (interrupt handlers run with // interrupts disabled) while (CheckIfDue(FALSE)) // check for pending interrupts ; ChangeLevel(IntOff, IntOn); // re-enable interrupts if (yieldOnReturn) { // if the timer device handler asked // for a context switch, ok to do it now yieldOnReturn = FALSE; status = SystemMode; // yield is a kernel routine currentThread->Yield(); status = old; } }
Page5
[Nachos]Multiprogramming,Processmanagementandconsole
As we can see where, there is a provision for Thread yield in Interrupt::OneTick. If rs switch is specified, threads areset to be subject to random switchingat defined points, then Interrupt::OneTick may switch a context.(Nachosdonthavetimeslicingimplemented). If current Thread is not yielded control again returns inside Machine::Run(), it fetches another instruction accordingtoPCviaregisters[PCReg] andexecutesit. Atthelastofuserprogramitcalls(automaticallyadded)theSC_Haltsystemcall.Thissystemcallismeant to do necessary process management (to be added by the student) and clean up tasks when a process terminates.
1.4NACHOSSYSTEMCALLS
Checkthefileuserprog/syscall.handyouwillfinddeclarationsfornachossystemcalls.
#define #define #define #define #define #define #define #define #define #define #define SC_Halt SC_Exit SC_Exec SC_Join SC_Create SC_Open SC_Read SC_Write SC_Close SC_Fork SC_Yield 0 1 2 3 4 5 6 7 8 9 10
Exceptionsorinterruptsarethewayauserprogramtakeservicefromkernel,i.ekernelwillrunoncontext oftheuserprogram.Whenauserprogramisrunningisusermode,thereisnowaytodirectlygotokernel mode. Rather every CPU provides special instructions to trap in Special places in memory, which contains interrupt/exception handlers not alterable by the user and control is returned to kernel code in kernel mode.Thissystemis forsecurity andconsistency.When asystem call occurs, a SyscallExceptionisRaised in MIPS [7]. For details on the actual MIPS cpu mechanism refer to the Computer Organization and Design booksbyHenessyandPatterson. CheckthefollowingredportioninsideMachine::OneInstruction()functioninmachine/mipssim.cc
case OP_SYSCALL: RaiseException(SyscallException, 0); return; case OP_XOR: registers[instr->rd] = registers[instr->rs] ^ registers[instr->rt]; break;
Page6
[Nachos]Multiprogramming,Processmanagementandconsole
Hint : Try to find why the OP_XOR case in has a break but OP_SYSCALL has a return . You should be able to find it out by yourself, when you understand the different types of exceptions that may occur and associated actions.
Machine::RaiseExceptionisinmachine/machine.cc RaiseException saves address of the exception creating instruction, changes to Kernel Mode and calls the ExceptionHandler (Interrupt Handlers for Intel 80X86 architectures), where control reappears as kernel mode. When returning from Handling the exception it again returns to UserMode again, as highlighted in violetinthecodeblockbelow.
void Machine::RaiseException(ExceptionType which, int badVAddr) { DEBUG('m', "Exception: %s\n", exceptionNames[which]); // ASSERT(interrupt->getStatus() == UserMode); registers[BadVAddrReg] = badVAddr; DelayedLoad(0, 0); // finish anything in progress interrupt->setStatus(SystemMode); ExceptionHandler(which); // interrupts are enabled at this point interrupt->setStatus(UserMode);
So we learn, basically this is the way control switches from the program running in user mode to kernel. Kernel will run in the context of that program. A running user program can return to kernel due to hardware interrupts, software exceptions, errors. Clock ticks are also hardware exceptions. In real hardware when a clock tick occurs, the clock tick exception handler take some scheduling decisions about ifacontextswitchistobedoneorwhethersomeprogrammoreeligiblefortheCPUiswaiting. A process is created or halted, a program asks for read or write operations, asks to spawn a thread or to join another thread, claims dynamic memory or resources or asks for some other operating system assistance everything is done via system calls, and these provide ample opportunity for the kernel to takecontrolback,dosometasksandreturntouseragain. ExceptionHandlerisinuserprog/exception.ccDefaultimplementationismeagerandimplementsonly SC_Halt,whichjusthaltsthemachine.AllothercallsaresignaledwithFalseAssertion.
void ExceptionHandler(ExceptionType which) { int type = machine->ReadRegister(2); if ((which == SyscallException) && (type == SC_Halt)) {
Page7
[Nachos]Multiprogramming,Processmanagementandconsole
DEBUG('a', "Shutdown, initiated by user program.\n"); interrupt->Halt(); } else { printf("Unexpected user mode exception %d %d\n", which, type); ASSERT(FALSE); } }
ForNachos2assignmentwehavetofillthisExceptionHandlerupforatleast5moreexceptions. ChecktheNachosPrimerdocument[4]fordetailsaboutNachosmachinesimulation.
Notes: When in actual hardware, implementing system calls requires a control transfer which involves some sort of architecture specific feature. A typical way to implement this is to use a software interrupt or trap. Interrupts transfer control to the kernel so software simply needs to set up some register with the system call number they want and execute the software interrupt. For MIPS there is a SYSCALL instruction. With Intel CPU, we can trap to kernel mode via INT instruction. Pentium II provides fast system call interface via SYSENTER and SYSEXIT instructions.
1.5NACHOSCONSOLE
Gotouserprogdirectory,andstartnachosas ./nachos c Nachosconsoledemo(ConsoleTestfunction)willstart,whichjustprintswhatuserhavewritten. ConsoleTestfunctionisinuserprog/progtest.cc.Itshowshowtoimplementandsynchronizeashared console,whentherearemultipleprocesses.
Page8
[Nachos]Multiprogramming,Processmanagementandconsole
1.6TASKSTOPERFORM
DefaultNachosexecutesuserprogramsonlyusingasimplememorymodel(checkaddrspace.cc),andonly one program can run at a time. We have to alter address space creation in such way so that multiprogramming is supported, and several user programs can reside in the provided memory and one program cant access other programs memory area (memory protection). Each user program will use its addressspaceasifitistheonlyprogramrunninginaFlatmodel(i.e.Memorymanagementwillbedoneby Nachos, not the user program). In short we have to implement page table based virtual memory scheme [1]tosupportmultiprogramming. UserprocessesaremeanttohaveprocessId.Oneuserprocesscancreateanotheruserprocess,sothereis a tree hierarchy. Parent can also wait for the child. We have to add support for process management, so that process parent child relationships are maintained in a data structure. Proper actions are taken for the casesparentexitsbeforechild,parentnevercallsjoinorparentcallsjoinandchildisalreadyexitedandso on. So we need to add classes and related functions so that process management is done when a user programcreated,exitsandJoinsotherprogram. To implement a fault free console for user i/o, we have to write synchronized console class. The ConsoleTestwillprovidecluesforasynchronizedconsole. Wehavetowritesystemcallhandlerssothatanewuserprogramcanbecreated(similartoforkinlinux, but not like the thread Fork of nachos), one process can wait for another and user program is supported with Read and Write operations. So in exception.cc, we have to write system calls handlers for SC_Exec, SC_Exit,SC_Write,SC_Read,SC_JoinsothatMultiprogramming,ConsoleI/OandProcessManagement issupported.CheckNachos2assignment[8]descriptionfordetailedspecification. In our implementation we also implemented PageFaultException handler so that swapping of memory pagesinandoutofswapspacewasalsosupported. Tocompletetheprojectsuccessfully,oneneedstohavesuccessfullyimplementedNachos1,Threadsand Synchronization Primitives. In this concept development stage, you are highly encouraged to study the source codes starting from main.cc to system.cc, interrupt.cc, scheduler.cc, machine.cc, mipssim.cc, list.cc, bitmap.cc, synchlist.cc, exception.cc, addrspace.cc, progtest.cc, synch.cc, thread.cc, translate.cc.Youwillalsoneedconsole.cclater.
Warning: Do not change any file in machine folder when programming. They are part of machine simulation and resembles the hardware. When we are to write an operating system, we cant change the hardware design, those are already fixed.
Page9
Whendoingthis W t projectwe w hadtowo orkiterativel lyorlikespir ral.Thingsar reinterrelate ed,soonetaskwasnt c complete insingle s pass.Here H ourpro ocessmodelis i described.Itmaynotbe b thebestmodel m tofollo ow,butit w worked fine for us. This s whole rep port also foll lows the fol llowing sequ uence. The numbers on n left are a associated se ections.
ThoroughIntegrationTe ests
[Nachos]Multiprogramming,Processmanagementandconsole
3AddMultiprogramming
Defaultnachosprovidesexampleofrunninguseprogramthroughmonoprogramming[Refertosec1.3] Tocreatenewprocessfromanotherprocess,weneedtoinvokesystemcalls. SC_Execisthesystemcalltostartanewuserprocess. SC_Exitisthesystemcalltoexitauserprocess. Insection3.1and3.2weatfirstwritecodesforthesystemcallsSC_ExecandSC_Exitassuming monoprogramming.Butwecanteventesttheserightinthatform,becausecallingSC_Execmeans creatingauserprocessfromauserprocesswhichbydefinitionismultiprogramming.Insection3.3we addatypicalmemorymanagementformultiprogrammingsothatseveraluserprocesscanresideinmain memoryhencecompletethemultiprogrammingpart.
3.1SC_EXEC
Use Case
Fromuserprogramwewanttowritelike SpaceId myProcess; myProcess = Exec(../test/sort); Andthiswillexecutenoffformatbinaryfilesortresidingintestfolderasauserprocess.
Idea
Thebasicstepofworksneededforthisisdescribedin/userprog/progtest.cc,infunctionStartProcess (refertosection1.3ofthisdocument).Thisfunctioniscalledfrom.threads/main.ccwhenxisspecifiedas anoptionwhenrunningnachos.Sowhatweactuallyhavetodointhissectionistoportthiscodeasa systemcallhandlerin/userprog/exception.cc. Sostartlikethis(inside/userprog/exception.cc).
Void ExceptionHandler(ExceptionType which) { int type = machine->ReadRegister(2);
if (which == SyscallException) {
Page11
[Nachos]Multiprogramming,Processmanagementandconsole
switch(type) { case SC_Halt: { DEBUG('a', "Shutdown, initiated by user program.\n"); interrupt->Halt(); break; } case SC_Exec: { /* write code for handling Exec */ /* ----------------------------*/ /* be careful to on and off interrupts at proper places */ /* ----------------------------*/ /* return the process id for the newly created process, return value is to write at R2 */ Machine->WriteRegister(2, processed);
/* routine task do at last -- generally manipulate PCReg, PrevPCReg, NextPCReg so that they point to proper place*/ int pc; pc=machine->ReadRegister(PCReg); machine->WriteRegister(PrevPCReg,pc); pc=machine->ReadRegister(NextPCReg); machine->WriteRegister(PCReg,pc); pc += 4; machine->WriteRegister(NextPCReg,pc); } } } }
[Nachos]Multiprogramming,Processmanagementandconsole
Togettheaddressofthefilename,wewrite
int buffadd = machine->ReadRegister(4); /* only one argument, so thats in R4 */
[Nachos]Multiprogramming,Processmanagementandconsole
Page14
[Nachos]Multiprogramming,Processmanagementandconsole
3.2SC_EXIT
Use Case
FromuserprogramwewillwritelikeExit(1); Andthissystemcallwillcauseoperatingsystemtodothecleanuptasksandmangeinternaldata structures.
Guide
Forthepurporseofthissection,wejustneedtofinishthecurrentthread,currentThread>Finish().Besure thatthecleanuptasksaredoneproperly.
3.3MEMORYMANAGEMENT
Whatwehavedonesofar,isjustpartofabigjob.Wehaventyetdoneanythingaboutmanaging memory. Severalprogramneedstoresideinmainmemory Oneprogramshouldnotbeabletoaccessanotherprogramsarea Thismemorymanagementshouldbetransparenttoeachuserprocess,i.ememoryshouldbe managedentirelybyoperatingsystemandhardware,userprocessshouldbeinvariantwhether thereisamultiprogrammingormonoprogramming.
Page Table
Hereweusepagetablebasedmemorymanagement.Eachprocesshasitsownaddressspace.Each processunderstandsandrealizesaddressesofitsownaddressspaceonly.Thepagetabletranslatesvirtual addresses(addressfromaprocessesownaddressspace)tophysicaladdress(actualaddressinphysical memoryaccessiblebykernelonly). Thememoryisdividedintoseveralfixedsizepages. At/machine/machine.hcheck
Page15
[Nachos]Multiprogramming,Processmanagementandconsole
PhysicalMemory
Process#3PageTable
Page16
[Nachos]Multiprogramming,Processmanagementandconsole
Page17
[Nachos]Multiprogramming,Processmanagementandconsole
// zero out the entire address space, to zero the unitialized data segment
// and the stack segment bzero(machine->mainMemory, size); // then, copy in the code and data segments into memory if (noffH.code.size > 0) {
DEBUG('a', "Initializing code segment, at 0x%x, size %d\n", noffH.code.virtualAddr, noffH.code.size); executable->ReadAt(&(machine->mainMemory[noffH.code.virtualAddr]), noffH.code.size, noffH.code.inFileAddr); } if (noffH.initData.size > 0) { DEBUG('a', "Initializing data segment, at 0x%x, size %d\n", noffH.initData.virtualAddr, noffH.initData.size); executable->ReadAt(&(machine->mainMemory[noffH.initData.virtualAddr]), noffH.initData.size, noffH.initData.inFileAddr); } }
Redmarkedlinesneedspecialattentionandcorrectionformultiprogramming.
ASSERT(numPages <= NumPhysPages)
ThisassertionshouldbeonNumberofFreepagesremaining,ratherthantotalnumberofpages.
pageTable = new TranslationEntry[numPages];
Fine,theyhavemadethepagetableforus
pageTable[i].physicalPage = i;
Page18
[Nachos]Multiprogramming,Processmanagementandconsole
anewprogramisloaded,thatmemoryneedstobeinitialized.Butthisisnotthecasefor multiprogramming.Soweshouldcallbzeroonlyintheloop,foreachoftheindividualpagesallocated.
executable->ReadAt(&(machine->mainMemory[noffH.code.virtualAddr]), noffH.code.size, noffH.code.inFileAddr); executable->ReadAt(&(machine->mainMemory[noffH.initData.virtualAddr]), noffH.initData.size, noffH.initData.inFileAddr);
virtual addres no longer equals to physical address. And we need to translate noffH.code.virtualAddr to physical address explicitly here. We may need to write our own translation function because translate.cc translate function works on machine>pageTable, which is the pageTableofthecurrentprocess,buthereweareworkingwithadifferentprocess.
delete pageTable;
Page19
[Nachos]Multiprogramming,Processmanagementandconsole
4ProcessManagement
Unixmaintainsaparentchildhierarchyofprocesses.Wearetomaintainparentchildrelationshipof processesinNachos.Oneprocesscanjoinanotherprocess.Forsimplicity,here,onlyaparentcanwaitfor itschild. Inthischapterwe: 1. Createtheprocessclassandupdatethreadclass. 2. RevisitSC_Execandtherebycompleteit. 3. AddsystemcallSC_JoinandrevisitSC_Exit.
4.1PROCESSCLASS
Weneedtohaveaprocessclassforeachoftheprocess. Hereistheinterfaceofourprocessclass.
#ifndef PROCESS_H_ #define PROCESS_H_ #ifdef USER_PROGRAM #include "list.h" class Thread; enum ProcessStatus { PROCESS_JUST_CREATED, PROCESS_RUNNING, PROCESS_READY, PROCESS_BLOCKED, PROCESS_ZOMBIE };
class Process{ private: int processId; Process *parent; Thread *container; int nChildren; // number of child int exitCode; ProcessStatus status; List *children; List *waitqueue;
Page20
[Nachos]Multiprogramming,Processmanagementandconsole
public: Process(Thread *myExecutor,Process *myParent); Process *getParent() { return parent;} Thread *getThread() {return container;} int numberOfChildren(){return nChildren;} ProcessStatus getStatus() {return status;} void setStatus(ProcessStatus st) {status = st;} void void void void void addChild(Process *myChild); wakeUpJoiner(); exit(int ec); addJoiner(Process *joiner); deathOfChild(Process *p);
int getId() {return processId;} int getExitCode(){return exitCode;} void dumpChildInfo(); ~Process(); }; #endif #endif /*PROCESS_H_*/
Insidethead.hweupdatethefollowing(redmarked):
#ifdef USER_PROGRAM // A thread running a user program actually has *two* sets of CPU registers -// one for its state while executing user code, one for its state // while executing kernel code. int userRegisters[NumTotalRegs]; Process *userProcess; public: void SaveUserState(); void RestoreUserState(); AddrSpace *space; // user-level CPU register state
// save user-level register state // restore user-level register state // User code this thread is running.
[Nachos]Multiprogramming,Processmanagementandconsole
4.2REVISITSC_EXEC
AnewprocessobjectiscreatedinsidehandlerofSC_Exec.(Redmarked) Tokeeptrackoftheprocesshierarchy,eachprocessobjectislinkedwithitsparentviaProcess *parent pointerinprocessclass,andparentsinformationispassedwhenthechildiscreated. Eachprocessalsohaveachildlist.Soparentprocessalsoattachesthechildwithitself(greenmarked).
Process *parentProcess=currentThread->getProcess(); Process *myProcess = new Process(t,parentProcess); parentProcess->addChild(myProcess);
Nowthequestionis,howdoweunderstand,currentThreadistheexecutoroftheparentoftheprocesswe aregoingtocreate?veryeasy,becausethiscodeisinsidethesystemcallSC_Exec,andwhenuserinvokes thissystemcallfromsomeuserprocess,thatprocessistheparent,andexecutorthreadofthatprocesswill actuallycometothesystemcallhandler,createthenewprocess,createthenewthreadanddootherjobs. InsideSC_Exit,weneedtheparenttodeattachitschild,changethechildsstatetozombieifparenthasnt exitedyet,checkfororphanedchildrenwhenaprocessexitsandothercleanuptasks.Butastheseare highlycorrelatedwithSC_Join,wediscusstheseatnextsection. WealsohaveaprovisionfortranslationbetweenprocessobjectandprocessIDeasily.Sowehavea translationtabledefinedin/threads/system.cc.Check/threads/system.ccandfindthatglobalobjectsare definedinthisfile.Insidesystem.ccwehave
#ifdef USER_PROGRAM SynchConsole *synchConsole; // visit this later List *processTranslationTable; Process *initProcess; Lock *pttLock; #endif
AlockisneededfortheprocessTranslationTable,becauseitisasharedobject. Wecreatetheseobjectsinsideinitializefunctionin/threads/system.cc
#ifdef USER_PROGRAM machine = new Machine(debugUserProg); // this must come first // <group 9> synchConsole = new SynchConsole (NULL, NULL); // visit this later processTranslationTable = new List; pttLock= new Lock("Process Translation Table Lock"); // </group 9>
Page22
[Nachos]Multiprogramming,Processmanagementandconsole
#endif
Insidethesystemcallhandler(SC_Exec)weupdatethesedatastructures:
pttLock->Acquire(); processTranslationTable->SortedInsert((void *)myProcess,myProcess->getId()); pttLock->Release();
AndInsideSC_Exitweupdatethesealso.ButasSC_ExitishighlycorrelatedwithSC_Join,wediscussit there.
4.3ADDSC_JOIN
Parentprocessalsocancalljoinonchild. Theusecasemaybelike:
newProc = Exec ( "../test/gchild" ) ; for(i=0;i<10;i++) j += i; Join ( newProc ) ;
Page23
[Nachos]Multiprogramming,Processmanagementandconsole
SystemcallhandlerforSC_Joinissimple. 1. ItatfirstacquiresthelockforProcessTranslationTableandsearchesthejoineeIDthereandgets ProcesspointerforthatID. 2. ItthencheckswhethercallingwiththejoineeIDisvalid. 3. Assumingvalid,itcheckswhetherthejoineealreadyexited(ZombieState) a. Ifzombie,thenitgetstheexitcodestoredintheprocessstructureforthatchild b. Ifnotzombie,thencurrentthreadsleeps(currentthreadisthethreadforthecalling process) 4. Oninvalidcalls,1isreturned. Nottomentionherethatthesystemcallhandleratfirstdoestheroutinetask(settingcorrectvalues PCReg,NextPCReg,PrevPCReg) NowthatwekeptaZombiestate.Zombiestatemeansthechildisfunctionallydead,butithasstillthe entryinitsparentschildlist.Nowwhenthisentrywillbedeleted?Easy,whentheparentexits. SowenowcheckthehandlerforSC_Exit 1. Theprocessismarkedaszombie 2. Iftherearejoinerfortheprocess,itisawaken.(interruptsoff) 3. NowweneedtocareaboutthechildrenithasForallchildcinchild_list i. Ifcisazombieprocess(thischildexitedbeforetheparentandnowweare accessingitsundeletedentries),deleteitfromprocessTranslationtableandalso deletetheprocessobject.(butdontdeleteitfromthelinkedlistrightnow) ii. Ifcisnotazombieprocess,itisstillrunning.Weassignadummyprocessname initProcess,whichisjustaprocessanddoesnothing. 4. Deletefromchildlistlinkedlistallthezombiechilds. 5. IfthecurrentprocesssparentisinitProcess,itmeansthisprocesslostitsparentpreviouslyand nowhasadummyasaparent,whichisnotgoingtoexit.Sointhatcasetheprocessitselfdeletes itsdatastructures.
Page24
[Nachos]Multiprogramming,Processmanagementandconsole
5ConsoleManagement
Sorrythischapterwillbeavailableonnextiteration.
Page25
[Nachos]Multiprogramming,Processmanagementandconsole
References
[1] [2] [3] [4] [5] [6] [7] [8] [9] ModernOperatingSystems,AndrewSTanenbaum OperatingSystemConcepts,Silberchatz,Galvin,Gagne TheDesignofUnixOperatingSystem(Chapter6,7)MauriceJBach TheNachosPrimer,MatthewPeters,RobertHill,ShyamPather ARoadmaptoNachos,ThomasNarten UnderstandingtheLinuxKernel,Section1.6.DanielP.Bovet,MarcoCesati ComputerOrganizationandDesign,Patterson,Henessy. Nachos2AssignmentDescription,Md.SohrabHossain,KhaledMahmudShahriar,Md.Moazzem Hossain,ChowdhurySayeedHayder,DepartmentofComputerScienceandEngineering,BUET. Nachos1AssignmentReportGroup9,SukarnaBarua,TanvirAlAminPopel(Level3Term2,July 2007Term,DepartmentofComputerScienceandEngineering,BUET.
Page26