📄 exception.cc
字号:
// exception.cc // Entry point into the Nachos kernel from user programs.// There are two kinds of things that can cause control to// transfer back to here from user code://// syscall -- The user code explicitly requests to call a procedure// in the Nachos kernel. Right now, the only function we support is// "Halt".//// exceptions -- The user code does something that the CPU can't handle.// For instance, accessing memory that doesn't exist, arithmetic errors,// etc. //// Interrupts (which can also cause control to transfer from user// code into the Nachos kernel) are handled elsewhere.//// For now, this only handles the Halt() system call.// Everything else core dumps.//// Copyright (c) 1992-1993 The Regents of the University of California.// All rights reserved. See copyright.h for copyright notice and limitation // of liability and disclaimer of warranty provisions.#include <string.h>#include "copyright.h"#include "system.h"#include "syscall.h"#include "processmanager.h"//#include "addrspace.h"extern int fileoffset;extern AddrSpace *space;ProcessManager *pm=new ProcessManager();extern Lock *lock[100];int returnpid[100];int time,id=0;//----------------------------------------------------------------------// ExceptionHandler// Entry point into the Nachos kernel. Called when a user program// is executing, and either does a syscall, or generates an addressing// or arithmetic exception.//// For system calls, the following is the calling convention://// system call code -- r2// arg1 -- r4// arg2 -- r5// arg3 -- r6// arg4 -- r7//// The result of the system call, if any, must be put back into r2. //// And don't forget to increment the pc before returning. (Or else you'll// loop making the same system call forever!//// "which" is the kind of exception. The list of possible exceptions // are in machine.h.//----------------------------------------------------------------------void newExec(int which){ space->InitRegisters(); space->RestoreState(); machine->Run(); returnpid[which] = 1; ASSERT(false);}void AdjustPCRegs(){ int pc; pc = machine->ReadRegister(PCReg); machine->WriteRegister(PrevPCReg,pc); pc = machine->ReadRegister(NextPCReg); machine->WriteRegister(PCReg,pc); pc+=4; machine->WriteRegister(NextPCReg,pc);}SpaceId Exec(char* name){ time++; printf("Exec run %d times\n",time); int pid,ppid; OpenFile * executable = fileSystem->Open(name); Thread *th =new Thread(name); if(executable == NULL) { printf("Unable to open file %s\n",name); return -1; } th->space=space; th->space->AssignMem(executable); delete executable; ppid = id; printf("father Process ID is %d\n",ppid); pid=pm->Getpid(ppid); printf("The Process ID is %d\n",pid); id = pid; th->Fork(newExec,pid); while(returnpid[pid] == 0) currentThread->Yield(); pm->Release(pid,0); id = ppid; AdjustPCRegs(); return pid;} voidExceptionHandler(ExceptionType which){ char filename[128]; int type = machine->ReadRegister(2); if (which == SyscallException){ switch(type){ case SC_Halt: DEBUG('a', "Shutdown, initiated by user program.\n"); interrupt->Halt(); break; case SC_Exec: strcpy(filename,machine->mainMemory+fileoffset); if(Exec(filename)==-1){ printf("error!\n"); interrupt->Halt(); return; } break; case SC_Join: break; case SC_Exit: currentThread->Finish(); break; default: printf("Unexpected SyscallException %d %d\n",which,type); ASSERT(FALSE); } } else { printf("Unexpected user mode exception %d %d\n", which, type); ASSERT(FALSE); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -