1 / 15

Project 2: Initial Implementation Notes

Project 2: Initial Implementation Notes. Tao Yang. Part I: Multiprogramming. Fork(func) creates a new user-level (child) process, whose address space starts out as an exact copy of that of the caller (the parent), Yield(): temporarily relinquish the CPU to another process.

tarika
Download Presentation

Project 2: Initial Implementation Notes

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Project 2: Initial Implementation Notes Tao Yang

  2. Part I: Multiprogramming • Fork(func) creates a new user-level (child) process, whose address space starts out as an exact copy of that of the caller (the parent), • Yield(): temporarily relinquish the CPU to another process. • Exit(int) call takes a single argument, which is an integer status value as in Unix. The currently executing process is terminated.. • Exec(filename) spawns a new user-level thread (process), but creates a new address space. It should return to the parent a SpaceId. • Join(ID) call waits and returns only after a process with the specified ID has finished.

  3. Getting Started • Review start.s (under test directory) which includes all system call stubs, following the style of Halt. • Modify ExceptionHandler() in exception.cc to include all system call entries. • After each system call, increment PC registers so that ExceptionHandler() execution flow returns back to next instruction after user’s system call place. • counter = machine->ReadRegister(PCReg); • machine->WriteRegister(PrevPCReg,counter); • counter = counter + 4;machine->WriteRegister(PCReg,counter); • counter = counter + 4; machine->WriteRegister(NextPCReg,counter); • Arguments of a system call are in Register s 4, 5, 6 etc. • how to verify? You may review MPIS assembly code produced for a test C program using gcc -S. • If needed, return result is register 2 • machine->WriteRegister(2,result);

  4. PCB (Process Control Block) • Write the PCB and a process manager. Create a PCB class that will store the necessary information about a process. Don't worry about putting everything in it right now, you can always add more as you go along. To start, it should have a PID, parent PID, and Thread*. • The process manager- it can have getPID and clearPID methods, which return an unused process id and clear a process id respectively.

  5. Memory Manager • Write a Memory Manager that will be used to facilitate memory allocation: • Track memory page usage. • Allocate a page • Free a page • Modify AddrSpace:AddrSpace (addrspace.cc) to use the memory manager. • Modify the page table constructors to use pages allocated by your memory manager • Create a PCB (process control block) also for each process to include key control information.

  6. AddSpace.cc • Write a function (e.g. AddrSpace::Translate), which converts a virtual address to a physical address. It does so by breaking the virtual address into a page table index and an offset. • Write a function( e.g. AddrSpace::ReadFile), which loads the code and data segments into the translated memory, instead of at position 0. • Read data into a system buffer (diskBuffer). • Copy buffered data into proper memory locations (e.g. at machine->mainMemory[physAddr].)

  7. Implement Fork() in ExceptionHandler() • FuncEntry = Value of register 4 ( sys call argu) • Target function to be executed in the new space. • Create a new kernel thread. • Create a new AddrSpace to be a duplicate of the CurrentThread's space and get a new PCB. • The current thread calls Yield() so the new thread can run. • The new thread runs a dummy function that creates a bridge for execution of the user function). • Call NewThread->Fork(ForkBridge, FuncEntry) • Why? It needs to set program counter properly in a new space.

  8. ForkBridge() : Key parts • Set counter = FuncEntry • Initialize and restore the registers. For example, • currentThread->RestoreUserState(); • currentThread->space->RestoreState(); • machine->WriteRegister(PCReg, counter); • machine->WriteRegister(PrevPCReg,counter-4); • machine->WriteRegister(NextPCReg,counter+4); • Call machine->Run() which executes the forked user process in the desired FuncEntry address.

  9. Implement Exec() • Exec is creating a new process with new code and data segments from a file. • Allocate a new address space which fits this file. • Load data/code from an OpenFile object constructed from the filename passed in by the user. • In order to get that file name you will have to write a function that copies over the string from user space. • Allocate a new kernel thread and a PCB to execute with the above space. • Fork the new thread to run a dummy bridge function that sets the machine registers straight and runs the code • Call NewThread->Fork(ExecBridge ,NULL); • The calling thread should yield to give control to the newly spawned thread. • Return the process ID that executes this binary.

  10. ExecBridge(): Key parts • Initialize registers/restore state. • (currentThread->space)->InitRegisters(); • (currentThread->space)->RestoreState(); • Machine->run();

  11. System Calls for File System • For the entire system, maintain a set of objects (SysOpenFile class) representing system-wide opened files. • Each file may be opened by many user processes. • Call it fileOpenTable[]; • For each process, maintain a set of objects in PCB (UserOpenFile class) representing files opened by this process. • Each file has filename, index to the system-wide open table entry, and offset for the current read/write pointer

  12. Implement create() • Nachos already has a simple file system implemented • filesys.cc and openfile.cc under filesys directory. • Use Nachos fileSystem to add a new file to its directory.

  13. Implement open() • Use fileSystem->Open() (nachos’open) to locate the file object. • Add the opened file object to the system-wide fileOpenTable. • If it is already opened by some other user process, just share the entry. • Else insert to the local file open table in PCB.

  14. Implement read() • Allocate an internal buffer. • If Inputfile ID is ConsoleInput • Then use getchar() and save data in the internal buffer. • Read until EOF or \n. • Else, find the current read offset. • Use openFile:ReadAt (defined in openfile.cc) to read data from the nachos file. • Copy data from the internal buffer to the destination memory location. • Need to copy one by one since the address needs to be translated one by one.

  15. Implement write() • Allocate an internal buffer. • Copy data from the source memory location to the internal buffer. • Need to copy one by one since the address needs to be translated one by one. • If Outputfile ID is ConsoleOutput • Then use printf (assuming string type). • Else, find the current write offset. • Use openFile:WriteAt (defined in openfile.cc) to write data to the nachos file.

More Related